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)
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])
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)
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()
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)
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)
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)
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)
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'])
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)
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)
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)