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 #2
0
    def post(self, port):
        """Create a new port.

        :param port: a port within the request body.
        :raises: NotAcceptable, HTTPNotFound
        """
        cdict = pecan.request.context.to_dict()
        policy.authorize('baremetal:port:create', cdict, cdict)

        if self.parent_node_ident or self.parent_portgroup_ident:
            raise exception.OperationNotPermitted()

        pdict = port.as_dict()
        if (not api_utils.allow_port_advanced_net_fields()
                and set(pdict).intersection(self.advanced_net_fields)):
            raise exception.NotAcceptable()
        if (not api_utils.allow_portgroups_subcontrollers()
                and 'portgroup_uuid' in pdict):
            raise exception.NotAcceptable()

        new_port = objects.Port(pecan.request.context, **pdict)

        new_port.create()
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('ports', new_port.uuid)
        return Port.convert_with_links(new_port)
Exemple #3
0
    def delete(self, port_uuid):
        """Delete a port.

        :param port_uuid: UUID of a port.
        :raises: OperationNotPermitted, HTTPNotFound
        """
        context = pecan.request.context
        cdict = context.to_policy_values()
        policy.authorize('baremetal:port:delete', cdict, cdict)

        if self.parent_node_ident or self.parent_portgroup_ident:
            raise exception.OperationNotPermitted()

        rpc_port = objects.Port.get_by_uuid(context, port_uuid)
        rpc_node = objects.Node.get_by_id(context, rpc_port.node_id)

        portgroup_uuid = None
        if rpc_port.portgroup_id:
            portgroup = objects.Portgroup.get_by_id(context,
                                                    rpc_port.portgroup_id)
            portgroup_uuid = portgroup.uuid

        notify_extra = {
            'node_uuid': rpc_node.uuid,
            'portgroup_uuid': portgroup_uuid
        }
        notify.emit_start_notification(context, rpc_port, 'delete',
                                       **notify_extra)
        with notify.handle_error_notification(context, rpc_port, 'delete',
                                              **notify_extra):
            topic = pecan.request.rpcapi.get_topic_for(rpc_node)
            pecan.request.rpcapi.destroy_port(context, rpc_port, topic)
        notify.emit_end_notification(context, rpc_port, 'delete',
                                     **notify_extra)
Exemple #4
0
def has_server_profile(task, oneview_client):
    """Checks if the node's Server Hardware has a Server Profile associated.

    Function to check if the Server Profile is applied to the Server Hardware.

    :param oneview_client: an instance of the OneView client
    :param task: a TaskManager instance containing the node to act on.
    """
    oneview_info = get_oneview_info(task.node)
    try:
        node_has_server_profile = (
            oneview_client.get_server_profile_from_hardware(oneview_info)
        )
    except oneview_exceptions.OneViewException as oneview_exc:
        LOG.error(
            "Failed to get server profile from OneView appliance for"
            " node %(node)s. Error: %(message)s",
            {"node": task.node.uuid, "message": oneview_exc}
        )
        raise exception.OneViewError(error=oneview_exc)
    if not node_has_server_profile:
        raise exception.OperationNotPermitted(
            _("A Server Profile is not associated with node %s.") %
            task.node.uuid
        )
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 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 #7
0
    def get_one(self, target_uuid, fields=None):
        """Retrieve information about the given volume target.

        :param target_uuid: UUID of a volume target.
        :param fields: Optional, a list with a specified set of fields
               of the resource to be returned.

        :returns: API-serializable volume target object.

        :raises: OperationNotPermitted if accessed with specifying a parent
                 node.
        :raises: VolumeTargetNotFound if no volume target with this UUID exists
        """

        rpc_target, _ = api_utils.check_volume_policy_and_retrieve(
            'baremetal:volume:get',
            target_uuid,
            target=True)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        cdict = api.request.context.to_policy_values()
        if not policy.check_policy('baremetal:volume:view_target_properties',
                                   cdict, cdict):
            self._redact_target_properties(rpc_target)

        return convert_with_links(rpc_target, fields=fields)
