Exemple #1
0
    def get(self):
        if not api_utils.allow_volume():
            raise exception.NotFound()

        api_utils.check_policy('baremetal:volume:get')

        return convert(self.parent_node_ident)
Exemple #2
0
    def patch(self, portgroup_ident, patch):
        """Update an existing portgroup.

        :param portgroup_ident: UUID or logical name of a portgroup.
        :param patch: a json PATCH document to apply to this portgroup.
        """
        if not api_utils.allow_portgroups():
            raise exception.NotFound()

        cdict = pecan.request.context.to_dict()
        policy.authorize('baremetal:portgroup:update', cdict, cdict)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        rpc_portgroup = api_utils.get_rpc_portgroup(portgroup_ident)

        names = api_utils.get_patch_values(patch, '/name')
        for name in names:
            if (name and not api_utils.is_valid_logical_name(name)):
                error_msg = _("Portgroup %(portgroup)s: Cannot change name to"
                              " invalid name '%(name)s'") % {
                                  'portgroup': portgroup_ident,
                                  'name': name
                              }
                raise wsme.exc.ClientSideError(
                    error_msg, status_code=http_client.BAD_REQUEST)

        try:
            portgroup_dict = rpc_portgroup.as_dict()
            # NOTE:
            # 1) Remove node_id because it's an internal value and
            #    not present in the API object
            # 2) Add node_uuid
            portgroup_dict['node_uuid'] = portgroup_dict.pop('node_id', None)
            portgroup = Portgroup(
                **api_utils.apply_jsonpatch(portgroup_dict, patch))
        except api_utils.JSONPATCH_EXCEPTIONS as e:
            raise exception.PatchError(patch=patch, reason=e)

        # Update only the fields that have changed
        for field in objects.Portgroup.fields:
            try:
                patch_val = getattr(portgroup, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if rpc_portgroup[field] != patch_val:
                rpc_portgroup[field] = patch_val

        rpc_node = objects.Node.get_by_id(pecan.request.context,
                                          rpc_portgroup.node_id)
        topic = pecan.request.rpcapi.get_topic_for(rpc_node)

        new_portgroup = pecan.request.rpcapi.update_portgroup(
            pecan.request.context, rpc_portgroup, topic)

        return Portgroup.convert_with_links(new_portgroup)
Exemple #3
0
 def update(self, image_id, **metadata):
     for i, image in enumerate(self._images):
         if image.id == str(image_id):
             for k, v in metadata.items():
                 setattr(self._images[i], k, v)
             return self._images[i]
     raise exception.NotFound(image_id)
Exemple #4
0
 def post(self, evts):
     if not api_utils.allow_expose_events():
         raise exception.NotFound()
     cdict = pecan.request.context.to_policy_values()
     policy.authorize('baremetal:events:post', cdict, cdict)
     for e in evts.events:
         LOG.debug("Received external event: %s", e)
Exemple #5
0
    def delete(self, portgroup_ident):
        """Delete a portgroup.

        :param portgroup_ident: UUID or logical name of a portgroup.
        """
        if not api_utils.allow_portgroups():
            raise exception.NotFound()

        rpc_portgroup, rpc_node = api_utils.check_port_policy_and_retrieve(
            'baremetal:portgroup:delete', portgroup_ident, portgroup=True)

        context = api.request.context

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        notify.emit_start_notification(context,
                                       rpc_portgroup,
                                       'delete',
                                       node_uuid=rpc_node.uuid)
        with notify.handle_error_notification(context,
                                              rpc_portgroup,
                                              'delete',
                                              node_uuid=rpc_node.uuid):
            topic = api.request.rpcapi.get_topic_for(rpc_node)
            api.request.rpcapi.destroy_portgroup(context, rpc_portgroup, topic)
        notify.emit_end_notification(context,
                                     rpc_portgroup,
                                     'delete',
                                     node_uuid=rpc_node.uuid)
Exemple #6
0
    def get_all(self, marker=None, limit=None, sort_key='id', sort_dir='asc',
                fields=None, detail=None):
        """Retrieve a list of conductors.

        :param marker: pagination marker for large data sets.
        :param limit: maximum number of resources to return in a single result.
                      This value cannot be larger than the value of max_limit
                      in the [api] section of the ironic configuration, or only
                      max_limit resources will be returned.
        :param sort_key: column to sort results by. Default: id.
        :param sort_dir: direction to sort. "asc" or "desc". Default: asc.
        :param fields: Optional, a list with a specified set of fields
                       of the resource to be returned.
        :param detail: Optional, boolean to indicate whether retrieve a list
                       of conductors with detail.
        """
        cdict = api.request.context.to_policy_values()
        policy.authorize('baremetal:conductor:get', cdict, cdict)

        if not api_utils.allow_expose_conductors():
            raise exception.NotFound()

        api_utils.check_allow_specify_fields(fields)
        api_utils.check_allowed_fields(fields)
        api_utils.check_allowed_fields([sort_key])

        fields = api_utils.get_request_return_fields(fields, detail,
                                                     _DEFAULT_RETURN_FIELDS)

        return self._get_conductors_collection(marker, limit, sort_key,
                                               sort_dir, fields=fields,
                                               detail=detail)
    def get_all(self, node=None, address=None, marker=None,
                limit=None, sort_key='id', sort_dir='asc', fields=None):
        """Retrieve a list of portgroups.

        :param node: UUID or name of a node, to get only portgroups for that
                     node.
        :param address: MAC address of a portgroup, to get the portgroup which
                        has this MAC address.
        :param marker: pagination marker for large data sets.
        :param limit: maximum number of resources to return in a single result.
                      This value cannot be larger than the value of max_limit
                      in the [api] section of the ironic configuration, or only
                      max_limit resources will be returned.
        :param sort_key: column to sort results by. Default: id.
        :param sort_dir: direction to sort. "asc" or "desc". Default: asc.
        :param fields: Optional, a list with a specified set of fields
                       of the resource to be returned.
        """
        if not api_utils.allow_portgroups():
            raise exception.NotFound()

        cdict = pecan.request.context.to_policy_values()
        policy.authorize('baremetal:portgroup:get', cdict, cdict)

        api_utils.check_allowed_portgroup_fields(fields)
        api_utils.check_allowed_portgroup_fields([sort_key])

        if fields is None:
            fields = _DEFAULT_RETURN_FIELDS

        return self._get_portgroups_collection(node, address,
                                               marker, limit,
                                               sort_key, sort_dir,
                                               fields=fields)
    def post(self, node_ident, callback_url):
        """Process a heartbeat from the deploy ramdisk.

        :param node_ident: the UUID or logical name of a node.
        :param callback_url: the URL to reach back to the ramdisk.
        :raises: NodeNotFound if node with provided UUID or name was not found.
        :raises: InvalidUuidOrName if node_ident is not valid name or UUID.
        :raises: NoValidHost if RPC topic for node could not be retrieved.
        :raises: NotFound if requested API version does not allow this
            endpoint.
        """
        if not api_utils.allow_ramdisk_endpoints():
            raise exception.NotFound()

        cdict = pecan.request.context.to_policy_values()
        policy.authorize('baremetal:node:ipa_heartbeat', cdict, cdict)

        rpc_node = api_utils.get_rpc_node(node_ident)

        try:
            topic = pecan.request.rpcapi.get_topic_for(rpc_node)
        except exception.NoValidHost as e:
            e.code = http_client.BAD_REQUEST
            raise

        pecan.request.rpcapi.heartbeat(pecan.request.context,
                                       rpc_node.uuid,
                                       callback_url,
                                       topic=topic)
    def detail(self, node=None, address=None, marker=None,
               limit=None, sort_key='id', sort_dir='asc'):
        """Retrieve a list of portgroups with detail.

        :param node: UUID or name of a node, to get only portgroups for that
                     node.
        :param address: MAC address of a portgroup, to get the portgroup which
                        has this MAC address.
        :param marker: pagination marker for large data sets.
        :param limit: maximum number of resources to return in a single result.
                      This value cannot be larger than the value of max_limit
                      in the [api] section of the ironic configuration, or only
                      max_limit resources will be returned.
        :param sort_key: column to sort results by. Default: id.
        :param sort_dir: direction to sort. "asc" or "desc". Default: asc.
        """
        if not api_utils.allow_portgroups():
            raise exception.NotFound()

        cdict = pecan.request.context.to_policy_values()
        policy.authorize('baremetal:portgroup:get', cdict, cdict)
        api_utils.check_allowed_portgroup_fields([sort_key])

        # NOTE: /detail should only work against collections
        parent = pecan.request.path.split('/')[:-1][-1]
        if parent != "portgroups":
            raise exception.HTTPNotFound()

        resource_url = '/'.join(['portgroups', 'detail'])
        return self._get_portgroups_collection(
            node, address, marker, limit, sort_key, sort_dir,
            resource_url=resource_url)
Exemple #10
0
    def delete(self):
        if not api_utils.allow_allocations():
            raise exception.NotFound()

        context = pecan.request.context
        cdict = context.to_policy_values()
        policy.authorize('baremetal:allocation:delete', cdict, cdict)

        rpc_node = api_utils.get_rpc_node_with_suffix(self.parent_node_ident)
        allocations = objects.Allocation.list(
            pecan.request.context,
            filters={'node_uuid': rpc_node.uuid})

        try:
            rpc_allocation = allocations[0]
        except IndexError:
            raise exception.AllocationNotFound(
                _("Allocation for node %s was not found") %
                self.parent_node_ident)

        notify.emit_start_notification(context, rpc_allocation, 'delete',
                                       node_uuid=rpc_node.uuid)
        with notify.handle_error_notification(context, rpc_allocation,
                                              'delete',
                                              node_uuid=rpc_node.uuid):
            topic = pecan.request.rpcapi.get_random_topic()
            pecan.request.rpcapi.destroy_allocation(context, rpc_allocation,
                                                    topic)
        notify.emit_end_notification(context, rpc_allocation, 'delete',
                                     node_uuid=rpc_node.uuid)
Exemple #11
0
    def delete(self, allocation_ident):
        """Delete an allocation.

        :param allocation_ident: UUID or logical name of an allocation.
        """
        if not api_utils.allow_allocations():
            raise exception.NotFound()

        context = pecan.request.context
        cdict = context.to_policy_values()
        policy.authorize('baremetal:allocation:delete', cdict, cdict)

        rpc_allocation = api_utils.get_rpc_allocation_with_suffix(
            allocation_ident)
        if rpc_allocation.node_id:
            node_uuid = objects.Node.get_by_id(pecan.request.context,
                                               rpc_allocation.node_id).uuid
        else:
            node_uuid = None

        notify.emit_start_notification(context, rpc_allocation, 'delete',
                                       node_uuid=node_uuid)
        with notify.handle_error_notification(context, rpc_allocation,
                                              'delete', node_uuid=node_uuid):
            topic = pecan.request.rpcapi.get_random_topic()
            pecan.request.rpcapi.destroy_allocation(context, rpc_allocation,
                                                    topic)
        notify.emit_end_notification(context, rpc_allocation, 'delete',
                                     node_uuid=node_uuid)
    def delete(self, portgroup_ident):
        """Delete a portgroup.

        :param portgroup_ident: UUID or logical name of a portgroup.
        """
        if not api_utils.allow_portgroups():
            raise exception.NotFound()

        context = pecan.request.context
        cdict = context.to_policy_values()
        policy.authorize('baremetal:portgroup:delete', cdict, cdict)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        rpc_portgroup = api_utils.get_rpc_portgroup(portgroup_ident)
        rpc_node = objects.Node.get_by_id(pecan.request.context,
                                          rpc_portgroup.node_id)

        notify.emit_start_notification(context, rpc_portgroup, 'delete',
                                       node_uuid=rpc_node.uuid)
        with notify.handle_error_notification(context, rpc_portgroup, 'delete',
                                              node_uuid=rpc_node.uuid):
            topic = pecan.request.rpcapi.get_topic_for(rpc_node)
            pecan.request.rpcapi.destroy_portgroup(context, rpc_portgroup,
                                                   topic)
        notify.emit_end_notification(context, rpc_portgroup, 'delete',
                                     node_uuid=rpc_node.uuid)
Exemple #13
0
    def get_all(self, node=None, resource_class=None, state=None, marker=None,
                limit=None, sort_key='id', sort_dir='asc', fields=None):
        """Retrieve a list of allocations.

        :param node: UUID or name of a node, to get only allocations for that
                     node.
        :param resource_class: Filter by requested resource class.
        :param state: Filter by allocation state.
        :param marker: pagination marker for large data sets.
        :param limit: maximum number of resources to return in a single result.
                      This value cannot be larger than the value of max_limit
                      in the [api] section of the ironic configuration, or only
                      max_limit resources will be returned.
        :param sort_key: column to sort results by. Default: id.
        :param sort_dir: direction to sort. "asc" or "desc". Default: asc.
        :param fields: Optional, a list with a specified set of fields
                       of the resource to be returned.
        """
        if not api_utils.allow_allocations():
            raise exception.NotFound()

        cdict = pecan.request.context.to_policy_values()
        policy.authorize('baremetal:allocation:get', cdict, cdict)

        return self._get_allocations_collection(node, resource_class, state,
                                                marker, limit,
                                                sort_key, sort_dir,
                                                fields=fields)
Exemple #14
0
    def post(self, portgroup):
        """Create a new portgroup.

        :param portgroup: a portgroup within the request body.
        """
        if not api_utils.allow_portgroups():
            raise exception.NotFound()

        cdict = pecan.request.context.to_dict()
        policy.authorize('baremetal:portgroup:create', cdict, cdict)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        if (portgroup.name
                and not api_utils.is_valid_logical_name(portgroup.name)):
            error_msg = _("Cannot create portgroup with invalid name "
                          "'%(name)s'") % {
                              'name': portgroup.name
                          }
            raise wsme.exc.ClientSideError(error_msg,
                                           status_code=http_client.BAD_REQUEST)

        new_portgroup = objects.Portgroup(pecan.request.context,
                                          **portgroup.as_dict())
        new_portgroup.create()
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('portgroups',
                                                 new_portgroup.uuid)
        return Portgroup.convert_with_links(new_portgroup)
Exemple #15
0
    def post(self, allocation):
        """Create a new allocation.

        :param allocation: an allocation within the request body.
        """
        if not api_utils.allow_allocations():
            raise exception.NotFound()

        context = pecan.request.context
        cdict = context.to_policy_values()
        policy.authorize('baremetal:allocation:create', cdict, cdict)

        if allocation.node_uuid is not wtypes.Unset:
            msg = _("Cannot set node_uuid when creating an allocation")
            raise exception.Invalid(msg)

        if (allocation.name
                and not api_utils.is_valid_logical_name(allocation.name)):
            msg = _("Cannot create allocation with invalid name "
                    "'%(name)s'") % {'name': allocation.name}
            raise exception.Invalid(msg)

        if allocation.traits:
            for trait in allocation.traits:
                api_utils.validate_trait(trait)

        if allocation.candidate_nodes:
            # Convert nodes from names to UUIDs and check their validity
            converted = []
            for node in allocation.candidate_nodes:
                try:
                    node = api_utils.get_rpc_node(node)
                except exception.NodeNotFound as exc:
                    exc.code = http_client.BAD_REQUEST
                    raise
                else:
                    converted.append(node.uuid)
            allocation.candidate_nodes = converted

        all_dict = allocation.as_dict()

        # NOTE(yuriyz): UUID is mandatory for notifications payload
        if not all_dict.get('uuid'):
            all_dict['uuid'] = uuidutils.generate_uuid()

        new_allocation = objects.Allocation(context, **all_dict)
        topic = pecan.request.rpcapi.get_random_topic()

        notify.emit_start_notification(context, new_allocation, 'create')
        with notify.handle_error_notification(context, new_allocation,
                                              'create'):
            new_allocation = pecan.request.rpcapi.create_allocation(
                context, new_allocation, topic)
        notify.emit_end_notification(context, new_allocation, 'create')

        # Set the HTTP Location Header
        pecan.response.location = link.build_url('allocations',
                                                 new_allocation.uuid)
        return Allocation.convert_with_links(new_allocation)
Exemple #16
0
    def post(self, node_ident, callback_url, agent_version=None,
             agent_token=None):
        """Process a heartbeat from the deploy ramdisk.

        :param node_ident: the UUID or logical name of a node.
        :param callback_url: the URL to reach back to the ramdisk.
        :param agent_version: The version of the agent that is heartbeating.
            ``None`` indicates that the agent that is heartbeating is a version
            before sending agent_version was introduced so agent v3.0.0 (the
            last release before sending agent_version was introduced) will be
            assumed.
        :param agent_token: randomly generated validation token.
        :raises: NodeNotFound if node with provided UUID or name was not found.
        :raises: InvalidUuidOrName if node_ident is not valid name or UUID.
        :raises: NoValidHost if RPC topic for node could not be retrieved.
        :raises: NotFound if requested API version does not allow this
            endpoint.
        """
        if not api_utils.allow_ramdisk_endpoints():
            raise exception.NotFound()

        if agent_version and not api_utils.allow_agent_version_in_heartbeat():
            raise exception.InvalidParameterValue(
                _('Field "agent_version" not recognised'))

        cdict = api.request.context.to_policy_values()
        policy.authorize('baremetal:node:ipa_heartbeat', cdict, cdict)

        rpc_node = api_utils.get_rpc_node_with_suffix(node_ident)
        dii = rpc_node['driver_internal_info']
        agent_url = dii.get('agent_url')
        # If we have an agent_url on file, and we get something different
        # we should fail because this is unexpected behavior of the agent.
        if agent_url is not None and agent_url != callback_url:
            LOG.error('Received heartbeat for node %(node)s with '
                      'callback URL %(url)s. This is not expected, '
                      'and the heartbeat will not be processed.',
                      {'node': rpc_node.uuid, 'url': callback_url})
            raise exception.Invalid(
                _('Detected change in ramdisk provided '
                  '"callback_url"'))
        # NOTE(TheJulia): If tokens are required, lets go ahead and fail the
        # heartbeat very early on.
        token_required = CONF.require_agent_token
        if token_required and agent_token is None:
            LOG.error('Agent heartbeat received for node %(node)s '
                      'without an agent token.', {'node': node_ident})
            raise exception.InvalidParameterValue(
                _('Agent token is required for heartbeat processing.'))

        try:
            topic = api.request.rpcapi.get_topic_for(rpc_node)
        except exception.NoValidHost as e:
            e.code = http_client.BAD_REQUEST
            raise

        api.request.rpcapi.heartbeat(
            api.request.context, rpc_node.uuid, callback_url,
            agent_version, agent_token, topic=topic)
Exemple #17
0
def _translate_plain_exception(exc_value):
    if isinstance(exc_value, (glance_exc.Forbidden, glance_exc.Unauthorized)):
        return exception.NotAuthorized(exc_value)
    if isinstance(exc_value, glance_exc.NotFound):
        return exception.NotFound(exc_value)
    if isinstance(exc_value, glance_exc.BadRequest):
        return exception.Invalid(exc_value)
    return exc_value
Exemple #18
0
    def get(self):
        if not api_utils.allow_volume():
            raise exception.NotFound()

        cdict = api.request.context.to_policy_values()
        policy.authorize('baremetal:volume:get', cdict, cdict)

        return Volume.convert(self.parent_node_ident)
Exemple #19
0
    def post(self, portgroup):
        """Create a new portgroup.

        :param portgroup: a portgroup within the request body.
        """
        if not api_utils.allow_portgroups():
            raise exception.NotFound()

        context = pecan.request.context
        cdict = context.to_policy_values()
        policy.authorize('baremetal:portgroup:create', cdict, cdict)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        if (not api_utils.allow_portgroup_mode_properties()
                and (portgroup.mode is not wtypes.Unset
                     or portgroup.properties is not wtypes.Unset)):
            raise exception.NotAcceptable()

        if (portgroup.name
                and not api_utils.is_valid_logical_name(portgroup.name)):
            error_msg = _("Cannot create portgroup with invalid name "
                          "'%(name)s'") % {
                              'name': portgroup.name
                          }
            raise wsme.exc.ClientSideError(error_msg,
                                           status_code=http_client.BAD_REQUEST)

        pg_dict = portgroup.as_dict()
        vif = pg_dict.get('extra', {}).get('vif_port_id')
        if vif:
            common_utils.warn_about_deprecated_extra_vif_port_id()

        # NOTE(yuriyz): UUID is mandatory for notifications payload
        if not pg_dict.get('uuid'):
            pg_dict['uuid'] = uuidutils.generate_uuid()

        new_portgroup = objects.Portgroup(context, **pg_dict)

        notify.emit_start_notification(context,
                                       new_portgroup,
                                       'create',
                                       node_uuid=portgroup.node_uuid)
        with notify.handle_error_notification(context,
                                              new_portgroup,
                                              'create',
                                              node_uuid=portgroup.node_uuid):
            new_portgroup.create()
        notify.emit_end_notification(context,
                                     new_portgroup,
                                     'create',
                                     node_uuid=portgroup.node_uuid)

        # Set the HTTP Location Header
        pecan.response.location = link.build_url('portgroups',
                                                 new_portgroup.uuid)
        return Portgroup.convert_with_links(new_portgroup)
Exemple #20
0
 def add_transition(self, start, end, event):
     """Adds an allowed transition from start -> end for the given event."""
     if start not in self._states:
         raise excp.NotFound(
             _("Can not add a transition on event '%(event)s' that "
               "starts in a undefined state '%(state)s'") % {
                   'event': event,
                   'state': start
               })
     if end not in self._states:
         raise excp.NotFound(
             _("Can not add a transition on event '%(event)s' that "
               "ends in a undefined state '%(state)s'") % {
                   'event': event,
                   'state': end
               })
     self._transitions[start][event] = _Jump(end,
                                             self._states[end]['on_enter'],
                                             self._states[start]['on_exit'])
Exemple #21
0
    def post(self, portgroup):
        """Create a new portgroup.

        :param portgroup: a portgroup within the request body.
        """
        if not api_utils.allow_portgroups():
            raise exception.NotFound()

        context = api.request.context
        api_utils.check_policy('baremetal:portgroup:create')

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        if (not api_utils.allow_portgroup_mode_properties()
                and (portgroup.get('mode') or portgroup.get('properties'))):
            raise exception.NotAcceptable()

        if (portgroup.get('name')
                and not api_utils.is_valid_logical_name(portgroup['name'])):
            error_msg = _("Cannot create portgroup with invalid name "
                          "'%(name)s'") % {
                              'name': portgroup['name']
                          }
            raise exception.ClientSideError(
                error_msg, status_code=http_client.BAD_REQUEST)

        api_utils.handle_post_port_like_extra_vif(portgroup)

        # NOTE(yuriyz): UUID is mandatory for notifications payload
        if not portgroup.get('uuid'):
            portgroup['uuid'] = uuidutils.generate_uuid()

        node = api_utils.replace_node_uuid_with_id(portgroup)

        new_portgroup = objects.Portgroup(context, **portgroup)

        notify.emit_start_notification(context,
                                       new_portgroup,
                                       'create',
                                       node_uuid=node.uuid)
        with notify.handle_error_notification(context,
                                              new_portgroup,
                                              'create',
                                              node_uuid=node.uuid):
            new_portgroup.create()
        notify.emit_end_notification(context,
                                     new_portgroup,
                                     'create',
                                     node_uuid=node.uuid)

        # Set the HTTP Location Header
        api.response.location = link.build_url('portgroups',
                                               new_portgroup.uuid)
        return convert_with_links(new_portgroup)
Exemple #22
0
 def delete(self, image_id):
     for i, image in enumerate(self._images):
         if image.id == image_id:
             # When you delete an image from glance, it sets the status to
             # DELETED. If you try to delete a DELETED image, it raises
             # HTTPForbidden.
             image_data = self._images[i]
             if image_data.deleted:
                 raise exception.Forbidden()
             image_data.deleted = True
             return
     raise exception.NotFound(image_id)
Exemple #23
0
    def get_all(self, addresses=None, node_uuid=None):
        """Look up a node by its MAC addresses and optionally UUID.

        If the "restrict_lookup" option is set to True (the default), limit
        the search to nodes in certain transient states (e.g. deploy wait).

        :param addresses: list of MAC addresses for a node.
        :param node_uuid: UUID of a node.
        :raises: NotFound if requested API version does not allow this
            endpoint.
        :raises: NotFound if suitable node was not found.
        """
        if not api_utils.allow_ramdisk_endpoints():
            raise exception.NotFound()

        cdict = pecan.request.context.to_dict()
        policy.authorize('baremetal:driver:ipa_lookup', cdict, cdict)

        if not addresses and not node_uuid:
            raise exception.IncompleteLookup()

        try:
            if node_uuid:
                node = objects.Node.get_by_uuid(
                    pecan.request.context, node_uuid)
            else:
                node = objects.Node.get_by_port_addresses(
                    pecan.request.context, addresses)
        except exception.NotFound:
            # NOTE(dtantsur): we are reraising the same exception to make sure
            # we don't disclose the difference between nodes that are not found
            # at all and nodes in a wrong state by different error messages.
            raise exception.NotFound()

        if (CONF.api.restrict_lookup and
                node.provision_state not in _LOOKUP_ALLOWED_STATES):
            raise exception.NotFound()

        return LookupResult.convert_with_links(node)
Exemple #24
0
    def get_all(self,
                node=None,
                address=None,
                marker=None,
                limit=None,
                sort_key='id',
                sort_dir='asc',
                fields=None,
                detail=None):
        """Retrieve a list of portgroups.

        :param node: UUID or name of a node, to get only portgroups for that
                     node.
        :param address: MAC address of a portgroup, to get the portgroup which
                        has this MAC address.
        :param marker: pagination marker for large data sets.
        :param limit: maximum number of resources to return in a single result.
                      This value cannot be larger than the value of max_limit
                      in the [api] section of the ironic configuration, or only
                      max_limit resources will be returned.
        :param sort_key: column to sort results by. Default: id.
        :param sort_dir: direction to sort. "asc" or "desc". Default: asc.
        :param fields: Optional, a list with a specified set of fields
                       of the resource to be returned.
        """
        if not api_utils.allow_portgroups():
            raise exception.NotFound()

        if self.parent_node_ident:
            # Override the node, since this is being called by another
            # controller with a linked view.
            node = self.parent_node_ident

        project = api_utils.check_port_list_policy(
            portgroup=True, parent_node=self.parent_node_ident)

        api_utils.check_allowed_portgroup_fields(fields)
        api_utils.check_allowed_portgroup_fields([sort_key])

        fields = api_utils.get_request_return_fields(fields, detail,
                                                     _DEFAULT_RETURN_FIELDS)

        return self._get_portgroups_collection(node,
                                               address,
                                               marker,
                                               limit,
                                               sort_key,
                                               sort_dir,
                                               fields=fields,
                                               detail=detail,
                                               project=project)
Exemple #25
0
    def get_all(self, fields=None):
        if not api_utils.allow_allocations():
            raise exception.NotFound()

        cdict = pecan.request.context.to_policy_values()
        policy.authorize('baremetal:allocation:get', cdict, cdict)

        result = self.inner._get_allocations_collection(self.parent_node_ident,
                                                        fields=fields)
        try:
            return result.allocations[0]
        except IndexError:
            raise exception.AllocationNotFound(
                _("Allocation for node %s was not found") %
                self.parent_node_ident)
Exemple #26
0
    def get_one(self, allocation_ident, fields=None):
        """Retrieve information about the given allocation.

        :param allocation_ident: UUID or logical name of an allocation.
        :param fields: Optional, a list with a specified set of fields
                       of the resource to be returned.
        """
        if not api_utils.allow_allocations():
            raise exception.NotFound()

        cdict = pecan.request.context.to_policy_values()
        policy.authorize('baremetal:allocation:get', cdict, cdict)

        rpc_allocation = api_utils.get_rpc_allocation_with_suffix(
            allocation_ident)
        return Allocation.convert_with_links(rpc_allocation, fields=fields)
Exemple #27
0
    def initialize(self, state=None):
        """Sets up the state machine.

        sets the current state to the specified state, or start_state
        if no state was specified..
        """
        if state is None:
            state = self._start_state
        if state not in self._states:
            raise excp.NotFound(
                _("Can not start from an undefined"
                  " state '%s'") % (state))
        if self._states[state]['terminal']:
            raise excp.InvalidState(
                _("Can not start from a terminal"
                  " state '%s'") % (state))
        self._current = _Jump(state, None, None)
Exemple #28
0
    def get_one(self, portgroup_ident, fields=None):
        """Retrieve information about the given portgroup.

        :param portgroup_ident: UUID or logical name of a portgroup.
        :param fields: Optional, a list with a specified set of fields
                       of the resource to be returned.
        """
        if not api_utils.allow_portgroups():
            raise exception.NotFound()

        cdict = pecan.request.context.to_dict()
        policy.authorize('baremetal:portgroup:get', cdict, cdict)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        rpc_portgroup = api_utils.get_rpc_portgroup(portgroup_ident)
        return Portgroup.convert_with_links(rpc_portgroup, fields=fields)
Exemple #29
0
    def get_one(self, hostname, fields=None):
        """Retrieve information about the given conductor.

        :param hostname: hostname of a conductor.
        :param fields: Optional, a list with a specified set of fields
            of the resource to be returned.
        """
        api_utils.check_policy('baremetal:conductor:get')

        if not api_utils.allow_expose_conductors():
            raise exception.NotFound()

        api_utils.check_allow_specify_fields(fields)
        api_utils.check_allowed_fields(fields)

        conductor = objects.Conductor.get_by_hostname(api.request.context,
                                                      hostname,
                                                      online=None)
        return convert_with_links(conductor, fields=fields)
Exemple #30
0
    def delete(self, portgroup_ident):
        """Delete a portgroup.

        :param portgroup_ident: UUID or logical name of a portgroup.
        """
        if not api_utils.allow_portgroups():
            raise exception.NotFound()

        cdict = pecan.request.context.to_dict()
        policy.authorize('baremetal:portgroup:delete', cdict, cdict)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        rpc_portgroup = api_utils.get_rpc_portgroup(portgroup_ident)
        rpc_node = objects.Node.get_by_id(pecan.request.context,
                                          rpc_portgroup.node_id)
        topic = pecan.request.rpcapi.get_topic_for(rpc_node)
        pecan.request.rpcapi.destroy_portgroup(pecan.request.context,
                                               rpc_portgroup, topic)