示例#1
0
    def post(self, aggregate_uuid, node):
        """Add node to the given aggregate."""
        validation.check_schema(node, agg_schema.add_aggregate_node)

        node = node['node']
        # check whether the node is already in another az
        db_aggregate = objects.Aggregate.get(pecan.request.context,
                                             aggregate_uuid)
        if 'availability_zone' in db_aggregate['metadata']:
            node_aggs = pecan.request.engine_api.list_node_aggregates(
                pecan.request.context, node)
            aggregates = objects.AggregateList.get_by_metadata_key(
                pecan.request.context, 'availability_zone')
            agg_az = db_aggregate.metadata['availability_zone']
            conflict_azs = [
                agg.metadata['availability_zone'] for agg in aggregates
                if agg.uuid in node_aggs['aggregates']
                and agg.metadata['availability_zone'] != agg_az
            ]
            if conflict_azs:
                msg = _("Node %(node)s is already in availability zone(s) "
                        "%(az)s") % {
                            "node": node,
                            "az": conflict_azs
                        }
                raise wsme.exc.ClientSideError(
                    msg, status_code=http_client.BAD_REQUEST)

        pecan.request.engine_api.add_aggregate_node(pecan.request.context,
                                                    aggregate_uuid, node)
示例#2
0
    def post(self, server):
        """Create a new server.

        :param server: a server within the request body.
        """
        validation.check_schema(server, server_schemas.create_server)
        scheduler_hints = server.get('scheduler_hints', {})
        server = server.get('server')

        min_count = server.get('min_count', 1)
        max_count = server.get('max_count', min_count)

        if min_count > max_count:
            msg = _('min_count must be <= max_count')
            raise wsme.exc.ClientSideError(msg,
                                           status_code=http_client.BAD_REQUEST)

        requested_networks = server.pop('networks', None)
        flavor_uuid = server.get('flavor_uuid')
        image_uuid = server.get('image_uuid')
        user_data = server.get('user_data')
        key_name = server.get('key_name')
        partitions = server.get('partitions')
        personality = server.pop('personality', None)

        password = self._get_server_admin_password(server)

        injected_files = []
        if personality:
            for item in personality:
                injected_files.append((item['path'], item['contents']))

        flavor = objects.Flavor.get(pecan.request.context, flavor_uuid)
        if flavor.disabled:
            raise exception.FlavorDisabled(flavor_id=flavor.uuid)
        servers = pecan.request.engine_api.create(
            pecan.request.context,
            flavor,
            image_uuid=image_uuid,
            name=server.get('name'),
            description=server.get('description'),
            availability_zone=server.get('availability_zone'),
            metadata=server.get('metadata'),
            requested_networks=requested_networks,
            user_data=user_data,
            injected_files=injected_files,
            admin_password=password,
            key_name=key_name,
            min_count=min_count,
            max_count=max_count,
            partitions=partitions,
            scheduler_hints=scheduler_hints)
        # Set the HTTP Location Header for the first server.
        pecan.response.location = link.build_url('server', servers[0].uuid)
        return Server.convert_with_links(servers[0])
示例#3
0
    def post(self, flavor):
        """Create an new flavor.

        :param flavor: a flavor within the request body.
        """
        validation.check_schema(flavor, flavor_schema.create_flavor)
        new_flavor = objects.Flavor(pecan.request.context, **flavor)
        new_flavor.create()
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('flavors', new_flavor.uuid)
        return Flavor.convert_with_links(new_flavor)
示例#4
0
    def post(self, flavor_uuid, tenant):
        """Add flavor access for the given tenant."""
        validation.check_schema(tenant, flavor_access.add_tenant_access)

        flavor = objects.Flavor.get(pecan.request.context, flavor_uuid)
        if flavor.is_public:
            msg = _("Can not add access to a public flavor.")
            raise wsme.exc.ClientSideError(msg,
                                           status_code=http_client.CONFLICT)

        flavor.projects.append(tenant['tenant_id'])
        flavor.save()