Exemple #8
0
    def delete(self, port_uuid):
        """Delete a port.

        :param port_uuid: UUID of a port.
        :raises: OperationNotPermitted, HTTPNotFound
        """
        if self.parent_node_ident or self.parent_portgroup_ident:
            raise exception.OperationNotPermitted()

        rpc_port, rpc_node = api_utils.check_port_policy_and_retrieve(
            'baremetal:port:delete', port_uuid)

        context = api.request.context

        portgroup_uuid = None
        if rpc_port.portgroup_id:
            portgroup = objects.Portgroup.get_by_id(context,
                                                    rpc_port.portgroup_id)
            portgroup_uuid = portgroup.uuid

        notify_extra = {
            'node_uuid': rpc_node.uuid,
            'portgroup_uuid': portgroup_uuid
        }
        notify.emit_start_notification(context, rpc_port, 'delete',
                                       **notify_extra)
        with notify.handle_error_notification(context, rpc_port, 'delete',
                                              **notify_extra):
            topic = api.request.rpcapi.get_topic_for(rpc_node)
            api.request.rpcapi.destroy_port(context, rpc_port, topic)
        notify.emit_end_notification(context, rpc_port, 'delete',
                                     **notify_extra)
Exemple #9
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 #10
0
    def delete(self, connector_uuid):
        """Delete a volume connector.

        :param connector_uuid: UUID of a volume connector.

        :raises: OperationNotPermitted if accessed with specifying a
                 parent node.
        :raises: NodeLocked if node is locked by another conductor
        :raises: NodeNotFound if the node associated with the connector does
                 not exist
        :raises: VolumeConnectorNotFound if the volume connector cannot be
                 found
        :raises: InvalidStateRequested If a node associated with the
                 volume connector is not powered off.
        """
        context = api.request.context

        rpc_connector, rpc_node = api_utils.check_volume_policy_and_retrieve(
            'baremetal:volume:delete',
            connector_uuid,
            target=False)
        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        notify.emit_start_notification(context, rpc_connector, 'delete',
                                       node_uuid=rpc_node.uuid)
        with notify.handle_error_notification(context, rpc_connector,
                                              'delete',
                                              node_uuid=rpc_node.uuid):
            topic = api.request.rpcapi.get_topic_for(rpc_node)
            api.request.rpcapi.destroy_volume_connector(context,
                                                        rpc_connector, topic)
        notify.emit_end_notification(context, rpc_connector, 'delete',
                                     node_uuid=rpc_node.uuid)
Exemple #11
0
    def post(self, port):
        """Create a new port.

        :param port: a port within the request body.
        :raises: NotAcceptable, HTTPNotFound, Conflict
        """
        context = pecan.request.context
        cdict = context.to_policy_values()
        policy.authorize('baremetal:port:create', cdict, cdict)

        if self.parent_node_ident or self.parent_portgroup_ident:
            raise exception.OperationNotPermitted()

        pdict = port.as_dict()
        self._check_allowed_port_fields(pdict)

        extra = pdict.get('extra')
        vif = extra.get('vif_port_id') if extra else None
        if vif:
            common_utils.warn_about_deprecated_extra_vif_port_id()
        if (pdict.get('portgroup_uuid') and (pdict.get('pxe_enabled') or vif)):
            rpc_pg = objects.Portgroup.get_by_uuid(context,
                                                   pdict['portgroup_uuid'])
            if not rpc_pg.standalone_ports_supported:
                msg = _("Port group %s doesn't support standalone ports. "
                        "This port cannot be created as a member of that "
                        "port group because either 'extra/vif_port_id' "
                        "was specified or 'pxe_enabled' was set to True.")
                raise exception.Conflict(msg % pdict['portgroup_uuid'])

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

        rpc_port = objects.Port(context, **pdict)
        rpc_node = objects.Node.get_by_id(context, rpc_port.node_id)

        notify_extra = {
            'node_uuid': port.node_uuid,
            'portgroup_uuid': port.portgroup_uuid
        }
        notify.emit_start_notification(context, rpc_port, 'create',
                                       **notify_extra)
        with notify.handle_error_notification(context, rpc_port, 'create',
                                              **notify_extra):
            # TODO(mgoddard): In RPC API v1.41, port creation was moved to the
            # conductor service to facilitate validation of the physical
            # network field of ports in portgroups. Further consideration is
            # required determine how best to support rolling upgrades from a
            # release in which ports are created by the API service to one in
            # which they are created by the conductor service, while ensuring
            # that all required validation is performed.
            topic = pecan.request.rpcapi.get_topic_for(rpc_node)
            new_port = pecan.request.rpcapi.create_port(
                context, rpc_port, topic)
        notify.emit_end_notification(context, new_port, 'create',
                                     **notify_extra)
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('ports', new_port.uuid)
        return Port.convert_with_links(new_port)
