def _create_server(self, context, flavor, image_uuid, name, description, availability_zone, metadata, requested_networks, user_data, injected_files, key_name, min_count, max_count): """Verify all the input parameters""" # Verify the specified image exists if image_uuid: self._get_image(context, image_uuid) if not availability_zone: availability_zone = CONF.engine.default_schedule_zone base_options, max_net_count, key_pair = \ self._validate_and_build_base_options( context, flavor, image_uuid, name, description, availability_zone, metadata, requested_networks, user_data, key_name, max_count) # max_net_count is the maximum number of servers requested by the # user adjusted for any network quota constraints, including # consideration of connections to each requested network if max_net_count < min_count: raise exception.PortLimitExceeded() elif max_net_count < max_count: LOG.info( "max count reduced from %(max_count)d to " "%(max_net_count)d due to network port quota", { 'max_count': max_count, 'max_net_count': max_net_count }) max_count = max_net_count # TODO(zhenguo): Check injected file quota # b64 decode the files to inject: decoded_files = self._decode_files(injected_files) servers = self._provision_servers(context, base_options, min_count, max_count) request_spec = { 'server_properties': { 'flavor_uuid': servers[0].flavor_uuid, 'networks': requested_networks, }, 'flavor': dict(flavor), 'availability_zone': availability_zone, } self.engine_rpcapi.schedule_and_create_servers(context, servers, requested_networks, user_data, decoded_files, key_pair, request_spec, filter_properties=None) return servers
def test_server_post_with_port_limit_exceeded(self, mock_get, mock_engine_create): mock_get.side_effect = None mock_engine_create.side_effect = exception.PortLimitExceeded() body = gen_post_body() self.context.roles = "no-admin" self.context.tenant = self.evil_project headers = self.gen_headers(self.context) self.post_json('/servers', body, headers=headers, status=403)
def validate_networks(self, context, requested_networks, num_servers): """Validate that the tenant can use the requested networks. Return the number of servers than can be successfully allocated with the requested network configuration. """ LOG.debug('validate_networks() for %s', requested_networks) client = get_client(context.auth_token) ports_needed_per_server = self._ports_needed_per_server( client, requested_networks) # Check the quota and return how many of the requested number of # servers can be created if ports_needed_per_server: quotas = client.show_quota(context.project_id)['quota'] if quotas.get('port', -1) == -1: # Unlimited Port Quota return num_servers # We only need the port count so only ask for ids back. params = dict(tenant_id=context.project_id, fields=['id']) ports = client.list_ports(**params)['ports'] free_ports = quotas.get('port') - len(ports) if free_ports < 0: msg = (_("The number of defined ports: %(ports)d " "is over the limit: %(quota)d") % { 'ports': len(ports), 'quota': quotas.get('port') }) raise exception.PortLimitExceeded(msg) ports_needed = ports_needed_per_server * num_servers if free_ports >= ports_needed: return num_servers else: return free_ports // ports_needed_per_server return num_servers
def _create_server(self, context, flavor, image_uuid, name, description, availability_zone, metadata, requested_networks, user_data, injected_files, admin_password, key_name, min_count, max_count, partitions, scheduler_hints): """Verify all the input parameters""" image = self._get_image(context, image_uuid) iwdi = self._is_whole_disk_image(context, image) if iwdi and partitions: raise exception.PartitionsNotSupport(image_id=image['id']) if (not iwdi) and (not partitions): partitions = {'root_gb': CONF.engine.default_root_partition} self._check_requested_image(context, image, partitions) if not availability_zone: availability_zone = CONF.engine.default_schedule_zone base_options, max_net_count, key_pair = \ self._validate_and_build_base_options( context, flavor, image_uuid, name, description, availability_zone, metadata, requested_networks, user_data, key_name, max_count, partitions) # max_net_count is the maximum number of servers requested by the # user adjusted for any network quota constraints, including # consideration of connections to each requested network if max_net_count < min_count: raise exception.PortLimitExceeded() elif max_net_count < max_count: LOG.info("max count reduced from %(max_count)d to " "%(max_net_count)d due to network port quota", {'max_count': max_count, 'max_net_count': max_net_count}) max_count = max_net_count # TODO(zhenguo): Check injected file quota # b64 decode the files to inject: decoded_files = self._decode_files(injected_files) server_group = self._get_requested_server_group(context, scheduler_hints) servers = self._provision_servers(context, base_options, min_count, max_count, server_group) request_spec = { 'server_properties': { 'flavor_uuid': servers[0].flavor_uuid, 'networks': requested_networks, }, 'flavor': dict(flavor), 'availability_zone': availability_zone, 'scheduler_hints': scheduler_hints } self.engine_rpcapi.schedule_and_create_servers(context, servers, requested_networks, user_data, decoded_files, admin_password, key_pair, partitions, request_spec, filter_properties=None) return servers