示例#5
0
    def post(self, server_uuid, interface):
        """Attach Interface.

        :param server_uuid: UUID of a server.
        :param interface: The Baremetal Network ID within the request body.
        """
        validation.check_schema(interface, interface_schemas.attach_interface)

        port_id = interface.get('port_id', None)
        net_id = interface.get('net_id', None)

        server = self._resource or self._get_resource(server_uuid)
        pecan.request.engine_api.attach_interface(pecan.request.context,
                                                  server, net_id, port_id)
示例#6
0
    def post(self, server_group):
        """Create an new server group.

        :param server_group: a server group within the request body.
        """
        validation.check_schema(server_group, sg_schema.create_server_group)
        new_server_group = objects.ServerGroup(pecan.request.context,
                                               **server_group)
        new_server_group.project_id = pecan.request.context.project_id
        new_server_group.user_id = pecan.request.context.user_id
        new_server_group.create()
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('server_groups',
                                                 new_server_group.uuid)
        return ServerGroup.convert_with_links(new_server_group)
示例#7
0
    def post(self, server):
        """Manage an existing bare metal node.

        :param server: A manageable server within the request body
        :return: The server information.
        """
        validation.check_schema(server, schema.manage_server)

        manageable_server = pecan.request.engine_api.manage(
            pecan.request.context, server.get('node_uuid'), server.get('name'),
            server.get('description'), server.get('metadata'))

        # Set the HTTP Location Header for the first server.
        pecan.response.location = link.build_url('server',
                                                 manageable_server.uuid)
        return Server.convert_with_links(manageable_server)
示例#8
0
    def post(self, server_uuid, interface):
        """Attach Interface.

        :param server_uuid: UUID of a server.
        :param interface: The Baremetal Network ID within the request body.
        """
        validation.check_schema(interface, interface_schemas.attach_interface)

        net_id = interface.get('net_id', None)

        if not net_id:
            msg = _("Must input network_id")
            raise exc.HTTPBadRequest(explanation=msg)

        server = self._resource or self._get_resource(server_uuid)
        pecan.request.engine_api.attach_interface(pecan.request.context,
                                                  server, net_id)
示例#9
0
    def post(self, server_uuid, remote_console):
        """Get the serial console info of the server.

        :param server_uuid: the UUID of a server.
        :param remote_console: request body includes console type and protocol.
        """
        validation.check_schema(remote_console, console_schemas.create_console)

        server_obj = self._resource or self._get_resource(server_uuid)
        protocol = remote_console['protocol']
        console_type = remote_console['type']
        # Only serial console is supported now
        if protocol == 'serial':
            console_url = pecan.request.engine_api.get_serial_console(
                pecan.request.context, server_obj, console_type)

        return ServerConsole(protocol=protocol,
                             type=console_type,
                             url=console_url['url'])
示例#10
0
    def post(self, aggregate):
        """Create a new aggregate.

        :param aggregate: an aggregate within the request body.
        """
        validation.check_schema(aggregate, agg_schema.create_aggregate)
        metadata = aggregate.get('metadata')
        if metadata and 'availability_zone' in metadata:
            if not metadata['availability_zone']:
                msg = _("Aggregate %s does not support empty named "
                        "availability zone") % aggregate['name']
                raise wsme.exc.ClientSideError(
                    msg, status_code=http_client.BAD_REQUEST)

        new_aggregate = objects.Aggregate(pecan.request.context, **aggregate)
        new_aggregate.create()
        # Set the HTTP Location Header
        pecan.response.location = link.build_url('aggregates',
                                                 new_aggregate.uuid)
        return Aggregate.convert_with_links(new_aggregate)