Exemple #12
0
    def delete(self, target_uuid):
        """Delete a volume target.

        :param target_uuid: UUID of a volume target.

        :raises: OperationNotPermitted if accessed with specifying a
                 parent node.
        :raises: NodeLocked if node is locked by another conductor
        :raises: NodeNotFound if the node associated with the target does
                 not exist
        :raises: VolumeTargetNotFound if the volume target cannot be found
        :raises: InvalidStateRequested If a node associated with the
                 volume target is not powered off.
        """
        context = pecan.request.context
        cdict = context.to_policy_values()
        policy.authorize('baremetal:volume:delete', cdict, cdict)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        rpc_target = objects.VolumeTarget.get_by_uuid(context, target_uuid)
        rpc_node = objects.Node.get_by_id(context, rpc_target.node_id)
        notify.emit_start_notification(context, rpc_target, 'delete',
                                       node_uuid=rpc_node.uuid)
        with notify.handle_error_notification(context, rpc_target, 'delete',
                                              node_uuid=rpc_node.uuid):
            topic = pecan.request.rpcapi.get_topic_for(rpc_node)
            pecan.request.rpcapi.destroy_volume_target(context,
                                                       rpc_target, topic)
        notify.emit_end_notification(context, rpc_target, 'delete',
                                     node_uuid=rpc_node.uuid)
Exemple #13
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 #14
0
    def post(self, port):
        """Create a new port.

        :param port: a port within the request body.
        :raises: NotAcceptable, HTTPNotFound, Conflict
        """
        context = pecan.request.context
        cdict = context.to_policy_values()
        policy.authorize('baremetal:port:create', cdict, cdict)

        if self.parent_node_ident or self.parent_portgroup_ident:
            raise exception.OperationNotPermitted()

        pdict = port.as_dict()
        if (not api_utils.allow_port_advanced_net_fields()
                and set(pdict).intersection(self.advanced_net_fields)):
            raise exception.NotAcceptable()
        if (not api_utils.allow_portgroups_subcontrollers()
                and 'portgroup_uuid' in pdict):
            raise exception.NotAcceptable()

        extra = pdict.get('extra')
        vif = extra.get('vif_port_id') if extra else None
        if vif:
            common_utils.warn_about_deprecated_extra_vif_port_id()
        if (pdict.get('portgroup_uuid') and (pdict.get('pxe_enabled') or vif)):
            rpc_pg = objects.Portgroup.get_by_uuid(context,
                                                   pdict['portgroup_uuid'])
            if not rpc_pg.standalone_ports_supported:
                msg = _("Port group %s doesn't support standalone ports. "
                        "This port cannot be created as a member of that "
                        "port group because either 'extra/vif_port_id' "
                        "was specified or 'pxe_enabled' was set to True.")
                raise exception.Conflict(msg % pdict['portgroup_uuid'])

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

        new_port = objects.Port(context, **pdict)

        notify.emit_start_notification(context,
                                       new_port,
                                       'create',
                                       node_uuid=port.node_uuid)
        with notify.handle_error_notification(context,
                                              new_port,
                                              'create',
                                              node_uuid=port.node_uuid):
            new_port.create()
        notify.emit_end_notification(context,
                                     new_port,
                                     'create',
                                     node_uuid=port.node_uuid)
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('ports', new_port.uuid)
        return Port.convert_with_links(new_port)
Exemple #15
0
    def _get_ports_collection(self, node_ident, address, portgroup_ident,
                              marker, limit, sort_key, sort_dir,
                              resource_url=None, fields=None):

        limit = api_utils.validate_limit(limit)
        sort_dir = api_utils.validate_sort_dir(sort_dir)

        marker_obj = None
        if marker:
            marker_obj = objects.Port.get_by_uuid(pecan.request.context,
                                                  marker)

        if sort_key in self.invalid_sort_key_list:
            raise exception.InvalidParameterValue(
                _("The sort_key value %(key)s is an invalid field for "
                  "sorting") % {'key': sort_key})

        node_ident = self.parent_node_ident or node_ident
        portgroup_ident = self.parent_portgroup_ident or portgroup_ident

        if node_ident and portgroup_ident:
            raise exception.OperationNotPermitted()

        if portgroup_ident:
            # FIXME: Since all we need is the portgroup ID, we can
            #                 make this more efficient by only querying
            #                 for that column. This will get cleaned up
            #                 as we move to the object interface.
            portgroup = api_utils.get_rpc_portgroup(portgroup_ident)
            ports = objects.Port.list_by_portgroup_id(pecan.request.context,
                                                      portgroup.id, limit,
                                                      marker_obj,
                                                      sort_key=sort_key,
                                                      sort_dir=sort_dir)
        elif node_ident:
            # FIXME(comstud): Since all we need is the node ID, we can
            #                 make this more efficient by only querying
            #                 for that column. This will get cleaned up
            #                 as we move to the object interface.
            node = api_utils.get_rpc_node(node_ident)
            ports = objects.Port.list_by_node_id(pecan.request.context,
                                                 node.id, limit, marker_obj,
                                                 sort_key=sort_key,
                                                 sort_dir=sort_dir)
        elif address:
            ports = self._get_ports_by_address(address)
        else:
            ports = objects.Port.list(pecan.request.context, limit,
                                      marker_obj, sort_key=sort_key,
                                      sort_dir=sort_dir)

        return PortCollection.convert_with_links(ports, limit,
                                                 url=resource_url,
                                                 fields=fields,
                                                 sort_key=sort_key,
                                                 sort_dir=sort_dir)
Exemple #16
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 #17
0
    def post(self, connector):
        """Create a new volume connector.

        :param connector: a volume connector within the request body.

        :returns: API-serializable volume connector object.

        :raises: OperationNotPermitted if accessed with specifying a parent
                 node.
        :raises: VolumeConnectorTypeAndIdAlreadyExists if a volume
                 connector already exists with the same type and connector_id
        :raises: VolumeConnectorAlreadyExists if a volume connector with the
                 same UUID already exists
        """
        context = api.request.context
        owner = None
        lessee = None
        raise_node_not_found = False
        node_uuid = connector.get('node_uuid')

        try:
            node = api_utils.replace_node_uuid_with_id(connector)
            owner = node.owner
            lessee = node.lessee
        except exception.NotFound:
            raise_node_not_found = True
        api_utils.check_owner_policy('node', 'baremetal:volume:create',
                                     owner, lessee=lessee, conceal_node=False)

        if raise_node_not_found:
            raise exception.InvalidInput(fieldname='node_uuid',
                                         value=node_uuid)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        # NOTE(hshiina): UUID is mandatory for notification payload
        if not connector.get('uuid'):
            connector['uuid'] = uuidutils.generate_uuid()

        new_connector = objects.VolumeConnector(context, **connector)

        notify.emit_start_notification(context, new_connector, 'create',
                                       node_uuid=node.uuid)
        with notify.handle_error_notification(context, new_connector,
                                              'create',
                                              node_uuid=node.uuid):
            new_connector.create()
        notify.emit_end_notification(context, new_connector, 'create',
                                     node_uuid=node.uuid)
        # Set the HTTP Location Header
        api.response.location = link.build_url('volume/connectors',
                                               new_connector.uuid)
        return convert_with_links(new_connector)