示例#11
0
    def post(self, aggregate_uuid, node):
        """Add node to the given aggregate."""
        validation.check_schema(node, agg_schema.add_aggregate_node)

        node = node['node']
        db_aggregate = objects.Aggregate.get(pecan.request.context,
                                             aggregate_uuid)
        node_aggregates = pecan.request.engine_api.list_node_aggregates(
            pecan.request.context, node)
        # check whether the node is already in another az
        if 'availability_zone' in db_aggregate['metadata']:
            self._check_aggregates_conflict(
                node, node_aggregates['aggregates'], 'availability_zone',
                db_aggregate.metadata['availability_zone'])
        # check whether the node is already in another affinity zone
        if 'affinity_zone' in db_aggregate['metadata']:
            self._check_aggregates_conflict(
                node, node_aggregates['aggregates'], 'affinity_zone',
                db_aggregate.metadata['affinity_zone'])

        pecan.request.engine_api.add_aggregate_node(
            pecan.request.context, aggregate_uuid, node)
示例#12
0
    def post(self, server_uuid, floatingip):
        """Add(Associate) Floating Ip.

        :param server_uuid: UUID of a server.
        :param floatingip: The floating IP within the request body.
        """
        validation.check_schema(floatingip, fip_schemas.add_floating_ip)

        server = self._resource or self._get_resource(server_uuid)
        address = floatingip['address']
        server_nics = server.nics

        if not server_nics:
            msg = _('No ports associated to server')
            raise wsme.exc.ClientSideError(msg,
                                           status_code=http_client.BAD_REQUEST)

        fixed_address = None
        nic_to_associate = None
        if 'fixed_address' in floatingip:
            fixed_address = floatingip['fixed_address']
            for nic in server_nics:
                for port_address in nic.fixed_ips:
                    if port_address['ip_address'] == fixed_address:
                        nic_to_associate = nic
                        break
                else:
                    continue
                break
            else:
                msg = _('Specified fixed address not assigned to server')
                raise wsme.exc.ClientSideError(
                    msg, status_code=http_client.BAD_REQUEST)
        if nic_to_associate and nic_to_associate.floating_ip:
            msg = _('The specified fixed ip has already been associated with '
                    'a floating ip.')
            raise wsme.exc.ClientSideError(msg,
                                           status_code=http_client.CONFLICT)
        if not fixed_address:
            for nic in server_nics:
                if nic.floating_ip:
                    continue
                for port_address in nic.fixed_ips:
                    if netutils.is_valid_ipv4(port_address['ip_address']):
                        fixed_address = port_address['ip_address']
                        nic_to_associate = nic
                        break
                else:
                    continue
                break
            else:
                msg = _('Unable to associate floating IP %(address)s '
                        'to any fixed IPs for server %(id)s. '
                        'Server has no fixed IPv4 addresses to '
                        'associate or all fixed ips have already been '
                        'associated with floating ips.') % ({
                            'address': address,
                            'id': server.uuid
                        })
                raise wsme.exc.ClientSideError(
                    msg, status_code=http_client.BAD_REQUEST)
            if len(server_nics) > 1:
                LOG.warning(
                    'multiple ports exist, using the first '
                    'IPv4 fixed_ip: %s', fixed_address)
        try:
            self.network_api.associate_floating_ip(pecan.request.context,
                                                   floating_address=address,
                                                   port_id=nic.port_id,
                                                   fixed_address=fixed_address)
        except (exception.FloatingIpNotFoundForAddress,
                exception.Forbidden) as e:
            six.reraise(type(e), e)
        except Exception as e:
            msg = _('Unable to associate floating IP %(address)s to '
                    'fixed IP %(fixed_address)s for server %(id)s. '
                    'Error: %(error)s') % ({
                        'address': address,
                        'fixed_address': fixed_address,
                        'id': server.uuid,
                        'error': e
                    })
            LOG.exception(msg)
            raise wsme.exc.ClientSideError(msg,
                                           status_code=http_client.BAD_REQUEST)
        nic_to_associate.floating_ip = address
        nic_to_associate.save(pecan.request.context)