Exemple #18
0
    def patch(self, port_uuid, patch):
        """Update an existing port.

        :param port_uuid: UUID of a port.
        :param patch: a json PATCH document to apply to this port.
        :raises: NotAcceptable
        """
        cdict = pecan.request.context.to_dict()
        policy.authorize('baremetal:port:update', cdict, cdict)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()
        if not api_utils.allow_port_advanced_net_fields():
            for field in self.advanced_net_fields:
                field_path = '/%s' % field
                if (api_utils.get_patch_values(patch, field_path)
                        or api_utils.is_path_removed(patch, field_path)):
                    raise exception.NotAcceptable()

        rpc_port = objects.Port.get_by_uuid(pecan.request.context, port_uuid)
        try:
            port_dict = rpc_port.as_dict()
            # NOTE(lucasagomes):
            # 1) Remove node_id because it's an internal value and
            #    not present in the API object
            # 2) Add node_uuid
            port_dict['node_uuid'] = port_dict.pop('node_id', None)
            port = Port(**api_utils.apply_jsonpatch(port_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.Port.fields:
            try:
                patch_val = getattr(port, field)
            except AttributeError:
                # Ignore fields that aren't exposed in the API
                continue
            if patch_val == wtypes.Unset:
                patch_val = None
            if rpc_port[field] != patch_val:
                rpc_port[field] = patch_val

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

        new_port = pecan.request.rpcapi.update_port(pecan.request.context,
                                                    rpc_port, topic)

        return Port.convert_with_links(new_port)
Exemple #19
0
    def get_one(self, port_uuid, fields=None):
        """Retrieve information about the given port.

        :param port_uuid: UUID of a port.
        :param fields: Optional, a list with a specified set of fields
            of the resource to be returned.
        """
        if self.from_nodes:
            raise exception.OperationNotPermitted()

        api_utils.check_allow_specify_fields(fields)

        rpc_port = objects.Port.get_by_uuid(pecan.request.context, port_uuid)
        return Port.convert_with_links(rpc_port, fields=fields)
Exemple #20
0
    def delete(self, port_uuid):
        """Delete a port.

        :param port_uuid: UUID of a port.
        """
        if self.from_nodes:
            raise exception.OperationNotPermitted()
        rpc_port = objects.Port.get_by_uuid(pecan.request.context,
                                            port_uuid)
        rpc_node = objects.Node.get_by_id(pecan.request.context,
                                          rpc_port.node_id)
        topic = pecan.request.rpcapi.get_topic_for(rpc_node)
        pecan.request.rpcapi.destroy_port(pecan.request.context,
                                          rpc_port, topic)
Exemple #21
0
    def post(self, port):
        """Create a new port.

        :param port: a port within the request body.
        """
        if self.from_nodes:
            raise exception.OperationNotPermitted()

        new_port = objects.Port(pecan.request.context,
                                **port.as_dict())
        new_port.create()
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('ports', new_port.uuid)
        return Port.convert_with_links(new_port)
Exemple #22
0
    def delete(self, port_uuid):
        """Delete a port.

        :param port_uuid: UUID of a port.
        """
        cdict = pecan.request.context.to_dict()
        policy.authorize('baremetal:port:delete', cdict, cdict)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()
        rpc_port = objects.Port.get_by_uuid(pecan.request.context, port_uuid)
        rpc_node = objects.Node.get_by_id(pecan.request.context,
                                          rpc_port.node_id)
        topic = pecan.request.rpcapi.get_topic_for(rpc_node)
        pecan.request.rpcapi.destroy_port(pecan.request.context, rpc_port,
                                          topic)
Exemple #23
0
    def post(self, connector):
        """Create a new volume connector.

        :param connector: a volume connector within the request body.

        :returns: API-serializable volume connector object.

        :raises: OperationNotPermitted if accessed with specifying a parent
                 node.
        :raises: VolumeConnectorTypeAndIdAlreadyExists if a volume
                 connector already exists with the same type and connector_id
        :raises: VolumeConnectorAlreadyExists if a volume connector with the
                 same UUID already exists
        """
        context = pecan.request.context
        cdict = context.to_policy_values()
        policy.authorize('baremetal:volume:create', cdict, cdict)

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        connector_dict = connector.as_dict()
        # NOTE(hshiina): UUID is mandatory for notification payload
        if not connector_dict.get('uuid'):
            connector_dict['uuid'] = uuidutils.generate_uuid()

        new_connector = objects.VolumeConnector(context, **connector_dict)

        notify.emit_start_notification(context,
                                       new_connector,
                                       'create',
                                       node_uuid=connector.node_uuid)
        with notify.handle_error_notification(context,
                                              new_connector,
                                              'create',
                                              node_uuid=connector.node_uuid):
            new_connector.create()
        notify.emit_end_notification(context,
                                     new_connector,
                                     'create',
                                     node_uuid=connector.node_uuid)
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('volume/connectors',
                                                 new_connector.uuid)
        return VolumeConnector.convert_with_links(new_connector)
Exemple #24
0
    def post(self, target):
        """Create a new volume target.

        :param target: a volume target within the request body.

        :returns: API-serializable volume target object.

        :raises: OperationNotPermitted if accessed with specifying a parent
                 node.
        :raises: VolumeTargetBootIndexAlreadyExists if a volume target already
                 exists with the same node ID and boot index
        :raises: VolumeTargetAlreadyExists if a volume target with the same
                 UUID exists
        """
        context = api.request.context
        api_utils.check_policy('baremetal:volume:create')

        if self.parent_node_ident:
            raise exception.OperationNotPermitted()

        # NOTE(hshiina): UUID is mandatory for notification payload
        if not target.get('uuid'):
            target['uuid'] = uuidutils.generate_uuid()

        node = api_utils.replace_node_uuid_with_id(target)

        new_target = objects.VolumeTarget(context, **target)

        notify.emit_start_notification(context,
                                       new_target,
                                       'create',
                                       node_uuid=node.uuid)
        with notify.handle_error_notification(context,
                                              new_target,
                                              'create',
                                              node_uuid=node.uuid):
            new_target.create()
        notify.emit_end_notification(context,
                                     new_target,
                                     'create',
                                     node_uuid=node.uuid)
        # Set the HTTP Location Header
        api.response.location = link.build_url('volume/targets',
                                               new_target.uuid)
        return convert_with_links(new_target)
Exemple #25
0
    def set_boot_device(self, task, device, persistent=False):
        driver_info = common.parse_driver_info(task.node)

        if device not in self.get_supported_boot_devices():
            raise exception.InvalidParameterValue(
                _("Invalid boot device %s specified.") % device)

        node_has_server_profile = (oneview_client
                                   .get_server_profile_from_hardware(
                                       driver_info
                                   )
                                   )
        if not node_has_server_profile:
            raise exception.OperationNotPermitted(
                _("A Server Profile is not associated with the node."))

        device_to_oneview = BOOT_DEVICE_MAPPING_TO_OV.get(device)
        oneview_client.set_boot_device(driver_info, device_to_oneview)
Exemple #26
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 #27
0
    def get_one(self, port_uuid, fields=None):
        """Retrieve information about the given port.

        :param port_uuid: UUID of a port.
        :param fields: Optional, a list with a specified set of fields
            of the resource to be returned.
        :raises: NotAcceptable, HTTPNotFound
        """
        if self.parent_node_ident or self.parent_portgroup_ident:
            raise exception.OperationNotPermitted()

        rpc_port, rpc_node = api_utils.check_port_policy_and_retrieve(
            'baremetal:port:get', port_uuid)

        api_utils.check_allow_specify_fields(fields)
        self._check_allowed_port_fields(fields)

        return Port.convert_with_links(rpc_port, fields=fields)
Exemple #28
0
    def get_one(self, port_uuid, fields=None):
        """Retrieve information about the given port.

        :param port_uuid: UUID of a port.
        :param fields: Optional, a list with a specified set of fields
            of the resource to be returned.
        :raises: NotAcceptable, HTTPNotFound
        """
        cdict = pecan.request.context.to_policy_values()
        policy.authorize('baremetal:port:get', cdict, cdict)

        if self.parent_node_ident or self.parent_portgroup_ident:
            raise exception.OperationNotPermitted()

        api_utils.check_allow_specify_fields(fields)

        rpc_port = objects.Port.get_by_uuid(pecan.request.context, port_uuid)
        return Port.convert_with_links(rpc_port, fields=fields)
Exemple #29
0
    def get_boot_device(self, task):
        driver_info = common.parse_driver_info(task.node)
        node_has_server_profile = (oneview_client
                                   .get_server_profile_from_hardware(
                                       driver_info
                                   )
                                   )

        if not node_has_server_profile:
            raise exception.OperationNotPermitted(
                _("A Server Profile is not associated with the node."))

        boot_order = oneview_client.get_boot_order(driver_info)
        boot_device = {
            'boot_device': BOOT_DEVICE_OV_TO_GENERIC.get(boot_order[0]),
            'persistent': False
        }

        return boot_device
Exemple #30
0
 def inner(self, *args, **kwargs):
     oneview_client = self.oneview_client
     task = args[0]
     oneview_info = get_oneview_info(task.node)
     try:
         node_has_server_profile = (
             oneview_client.get_server_profile_from_hardware(oneview_info))
     except oneview_exceptions.OneViewException as oneview_exc:
         LOG.error(
             _LE("Failed to get server profile from OneView appliance for"
                 " node %(node)s. Error: %(message)s"), {
                     "node": task.node.uuid,
                     "message": oneview_exc
                 })
         raise exception.OneViewError(error=oneview_exc)
     if not node_has_server_profile:
         raise exception.OperationNotPermitted(
             _("A Server Profile is not associated with node %s.") %
             task.node.uuid)
     return func(self, *args, **kwargs)