def create(self, req, body): """Creates a new server group.""" context = _authorize_context(req) try: self._validate_input_body(body, 'server_group') except jacket.compute.exception.InvalidInput as e: raise exc.HTTPBadRequest(explanation=e.format_message()) quotas = None if self.ext_mgr.is_loaded('os-server-group-quotas'): quotas = objects.Quotas(context=context) try: quotas.reserve(project_id=context.project_id, user_id=context.user_id, server_groups=1) except jacket.compute.exception.OverQuota: msg = _("Quota exceeded, too many server groups.") raise exc.HTTPForbidden(explanation=msg) vals = body['server_group'] sg = objects.InstanceGroup(context) sg.project_id = context.project_id sg.user_id = context.user_id try: sg.name = vals.get('name') sg.policies = vals.get('policies') sg.create() except ValueError as e: if quotas: quotas.rollback() raise exc.HTTPBadRequest(explanation=e) if quotas: quotas.commit() return {'server_group': self._format_server_group(context, sg)}
def create(self, req, body): """Creates a new snapshot.""" context = req.environ['nova.context'] context.can(vol_policies.BASE_POLICY_NAME) snapshot = body['snapshot'] volume_id = snapshot['volume_id'] force = snapshot.get('force', False) force = strutils.bool_from_string(force, strict=True) if force: create_func = self.volume_api.create_snapshot_force else: create_func = self.volume_api.create_snapshot try: new_snapshot = create_func(context, volume_id, snapshot.get('display_name'), snapshot.get('display_description')) except exception.OverQuota as e: raise exc.HTTPForbidden(explanation=e.format_message()) retval = _translate_snapshot_detail_view(context, new_snapshot) return {'snapshot': retval}
def perform_import(self, doc=None, username_mapping=None, default_username=None, create_users=False, **kw): require_access(c.project, 'admin') if username_mapping is None: username_mapping = '{}' if not c.api_token.can_import_forum(): log.error('Import capability is not enabled for %s', c.project.shortname) raise exc.HTTPForbidden(detail='Import is not allowed') try: doc = json.loads(doc) username_mapping = json.loads(username_mapping) warnings = import_support.perform_import(doc, username_mapping, default_username, create_users) return dict(warnings=warnings, errors=[]) except Exception, e: raise log.exception(e) return dict(status=False, errors=[str(e)])
def _migrate(self, req, id, body): """Permit admins to migrate a server to a new host.""" context = req.environ['nova.context'] authorize(context, 'migrate') instance = common.get_instance(self.compute_api, context, id, want_objects=True) try: self.compute_api.resize(req.environ['nova.context'], instance) except (exception.TooManyInstances, exception.QuotaError) as e: raise exc.HTTPForbidden(explanation=e.format_message()) except exception.InstanceIsLocked as e: raise exc.HTTPConflict(explanation=e.format_message()) except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state( state_error, 'migrate', id) except exception.InstanceNotFound as e: raise exc.HTTPNotFound(explanation=e.format_message()) except exception.NoValidHost as e: raise exc.HTTPBadRequest(explanation=e.format_message()) return webob.Response(status_int=202)
def update(self, req, id, body): """Update specified share network.""" context = req.environ['manila.context'] policy.check_policy(context, RESOURCE_NAME, 'update') if not body or RESOURCE_NAME not in body: raise exc.HTTPUnprocessableEntity() try: share_network = db_api.share_network_get(context, id) except exception.ShareNetworkNotFound as e: raise exc.HTTPNotFound(explanation=six.text_type(e)) update_values = body[RESOURCE_NAME] if 'nova_net_id' in update_values: msg = _("nova networking is not supported starting in Ocata.") raise exc.HTTPBadRequest(explanation=msg) if share_network['share_servers']: for value in update_values: if value not in ['name', 'description']: msg = (_("Cannot update share network %s. It is used by " "share servers. Only 'name' and 'description' " "fields are available for update") % share_network['id']) raise exc.HTTPForbidden(explanation=msg) try: share_network = db_api.share_network_update( context, id, update_values) except db_exception.DBError: msg = "Could not save supplied data due to database error" raise exc.HTTPBadRequest(explanation=msg) return self._view_builder.build_share_network(req, share_network)
def update(self, req, id, body): """ Updates an existing image with the registry. :param req: wsgi Request object :param body: Dictionary of information about the image :param id: The opaque internal identifier for the image :retval Returns the updated image information as a mapping, """ if req.context.read_only: raise exc.HTTPForbidden() image_data = body['image'] # Prohibit modification of 'owner' if not req.context.is_admin and 'owner' in image_data: del image_data['owner'] purge_props = req.headers.get("X-Glance-Registry-Purge-Props", "false") try: logger.debug( _("Updating image %(id)s with metadata: " "%(image_data)r") % locals()) if purge_props == "true": updated_image = db_api.image_update(req.context, id, image_data, True) else: updated_image = db_api.image_update(req.context, id, image_data) return dict(image=make_image_dict(updated_image)) except exception.Invalid, e: msg = (_("Failed to update image metadata. " "Got error: %(e)s") % locals()) logger.error(msg) return exc.HTTPBadRequest(msg)
def create(self, req, body): """Create a child cell entry.""" context = req.environ['nova.context'] authorize(context) authorize(context, action="create") # NOTE(eliqiao): back-compatible with db layer hard-code admin # permission checks. nova_context.require_admin_context(context) if 'cell' not in body: msg = _("No cell information in request") raise exc.HTTPBadRequest(explanation=msg) cell = body['cell'] if 'name' not in cell: msg = _("No cell name in request") raise exc.HTTPBadRequest(explanation=msg) self._validate_cell_name(cell['name']) self._normalize_cell(cell) try: cell = self.cells_rpcapi.cell_create(context, cell) except exception.CellsUpdateUnsupported as e: raise exc.HTTPForbidden(explanation=e.format_message()) return dict(cell=_scrub_cell(cell))
def index(self, version=None, page=0, limit=None, **kw): if not self.page: redirect(c.app.url + h.urlquote(self.title) + '/edit') c.confirmation = W.confirmation c.thread = W.thread c.attachment_list = W.attachment_list c.subscribe_form = W.page_subscribe_form post_count = self.page.discussion_thread.post_count limit, pagenum, _ = g.handle_paging(limit, page) limit, pagenum = h.paging_sanitizer(limit, pagenum, post_count) page = self.get_version(version) if page is None: if version: redirect('.?version=%d' % (version - 1)) else: redirect('.') elif 'all' not in page.viewable_by and c.user.username not in page.viewable_by: raise exc.HTTPForbidden(detail="You may not view this page.") cur = page.version if cur > 1: prev = cur - 1 else: prev = None next = cur + 1 hide_left_bar = not (c.app.show_left_bar) subscribed_to_page = M.Mailbox.subscribed(artifact=self.page) return dict(page=page, cur=cur, prev=prev, next=next, page_subscribed=subscribed_to_page, hide_left_bar=hide_left_bar, show_meta=c.app.show_right_bar, pagenum=pagenum, limit=limit, count=post_count)
def _action_rebuild(self, req, id, body): """Rebuild an instance with the given attributes.""" body = body['rebuild'] try: image_href = body["imageRef"] except (KeyError, TypeError): msg = _("Could not parse imageRef from request.") raise exc.HTTPBadRequest(explanation=msg) image_href = self._image_uuid_from_href(image_href) password = self._get_server_admin_password(body) context = req.environ['nova.context'] instance = self._get_server(context, req, id) attr_map = { 'personality': 'files_to_inject', 'name': 'display_name', 'accessIPv4': 'access_ip_v4', 'accessIPv6': 'access_ip_v6', 'metadata': 'metadata', 'auto_disk_config': 'auto_disk_config', } kwargs = {} # take the preserve_ephemeral value into account only when the # corresponding extension is active if (self.ext_mgr.is_loaded('os-preserve-ephemeral-rebuild') and 'preserve_ephemeral' in body): kwargs['preserve_ephemeral'] = strutils.bool_from_string( body['preserve_ephemeral'], strict=True) if 'accessIPv4' in body: self._validate_access_ipv4(body['accessIPv4']) if 'accessIPv6' in body: self._validate_access_ipv6(body['accessIPv6']) if 'name' in body: self._validate_server_name(body['name']) for request_attribute, instance_attribute in attr_map.items(): try: kwargs[instance_attribute] = body[request_attribute] except (KeyError, TypeError): pass self._validate_metadata(kwargs.get('metadata', {})) if 'files_to_inject' in kwargs: personality = kwargs.pop('files_to_inject') files_to_inject = self._get_injected_files(personality) else: files_to_inject = None try: self.compute_api.rebuild(context, instance, image_href, password, files_to_inject=files_to_inject, **kwargs) except exception.InstanceIsLocked as e: raise exc.HTTPConflict(explanation=e.format_message()) except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state( state_error, 'rebuild', id) except exception.InstanceNotFound: msg = _("Instance could not be found") raise exc.HTTPNotFound(explanation=msg) except exception.InvalidMetadataSize as error: raise exc.HTTPRequestEntityTooLarge( explanation=error.format_message()) except exception.ImageNotFound: msg = _("Cannot find image for rebuild") raise exc.HTTPBadRequest(explanation=msg) except exception.QuotaError as error: raise exc.HTTPForbidden(explanation=error.format_message()) except (exception.ImageNotActive, exception.FlavorDiskTooSmall, exception.FlavorMemoryTooSmall, exception.InvalidMetadata, exception.AutoDiskConfigDisabledByImage) as error: raise exc.HTTPBadRequest(explanation=error.format_message()) instance = self._get_server(context, req, id) view = self._view_builder.show(req, instance) # Add on the adminPass attribute since the view doesn't do it # unless instance passwords are disabled if CONF.enable_instance_password: view['server']['adminPass'] = password robj = wsgi.ResponseObject(view) return self._add_location(robj)
def _get_servers(self, req, is_detail): """Returns a list of servers, based on any search options specified.""" search_opts = {} search_opts.update(req.GET) context = req.environ['nova.context'] remove_invalid_options(context, search_opts, self._get_server_search_options()) # Verify search by 'status' contains a valid status. # Convert it to filter by vm_state or task_state for compute_api. search_opts.pop('status', None) if 'status' in req.GET.keys(): statuses = req.GET.getall('status') states = common.task_and_vm_state_from_status(statuses) vm_state, task_state = states if not vm_state and not task_state: return {'servers': []} search_opts['vm_state'] = vm_state # When we search by vm state, task state will return 'default'. # So we don't need task_state search_opt. if 'default' not in task_state: search_opts['task_state'] = task_state if 'changes-since' in search_opts: try: parsed = timeutils.parse_isotime(search_opts['changes-since']) except ValueError: msg = _('Invalid changes-since value') raise exc.HTTPBadRequest(explanation=msg) search_opts['changes-since'] = parsed # By default, compute's get_all() will return deleted instances. # If an admin hasn't specified a 'deleted' search option, we need # to filter out deleted instances by setting the filter ourselves. # ... Unless 'changes-since' is specified, because 'changes-since' # should return recently deleted images according to the API spec. if 'deleted' not in search_opts: if 'changes-since' not in search_opts: # No 'changes-since', so we only want non-deleted servers search_opts['deleted'] = False if search_opts.get("vm_state") == ['deleted']: if context.is_admin: search_opts['deleted'] = True else: msg = _("Only administrators may list deleted instances") raise exc.HTTPForbidden(explanation=msg) # If all tenants is passed with 0 or false as the value # then remove it from the search options. Nothing passed as # the value for all_tenants is considered to enable the feature all_tenants = search_opts.get('all_tenants') if all_tenants: try: if not strutils.bool_from_string(all_tenants, True): del search_opts['all_tenants'] except ValueError as err: raise exception.InvalidInput(six.text_type(err)) if 'all_tenants' in search_opts: policy.enforce(context, 'compute:get_all_tenants', { 'project_id': context.project_id, 'user_id': context.user_id }) del search_opts['all_tenants'] else: if context.project_id: search_opts['project_id'] = context.project_id else: search_opts['user_id'] = context.user_id limit, marker = common.get_limit_and_marker(req) # Sorting by multiple keys and directions is conditionally enabled sort_keys, sort_dirs = None, None if self.ext_mgr.is_loaded('os-server-sort-keys'): sort_keys, sort_dirs = common.get_sort_params(req.params) try: instance_list = self.compute_api.get_all(context, search_opts=search_opts, limit=limit, marker=marker, want_objects=True, sort_keys=sort_keys, sort_dirs=sort_dirs) except exception.MarkerNotFound: msg = _('marker [%s] not found') % marker raise exc.HTTPBadRequest(explanation=msg) except exception.FlavorNotFound: LOG.debug("Flavor '%s' could not be found", search_opts['flavor']) instance_list = objects.InstanceList() if is_detail: instance_list.fill_faults() response = self._view_builder.detail(req, instance_list) else: response = self._view_builder.index(req, instance_list) req.cache_db_instances(instance_list) return response
def _action_rebuild(self, req, id, body): """Rebuild an instance with the given attributes.""" rebuild_dict = body['rebuild'] image_href = rebuild_dict["imageRef"] image_href = self._image_uuid_from_href(image_href) password = self._get_server_admin_password(rebuild_dict) context = req.environ['nova.context'] instance = self._get_server(context, req, id) attr_map = { 'name': 'display_name', 'metadata': 'metadata', } rebuild_kwargs = {} if list(self.rebuild_extension_manager): self.rebuild_extension_manager.map(self._rebuild_extension_point, rebuild_dict, rebuild_kwargs) for request_attribute, instance_attribute in attr_map.items(): try: rebuild_kwargs[instance_attribute] = rebuild_dict[ request_attribute] except (KeyError, TypeError): pass try: self.compute_api.rebuild(context, instance, image_href, password, **rebuild_kwargs) except exception.InstanceIsLocked as e: raise exc.HTTPConflict(explanation=e.format_message()) except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state( state_error, 'rebuild', id) except exception.InstanceNotFound: msg = _("Instance could not be found") raise exc.HTTPNotFound(explanation=msg) except exception.ImageNotFound: msg = _("Cannot find image for rebuild") raise exc.HTTPBadRequest(explanation=msg) except exception.QuotaError as error: raise exc.HTTPForbidden(explanation=error.format_message()) except (exception.ImageNotActive, exception.FlavorDiskTooSmall, exception.FlavorMemoryTooSmall, exception.InvalidMetadata, exception.AutoDiskConfigDisabledByImage) as error: raise exc.HTTPBadRequest(explanation=error.format_message()) instance = self._get_server(context, req, id) view = self._view_builder.show(req, instance) # Add on the admin_password attribute since the view doesn't do it # unless instance passwords are disabled if CONF.enable_instance_password: view['server']['adminPass'] = password robj = wsgi.ResponseObject(view) return self._add_location(robj)
def _get_servers(self, req, is_detail): """Returns a list of servers, based on any search options specified.""" search_opts = {} search_opts.update(req.GET) context = req.environ['nova.context'] remove_invalid_options(context, search_opts, self._get_server_search_options()) # Verify search by 'status' contains a valid status. # Convert it to filter by vm_state or task_state for compute_api. search_opts.pop('status', None) if 'status' in req.GET.keys(): statuses = req.GET.getall('status') states = common.task_and_vm_state_from_status(statuses) vm_state, task_state = states if not vm_state and not task_state: return {'servers': []} search_opts['vm_state'] = vm_state # When we search by vm state, task state will return 'default'. # So we don't need task_state search_opt. if 'default' not in task_state: search_opts['task_state'] = task_state if 'changes-since' in search_opts: try: parsed = timeutils.parse_isotime(search_opts['changes-since']) except ValueError: msg = _('Invalid changes-since value') raise exc.HTTPBadRequest(explanation=msg) search_opts['changes-since'] = parsed # By default, compute's get_all() will return deleted instances. # If an admin hasn't specified a 'deleted' search option, we need # to filter out deleted instances by setting the filter ourselves. # ... Unless 'changes-since' is specified, because 'changes-since' # should return recently deleted images according to the API spec. if 'deleted' not in search_opts: if 'changes-since' not in search_opts: # No 'changes-since', so we only want non-deleted servers search_opts['deleted'] = False if search_opts.get("vm_state") == ['deleted']: if context.is_admin: search_opts['deleted'] = True else: msg = _("Only administrators may list deleted instances") raise exc.HTTPForbidden(explanation=msg) # If tenant_id is passed as a search parameter this should # imply that all_tenants is also enabled unless explicitly # disabled. Note that the tenant_id parameter is filtered out # by remove_invalid_options above unless the requestor is an # admin. # TODO(gmann): 'all_tenants' flag should not be required while # searching with 'tenant_id'. Ref bug# 1185290 # +microversions to achieve above mentioned behavior by # uncommenting below code. # if 'tenant_id' in search_opts and 'all_tenants' not in search_opts: # We do not need to add the all_tenants flag if the tenant # id associated with the token is the tenant id # specified. This is done so a request that does not need # the all_tenants flag does not fail because of lack of # policy permission for compute:get_all_tenants when it # doesn't actually need it. # if context.project_id != search_opts.get('tenant_id'): # search_opts['all_tenants'] = 1 # If all tenants is passed with 0 or false as the value # then remove it from the search options. Nothing passed as # the value for all_tenants is considered to enable the feature all_tenants = search_opts.get('all_tenants') if all_tenants: try: if not strutils.bool_from_string(all_tenants, True): del search_opts['all_tenants'] except ValueError as err: raise exception.InvalidInput(six.text_type(err)) if 'all_tenants' in search_opts: policy.enforce(context, 'compute:get_all_tenants', { 'project_id': context.project_id, 'user_id': context.user_id }) del search_opts['all_tenants'] else: if context.project_id: search_opts['project_id'] = context.project_id else: search_opts['user_id'] = context.user_id limit, marker = common.get_limit_and_marker(req) sort_keys, sort_dirs = common.get_sort_params(req.params) try: instance_list = self.compute_api.get_all( context, search_opts=search_opts, limit=limit, marker=marker, want_objects=True, expected_attrs=['pci_devices'], sort_keys=sort_keys, sort_dirs=sort_dirs) except exception.MarkerNotFound: msg = _('marker [%s] not found') % marker raise exc.HTTPBadRequest(explanation=msg) except exception.FlavorNotFound: LOG.debug("Flavor '%s' could not be found ", search_opts['flavor']) instance_list = objects.InstanceList() if is_detail: instance_list.fill_faults() response = self._view_builder.detail(req, instance_list) else: response = self._view_builder.index(req, instance_list) req.cache_db_instances(instance_list) return response
def _authorize(self, context, action): try: policy.check_policy(context, self.resource_name, action) except exception.PolicyNotAuthorized: raise exc.HTTPForbidden()
def update(self, req, id, body): """Updates an existing image with the registry. :param req: wsgi Request object :param body: Dictionary of information about the image :param id: The opaque internal identifier for the image :retval Returns the updated image information as a mapping, """ image_data = body['image'] from_state = body.get('from_state', None) # Prohibit modification of 'owner' if not req.context.is_admin and 'owner' in image_data: del image_data['owner'] if 'location' in image_data: image_data['locations'] = [image_data.pop('location')] purge_props = req.headers.get("X-Glance-Registry-Purge-Props", "false") try: LOG.debug( "Updating image %(id)s with metadata: %(image_data)r", { 'id': id, 'image_data': {k: v for k, v in image_data.items() if k != 'locations'} }) image_data = _normalize_image_location_for_db(image_data) if purge_props == "true": purge_props = True else: purge_props = False updated_image = self.db_api.image_update(req.context, id, image_data, purge_props=purge_props, from_state=from_state) LOG.info(_LI("Updating metadata for image %(id)s"), {'id': id}) return dict(image=make_image_dict(updated_image)) except exception.Invalid as e: msg = (_("Failed to update image metadata. " "Got error: %s") % encodeutils.exception_to_unicode(e)) LOG.error(msg) return exc.HTTPBadRequest(msg) except exception.ImageNotFound: LOG.info(_LI("Image %(id)s not found"), {'id': id}) raise exc.HTTPNotFound(body='Image not found', request=req, content_type='text/plain') except exception.ForbiddenPublicImage: LOG.info(_LI("Update denied for public image %(id)s"), {'id': id}) raise exc.HTTPForbidden() except exception.Forbidden: # If it's private and doesn't belong to them, don't let on # that it exists LOG.info( _LI("Access denied to image %(id)s but returning" " 'not found'"), {'id': id}) raise exc.HTTPNotFound(body='Image not found', request=req, content_type='text/plain') except exception.Conflict as e: LOG.info(encodeutils.exception_to_unicode(e)) raise exc.HTTPConflict(body='Image operation conflicts', request=req, content_type='text/plain') except Exception: LOG.exception(_LE("Unable to update image %s") % id) raise
def _validate_manage_share_server_parameters(self, context, body): if not (body and self.is_valid_body(body, 'share_server')): msg = _("Share Server entity not found in request body") raise exc.HTTPUnprocessableEntity(explanation=msg) required_parameters = ('host', 'share_network_id', 'identifier') data = body['share_server'] for parameter in required_parameters: if parameter not in data: msg = _("Required parameter %s not found") % parameter raise exc.HTTPBadRequest(explanation=msg) if not data.get(parameter): msg = _("Required parameter %s is empty") % parameter raise exc.HTTPBadRequest(explanation=msg) identifier = data['identifier'] host, share_network_id = data['host'], data['share_network_id'] network_subnet_id = data.get('share_network_subnet_id') if network_subnet_id: try: network_subnet = db_api.share_network_subnet_get( context, network_subnet_id) except exception.ShareNetworkSubnetNotFound: msg = _("The share network subnet %s does not " "exist.") % network_subnet_id raise exc.HTTPBadRequest(explanation=msg) else: network_subnet = db_api.share_network_subnet_get_default_subnet( context, share_network_id) if network_subnet is None: msg = _("The share network %s does have a default subnet. Create " "one or use a specific subnet to manage this share server " "with API version >= 2.51.") % share_network_id raise exc.HTTPBadRequest(explanation=msg) if share_utils.extract_host(host, 'pool'): msg = _("Host parameter should not contain pool.") raise exc.HTTPBadRequest(explanation=msg) try: utils.validate_service_host(context, share_utils.extract_host(host)) except exception.ServiceNotFound as e: raise exc.HTTPBadRequest(explanation=e) except exception.PolicyNotAuthorized as e: raise exc.HTTPForbidden(explanation=e) except exception.AdminRequired as e: raise exc.HTTPForbidden(explanation=e) except exception.ServiceIsDown as e: raise exc.HTTPBadRequest(explanation=e) try: share_network = db_api.share_network_get(context, share_network_id) except exception.ShareNetworkNotFound as e: raise exc.HTTPBadRequest(explanation=e) driver_opts = data.get('driver_options') if driver_opts is not None and not isinstance(driver_opts, dict): msg = _("Driver options must be in dictionary format.") raise exc.HTTPBadRequest(explanation=msg) return identifier, host, share_network, driver_opts, network_subnet
def update(self, req, id, body): """Updates an existing image with the registry. :param req: wsgi Request object :param body: Dictionary of information about the image :param id: The opaque internal identifier for the image :retval Returns the updated image information as a mapping, """ image_data = body['image'] # Prohibit modification of 'owner' if not req.context.is_admin and 'owner' in image_data: del image_data['owner'] if 'location' in image_data: image_data['locations'] = [image_data.pop('location')] purge_props = req.headers.get("X-Glance-Registry-Purge-Props", "false") try: LOG.debug( _("Updating image %(id)s with metadata: " "%(image_data)r"), { 'id': id, 'image_data': image_data }) image_data = _normalize_image_location_for_db(image_data) if purge_props == "true": updated_image = self.db_api.image_update( req.context, id, image_data, True) else: updated_image = self.db_api.image_update( req.context, id, image_data) msg = _("Updating metadata for image %(id)s") LOG.info(msg % {'id': id}) return dict(image=make_image_dict(updated_image)) except exception.Invalid as e: msg = (_("Failed to update image metadata. " "Got error: %(e)s") % { 'e': e }) LOG.error(msg) return exc.HTTPBadRequest(msg) except exception.NotFound: msg = _("Image %(id)s not found") LOG.info(msg % {'id': id}) raise exc.HTTPNotFound(body='Image not found', request=req, content_type='text/plain') except exception.ForbiddenPublicImage: msg = _("Update denied for public image %(id)s") LOG.info(msg % {'id': id}) raise exc.HTTPForbidden() except exception.Forbidden: # If it's private and doesn't belong to them, don't let on # that it exists msg = _("Access denied to image %(id)s but returning 'not found'") LOG.info(msg % {'id': id}) raise exc.HTTPNotFound(body='Image not found', request=req, content_type='text/plain')
def _evacuate(self, req, id, body): """Permit admins to evacuate a server from a failed host to a new one. """ context = req.environ["nova.context"] instance = common.get_instance(self.compute_api, context, id) context.can(evac_policies.BASE_POLICY_NAME, target={'user_id': instance.user_id, 'project_id': instance.project_id}) evacuate_body = body["evacuate"] host = evacuate_body.get("host") force = None on_shared_storage = self._get_on_shared_storage(req, evacuate_body) if api_version_request.is_supported(req, min_version='2.29'): force = body["evacuate"].get("force", False) force = strutils.bool_from_string(force, strict=True) if force is True and not host: message = _("Can't force to a non-provided destination") raise exc.HTTPBadRequest(explanation=message) if api_version_request.is_supported(req, min_version='2.14'): password = self._get_password_v214(req, evacuate_body) else: password = self._get_password(req, evacuate_body, on_shared_storage) if host is not None: try: self.host_api.service_get_by_compute_host(context, host) except (exception.ComputeHostNotFound, exception.HostMappingNotFound): msg = _("Compute host %s not found.") % host raise exc.HTTPNotFound(explanation=msg) if instance.host == host: msg = _("The target host can't be the same one.") raise exc.HTTPBadRequest(explanation=msg) # We could potentially move this check to conductor and avoid the # extra API call to neutron when we support move operations with ports # having resource requests. if (common.instance_has_port_with_resource_request( instance.uuid, self.network_api) and not common.supports_port_resource_request_during_move()): LOG.warning("The evacuate action on a server with ports " "having resource requests, like a port with a QoS " "minimum bandwidth policy, is not supported until " "every nova-compute is upgraded to Ussuri") msg = _("The evacuate action on a server with ports having " "resource requests, like a port with a QoS minimum " "bandwidth policy, is not supported by this cluster right " "now") raise exc.HTTPBadRequest(explanation=msg) try: self.compute_api.evacuate(context, instance, host, on_shared_storage, password, force) except exception.InstanceInvalidState as state_error: common.raise_http_conflict_for_instance_invalid_state(state_error, 'evacuate', id) except exception.ComputeServiceInUse as e: raise exc.HTTPBadRequest(explanation=e.format_message()) except exception.ForbiddenWithAccelerators as e: raise exc.HTTPForbidden(explanation=e.format_message()) except exception.OperationNotSupportedForVTPM as e: raise exc.HTTPConflict(explanation=e.format_message()) if (not api_version_request.is_supported(req, min_version='2.14') and CONF.api.enable_instance_password): return {'adminPass': password} else: return None
return dict(image=make_image_dict(updated_image)) except exception.Invalid, e: msg = (_("Failed to update image metadata. " "Got error: %(e)s") % locals()) LOG.error(msg) return exc.HTTPBadRequest(msg) except exception.NotFound: msg = _("Image %(id)s not found") LOG.info(msg % {'id': id}) raise exc.HTTPNotFound(body='Image not found', request=req, content_type='text/plain') except exception.ForbiddenPublicImage: msg = _("Update denied for public image %(id)s") LOG.info(msg % {'id': id}) raise exc.HTTPForbidden() except exception.Forbidden: # If it's private and doesn't belong to them, don't let on # that it exists msg = _("Access denied to image %(id)s but returning 'not found'") LOG.info(msg % {'id': id}) raise exc.HTTPNotFound(body='Image not found', request=req, content_type='text/plain') def make_image_dict(image): """ Create a dict representation of an image which we can use to serialize the image. """
def process(self, req): if not req.method == 'POST': raise exc.HTTPMethodNotAllowed("Only POST allowed", allowed='POST').exception try: json = loads(req.body) except ValueError, e: raise ValueError('Bad JSON: %s' % e) try: method = json['method'] params = json['params'] id = json['id'] except KeyError, e: raise ValueError("JSON body missing parameter: %s" % e) if method.startswith('_'): raise exc.HTTPForbidden( "Bad method name %s: must not start with _" % method).exception if not isinstance(params, list): raise ValueError("Bad params %r: must be a list" % params) try: method = getattr(self.obj, method) except AttributeError: raise ValueError("No such method %s" % method) try: result = method(*params) except: text = traceback.format_exc() exc_value = sys.exc_info()[1] error_value = dict(name='JSONRPCError', code=100, message=str(exc_value), error=text)
def process_request(self, req): if req.headers.get('X-Auth-Token') != 'open-sesame': return exc.HTTPForbidden()
def _http_request(self, method, url, headers, body, ignore_result_body=False): """Perform an HTTP request against the server. method: the HTTP method to use url: the URL to request (not including server portion) headers: headers for the request body: body to send with the request ignore_result_body: the body of the result will be ignored Returns: a http_client response object """ if self.auth_token: headers.setdefault('x-auth-token', self.auth_token) LOG.debug( 'Request: %(method)s http://%(server)s:%(port)s' '%(url)s with headers %(headers)s', { 'method': method, 'server': self.conn.host, 'port': self.conn.port, 'url': url, 'headers': repr(headers) }) self.conn.request(method, url, body, headers) response = self.conn.getresponse() headers = self._header_list_to_dict(response.getheaders()) code = response.status code_description = http_client.responses[code] LOG.debug('Response: %(code)s %(status)s %(headers)s', { 'code': code, 'status': code_description, 'headers': repr(headers) }) if code == 400: raise exc.HTTPBadRequest(explanation=response.read()) if code == 500: raise exc.HTTPInternalServerError(explanation=response.read()) if code == 401: raise exc.HTTPUnauthorized(explanation=response.read()) if code == 403: raise exc.HTTPForbidden(explanation=response.read()) if code == 409: raise exc.HTTPConflict(explanation=response.read()) if ignore_result_body: # NOTE: because we are pipelining requests through a single HTTP # connection, http_client requires that we read the response body # before we can make another request. If the caller knows they # don't care about the body, they can ask us to do that for them. response.read() return response
def process_request(self, req): if req.headers.get('X-Auth-Token') != 'rainbow': return exc.HTTPForbidden()
def create(self, req, body): """Creates a new server for a given user.""" context = req.environ['nova.context'] server_dict = body['server'] password = self._get_server_admin_password(server_dict) name = server_dict['name'] # Arguments to be passed to instance create function create_kwargs = {} # Query extensions which want to manipulate the keyword # arguments. # NOTE(cyeoh): This is the hook that extensions use # to replace the extension specific code below. # When the extensions are ported this will also result # in some convenience function from this class being # moved to the extension if list(self.create_extension_manager): self.create_extension_manager.map(self._create_extension_point, server_dict, create_kwargs, body) image_uuid = self._image_from_req_data(server_dict, create_kwargs) # NOTE(cyeoh): Although an extension can set # return_reservation_id in order to request that a reservation # id be returned to the client instead of the newly created # instance information we do not want to pass this parameter # to the compute create call which always returns both. We use # this flag after the instance create call to determine what # to return to the client return_reservation_id = create_kwargs.pop('return_reservation_id', False) requested_networks = None if ('os-networks' in self.extension_info.get_extensions() or utils.is_neutron()): requested_networks = server_dict.get('networks') if requested_networks is not None: requested_networks = self._get_requested_networks( requested_networks) try: flavor_id = self._flavor_id_from_req_data(body) except ValueError as error: msg = _("Invalid flavorRef provided.") raise exc.HTTPBadRequest(explanation=msg) try: inst_type = flavors.get_flavor_by_flavor_id(flavor_id, ctxt=context, read_deleted="no") (instances, resv_id) = self.compute_api.create( context, inst_type, image_uuid, display_name=name, display_description=name, metadata=server_dict.get('metadata', {}), admin_password=password, requested_networks=requested_networks, check_server_group_quota=True, **create_kwargs) except (exception.QuotaError, exception.PortLimitExceeded) as error: raise exc.HTTPForbidden(explanation=error.format_message(), headers={'Retry-After': 0}) except exception.ImageNotFound: msg = _("Can not find requested image") raise exc.HTTPBadRequest(explanation=msg) except exception.FlavorNotFound: msg = _("Invalid flavorRef provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.KeypairNotFound: msg = _("Invalid key_name provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.ConfigDriveInvalidValue: msg = _("Invalid config_drive provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.ExternalNetworkAttachForbidden as error: raise exc.HTTPForbidden(explanation=error.format_message()) except messaging.RemoteError as err: msg = "%(err_type)s: %(err_msg)s" % { 'err_type': err.exc_type, 'err_msg': err.value } raise exc.HTTPBadRequest(explanation=msg) except UnicodeDecodeError as error: msg = "UnicodeError: %s" % error raise exc.HTTPBadRequest(explanation=msg) except (exception.ImageNotActive, exception.FlavorDiskTooSmall, exception.FlavorMemoryTooSmall, exception.InvalidMetadata, exception.InvalidRequest, exception.InvalidVolume, exception.MultiplePortsNotApplicable, exception.InvalidFixedIpAndMaxCountRequest, exception.InstanceUserDataMalformed, exception.InstanceUserDataTooLarge, exception.PortNotFound, exception.FixedIpAlreadyInUse, exception.SecurityGroupNotFound, exception.PortRequiresFixedIP, exception.NetworkRequiresSubnet, exception.NetworkNotFound, exception.InvalidBDMVolumeNotBootable, exception.InvalidBDMSnapshot, exception.InvalidBDMVolume, exception.InvalidBDMImage, exception.InvalidBDMBootSequence, exception.InvalidBDMLocalsLimit, exception.InvalidBDMVolumeNotBootable, exception.AutoDiskConfigDisabledByImage, exception.ImageNUMATopologyIncomplete, exception.ImageNUMATopologyForbidden, exception.ImageNUMATopologyAsymmetric, exception.ImageNUMATopologyCPUOutOfRange, exception.ImageNUMATopologyCPUDuplicates, exception.ImageNUMATopologyCPUsUnassigned, exception.ImageNUMATopologyMemoryOutOfRange) as error: raise exc.HTTPBadRequest(explanation=error.format_message()) except (exception.PortInUse, exception.InstanceExists, exception.NetworkAmbiguous, exception.NoUniqueMatch) as error: raise exc.HTTPConflict(explanation=error.format_message()) # If the caller wanted a reservation_id, return it if return_reservation_id: # NOTE(cyeoh): In v3 reservation_id was wrapped in # servers_reservation but this is reverted for V2 API # compatibility. In the long term with the tasks API we # will probably just drop the concept of reservation_id return wsgi.ResponseObject({'reservation_id': resv_id}) req.cache_db_instances(instances) server = self._view_builder.create(req, instances[0]) if CONF.enable_instance_password: server['server']['adminPass'] = password robj = wsgi.ResponseObject(server) return self._add_location(robj)
def run(self): #imageName=str(uuid.uuid4()) #create image #image_meta = self.compute_api.snapshot(self.context, self.instance, name=imageId, extra_properties=None) bdms = objects.BlockDeviceMappingList.get_by_instance_uuid( self.context, self.instance['uuid']) volume_ids = [bdm.volume_id for bdm in bdms if bdm.volume_id] image_uuid = None if volume_ids is None or volume_ids == []: tmp_image_name = "%s@%s" % (uuid.uuid1(), self.instance.uuid) image_meta = self.compute_api.snapshot(self.context, self.instance, name=tmp_image_name, extra_properties=None) image_uuid = image_meta['id'] try: filters = {'name':tmp_image_name} imagelist = self.image_api.get_all(self.context,filters=filters) image = imagelist[0] while image['status'] != 'active': time.sleep(1) imagelist = self.image_api.get_all(self.context,filters=filters) image = imagelist[0] image_uuid = image['id'] image = self.image_api.get(self.context,image_uuid ) except (exception.NotFound, exception.InvalidImageRef): explanation = _("Image not found.") raise webob.exc.HTTPNotFound(explanation=explanation) else : for volume_id in volume_ids: volume = self.volume_api.get(self.context, volume_id) #import pdb #pdb.set_trace() response = self.volume_api.upload_to_image(self.context, volume_id, True, volume_id, 'bare', 'qcow2') image_uuid = response[1]['os-volume_upload_image']['image_id'] #image_uuid = image_meta['id'] try: image = self.image_api.get(self.context, image_uuid) cascading_image_name = image['id'] filters = {'name':cascading_image_name} cascading_image = self.image_api.get_all(self.context,filters=filters) cascading_image_id = cascading_image[0]['id'] cascading_image = self.image_api.get(self.context,cascading_image_id ) while cascading_image['status'] != 'active': time.sleep(1) cascading_image = self.image_api.get(self.context,cascading_image_id ) except (exception.NotFound, exception.InvalidImageRef): explanation = _("Image not found.") raise webob.exc.HTTPNotFound(explanation=explanation) access_ip_v4 = self.instance.access_ip_v4 if access_ip_v4 is not None: self._validate_access_ipv4(access_ip_v4) access_ip_v6 = self.instance.access_ip_v6 if access_ip_v6 is not None: self._validate_access_ipv6(access_ip_v6) #networks = common.get_networks_for_instance(context, instance) min_count = 1 max_count = 1 name=self.instance.display_name key_name = None metadata = self.instance.metadata injected_files = [] security_group=self.instance.security_groups user_data=self.instance.user_data flavor_id = self.instance.system_metadata['instance_type_flavorid'] scheduler_hints = {} legacy_bdm = True #check_server_group_quota = \ # self.ext_mgr.is_loaded('os-server-group-quotas') check_server_group_quota=True requested_networks = [] nw_info = compute_utils.get_nw_info_for_instance(self.instance) for vif in nw_info: net_uuid = vif['network']['id'] net_ip = vif['network']['subnets'][0]['ips'][0]['address'] requested_networks.append({'fixed_ip':net_ip, 'uuid':net_uuid}) requested_networks = self._get_requested_networks(requested_networks) #detach port delete self.compute_api.delete(self.context,self.instance) while True: time.sleep(3) try: _get_inst_type = flavors.get_flavor_by_flavor_id inst_type = _get_inst_type(flavor_id, ctxt=self.context, read_deleted="no") (instances, resv_id) = self.compute_api.create(self.context, inst_type, image_uuid, display_name=name, display_description=name, key_name=key_name, metadata=metadata, access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6, injected_files=injected_files, admin_password=None, min_count=min_count, max_count=max_count, requested_networks=requested_networks, security_group=security_group, user_data=user_data, availability_zone=self.availability_zone, config_drive=None, block_device_mapping=None, auto_disk_config=None, scheduler_hints=scheduler_hints, legacy_bdm=legacy_bdm, check_server_group_quota=check_server_group_quota) except (exception.QuotaError, exception.PortLimitExceeded) as error: raise exc.HTTPForbidden( explanation=error.format_message(), headers={'Retry-After': 0}) except exception.InvalidMetadataSize as error: raise exc.HTTPRequestEntityTooLarge( explanation=error.format_message()) except exception.ImageNotFound as error: msg = _("Can not find requested image") raise exc.HTTPBadRequest(explanation=msg) except exception.FlavorNotFound as error: msg = _("Invalid flavorRef provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.KeypairNotFound as error: msg = _("Invalid key_name provided.") raise exc.HTTPBadRequest(explanation=msg) except exception.ConfigDriveInvalidValue: msg = _("Invalid config_drive provided.") raise exc.HTTPBadRequest(explanation=msg) except UnicodeDecodeError as error: msg = "UnicodeError: %s" % unicode(error) raise exc.HTTPBadRequest(explanation=msg) except (exception.ImageNotActive, exception.FlavorDiskTooSmall, exception.FlavorMemoryTooSmall, exception.NetworkNotFound, exception.PortNotFound, exception.FixedIpAlreadyInUse, exception.SecurityGroupNotFound, exception.InstanceUserDataTooLarge, exception.InstanceUserDataMalformed) as error: raise exc.HTTPBadRequest(explanation=error.format_message()) except (exception.ImageNUMATopologyIncomplete, exception.ImageNUMATopologyForbidden, exception.ImageNUMATopologyAsymmetric, exception.ImageNUMATopologyCPUOutOfRange, exception.ImageNUMATopologyCPUDuplicates, exception.ImageNUMATopologyCPUsUnassigned, exception.ImageNUMATopologyMemoryOutOfRange) as error: raise exc.HTTPBadRequest(explanation=error.format_message()) except (exception.PortInUse, exception.NoUniqueMatch) as error: continue raise exc.HTTPConflict(explanation=error.format_message()) except exception.Invalid as error: raise exc.HTTPBadRequest(explanation=error.format_message()) break
def _revert(self, req, id, body=None): """Revert a share to a snapshot.""" context = req.environ['manila.context'] revert_data = self._validate_revert_parameters(context, body) try: share_id = id snapshot_id = revert_data['snapshot_id'] share = self.share_api.get(context, share_id) snapshot = self.share_api.get_snapshot(context, snapshot_id) # Ensure share supports reverting to a snapshot if not share['revert_to_snapshot_support']: msg_args = {'share_id': share_id, 'snap_id': snapshot_id} msg = _('Share %(share_id)s may not be reverted to snapshot ' '%(snap_id)s, because the share does not have that ' 'capability.') raise exc.HTTPBadRequest(explanation=msg % msg_args) # Ensure requested share & snapshot match. if share['id'] != snapshot['share_id']: msg_args = {'share_id': share_id, 'snap_id': snapshot_id} msg = _('Snapshot %(snap_id)s is not associated with share ' '%(share_id)s.') raise exc.HTTPBadRequest(explanation=msg % msg_args) # Ensure share status is 'available'. if share['status'] != constants.STATUS_AVAILABLE: msg_args = { 'share_id': share_id, 'state': share['status'], 'available': constants.STATUS_AVAILABLE, } msg = _("Share %(share_id)s is in '%(state)s' state, but it " "must be in '%(available)s' state to be reverted to a " "snapshot.") raise exc.HTTPConflict(explanation=msg % msg_args) # Ensure snapshot status is 'available'. if snapshot['status'] != constants.STATUS_AVAILABLE: msg_args = { 'snap_id': snapshot_id, 'state': snapshot['status'], 'available': constants.STATUS_AVAILABLE, } msg = _("Snapshot %(snap_id)s is in '%(state)s' state, but it " "must be in '%(available)s' state to be restored.") raise exc.HTTPConflict(explanation=msg % msg_args) # Ensure a long-running task isn't active on the share if share.is_busy: msg_args = {'share_id': share_id} msg = _("Share %(share_id)s may not be reverted while it has " "an active task.") raise exc.HTTPConflict(explanation=msg % msg_args) # Ensure the snapshot is the most recent one. latest_snapshot = self.share_api.get_latest_snapshot_for_share( context, share_id) if not latest_snapshot: msg_args = {'share_id': share_id} msg = _("Could not determine the latest snapshot for share " "%(share_id)s.") raise exc.HTTPBadRequest(explanation=msg % msg_args) if latest_snapshot['id'] != snapshot_id: msg_args = { 'share_id': share_id, 'snap_id': snapshot_id, 'latest_snap_id': latest_snapshot['id'], } msg = _("Snapshot %(snap_id)s may not be restored because " "it is not the most recent snapshot of share " "%(share_id)s. Currently the latest snapshot is " "%(latest_snap_id)s.") raise exc.HTTPConflict(explanation=msg % msg_args) # Ensure the access rules are not in the process of updating for instance in share['instances']: access_rules_status = instance['access_rules_status'] if access_rules_status != constants.ACCESS_STATE_ACTIVE: msg_args = { 'share_id': share_id, 'snap_id': snapshot_id, 'state': constants.ACCESS_STATE_ACTIVE } msg = _("Snapshot %(snap_id)s belongs to a share " "%(share_id)s which has access rules that are" "not %(state)s.") raise exc.HTTPConflict(explanation=msg % msg_args) msg_args = {'share_id': share_id, 'snap_id': snapshot_id} msg = 'Reverting share %(share_id)s to snapshot %(snap_id)s.' LOG.info(msg, msg_args) self.share_api.revert_to_snapshot(context, share, snapshot) except exception.ShareNotFound as e: raise exc.HTTPNotFound(explanation=six.text_type(e)) except exception.ShareSnapshotNotFound as e: raise exc.HTTPBadRequest(explanation=six.text_type(e)) except exception.ShareSizeExceedsAvailableQuota as e: raise exc.HTTPForbidden(explanation=six.text_type(e)) except exception.ReplicationException as e: raise exc.HTTPBadRequest(explanation=six.text_type(e)) return webob.Response(status_int=202)
def update(self, req, id, body): """Update specified share network.""" context = req.environ['manila.context'] policy.check_policy(context, RESOURCE_NAME, 'update') if not body or RESOURCE_NAME not in body: raise exc.HTTPUnprocessableEntity() try: share_network = db_api.share_network_get(context, id) except exception.ShareNetworkNotFound as e: raise exc.HTTPNotFound(explanation=six.text_type(e)) update_values = body[RESOURCE_NAME] if 'nova_net_id' in update_values: msg = _("nova networking is not supported starting in Ocata.") raise exc.HTTPBadRequest(explanation=msg) if self._share_network_subnets_contain_share_servers(share_network): for value in update_values: if value not in ['name', 'description']: msg = (_("Cannot update share network %s. It is used by " "share servers. Only 'name' and 'description' " "fields are available for update") % share_network['id']) raise exc.HTTPForbidden(explanation=msg) try: if ('neutron_net_id' in update_values or 'neutron_subnet_id' in update_values): subnet = db_api.share_network_subnet_get_default_subnet( context, id) if not subnet: msg = _("The share network %(id)s does not have a " "'default' subnet that serves all availability " "zones, so subnet details " "('neutron_net_id', 'neutron_subnet_id') cannot " "be updated.") % { 'id': id } raise exc.HTTPBadRequest(explanation=msg) # NOTE(silvacarlose): If the default share network subnet have # the fields neutron_net_id and neutron_subnet_id set as None, # we need to make sure that in the update request the user is # passing both parameter since a share network subnet must # have both fields filled or empty. subnet_neutron_net_and_subnet_id_are_empty = ( subnet['neutron_net_id'] is None and subnet['neutron_subnet_id'] is None) update_values_without_neutron_net_or_subnet = ( update_values.get('neutron_net_id') is None or update_values.get('neutron_subnet_id') is None) if (subnet_neutron_net_and_subnet_id_are_empty and update_values_without_neutron_net_or_subnet): msg = _("To update the share network %(id)s you need to " "specify both 'neutron_net_id' and " "'neutron_subnet_id'.") % { 'id': id } raise webob.exc.HTTPBadRequest(explanation=msg) db_api.share_network_subnet_update(context, subnet['id'], update_values) share_network = db_api.share_network_update( context, id, update_values) except db_exception.DBError: msg = "Could not save supplied data due to database error" raise exc.HTTPBadRequest(explanation=msg) return self._view_builder.build_share_network(req, share_network)
def create(self, req, body): """Creates a new server for a given user.""" if not self.is_valid_body(body, 'server'): raise exc.HTTPUnprocessableEntity() context = req.environ['nova.context'] server_dict = body['server'] password = self._get_server_admin_password(server_dict) if 'name' not in server_dict: msg = _("Server name is not defined") raise exc.HTTPBadRequest(explanation=msg) name = server_dict['name'] self._validate_server_name(name) name = name.strip() image_uuid = self._image_from_req_data(body) personality = server_dict.get('personality') config_drive = None if self.ext_mgr.is_loaded('os-config-drive'): config_drive = server_dict.get('config_drive') injected_files = [] if personality: injected_files = self._get_injected_files(personality) sg_names = [] if self.ext_mgr.is_loaded('os-security-groups'): security_groups = server_dict.get('security_groups') if security_groups is not None: sg_names = [ sg['name'] for sg in security_groups if sg.get('name') ] if not sg_names: sg_names.append('default') sg_names = list(set(sg_names)) requested_networks = self._determine_requested_networks(server_dict) (access_ip_v4, ) = server_dict.get('accessIPv4'), if access_ip_v4 is not None: self._validate_access_ipv4(access_ip_v4) (access_ip_v6, ) = server_dict.get('accessIPv6'), if access_ip_v6 is not None: self._validate_access_ipv6(access_ip_v6) flavor_id = self._flavor_id_from_req_data(body) # optional openstack extensions: key_name = self._extract(server_dict, 'os-keypairs', 'key_name') availability_zone = self._extract(server_dict, 'os-availability-zone', 'availability_zone') user_data = self._extract(server_dict, 'os-user-data', 'user_data') self._validate_user_data(user_data) legacy_bdm, block_device_mapping = self._extract_bdm(server_dict) ret_resv_id = False # min_count and max_count are optional. If they exist, they may come # in as strings. Verify that they are valid integers and > 0. # Also, we want to default 'min_count' to 1, and default # 'max_count' to be 'min_count'. min_count = 1 max_count = 1 if self.ext_mgr.is_loaded('os-multiple-create'): ret_resv_id = server_dict.get('return_reservation_id', False) min_count = server_dict.get('min_count', 1) max_count = server_dict.get('max_count', min_count) try: min_count = utils.validate_integer(min_count, "min_count", min_value=1) max_count = utils.validate_integer(max_count, "max_count", min_value=1) except exception.InvalidInput as e: raise exc.HTTPBadRequest(explanation=e.format_message()) if min_count > max_count: msg = _('min_count must be <= max_count') raise exc.HTTPBadRequest(explanation=msg) auto_disk_config = False if self.ext_mgr.is_loaded('OS-DCF'): auto_disk_config = server_dict.get('auto_disk_config') scheduler_hints = {} if self.ext_mgr.is_loaded('OS-SCH-HNT'): scheduler_hints = server_dict.get('scheduler_hints', {}) check_server_group_quota = self.ext_mgr.is_loaded( 'os-server-group-quotas') try: _get_inst_type = flavors.get_flavor_by_flavor_id inst_type = _get_inst_type(flavor_id, ctxt=context, read_deleted="no") (instances, resv_id) = self.compute_api.create( context, inst_type, image_uuid, display_name=name, display_description=name, key_name=key_name, metadata=server_dict.get('metadata', {}), access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6, injected_files=injected_files, admin_password=password, min_count=min_count, max_count=max_count, requested_networks=requested_networks, security_group=sg_names, user_data=user_data, availability_zone=availability_zone, config_drive=config_drive, block_device_mapping=block_device_mapping, auto_disk_config=auto_disk_config, scheduler_hints=scheduler_hints, legacy_bdm=legacy_bdm, check_server_group_quota=check_server_group_quota) except (exception.QuotaError, exception.PortLimitExceeded) as error: raise exc.HTTPForbidden(explanation=error.format_message(), headers={'Retry-After': 0}) except messaging.RemoteError as err: msg = "%(err_type)s: %(err_msg)s" % { 'err_type': err.exc_type, 'err_msg': err.value } raise exc.HTTPBadRequest(explanation=msg) except UnicodeDecodeError as error: msg = "UnicodeError: %s" % error raise exc.HTTPBadRequest(explanation=msg) except Exception as error: # The remaining cases can be handled in a standard fashion. self._handle_create_exception(*sys.exc_info()) # If the caller wanted a reservation_id, return it if ret_resv_id: return wsgi.ResponseObject({'reservation_id': resv_id}) req.cache_db_instances(instances) server = self._view_builder.create(req, instances[0]) if CONF.enable_instance_password: server['server']['adminPass'] = password robj = wsgi.ResponseObject(server) return self._add_location(robj)
def create(self, req, body): context = _authorize_context(req) sg_rule = self._from_body(body, 'security_group_rule') group_id = sg_rule.get('group_id') source_group = {} try: parent_group_id = self.security_group_api.validate_id( sg_rule.get('parent_group_id')) security_group = self.security_group_api.get(context, None, parent_group_id, map_exception=True) if group_id is not None: group_id = self.security_group_api.validate_id(group_id) source_group = self.security_group_api.get( context, id=group_id) new_rule = self._rule_args_to_dict(context, to_port=sg_rule.get('to_port'), from_port=sg_rule.get('from_port'), ip_protocol=sg_rule.get('ip_protocol'), cidr=sg_rule.get('cidr'), group_id=group_id) except (exception.Invalid, exception.InvalidCidr) as exp: raise exc.HTTPBadRequest(explanation=exp.format_message()) except exception.SecurityGroupNotFound as exp: raise exc.HTTPNotFound(explanation=exp.format_message()) if new_rule is None: msg = _("Not enough parameters to build a valid rule.") raise exc.HTTPBadRequest(explanation=msg) new_rule['parent_group_id'] = security_group['id'] if 'cidr' in new_rule: net, prefixlen = netutils.get_net_and_prefixlen(new_rule['cidr']) if net not in ('0.0.0.0', '::') and prefixlen == '0': msg = _("Bad prefix for network in cidr %s") % new_rule['cidr'] raise exc.HTTPBadRequest(explanation=msg) group_rule_data = None try: if group_id: group_rule_data = {'name': source_group.get('name'), 'tenant_id': source_group.get('project_id')} security_group_rule = ( self.security_group_api.create_security_group_rule( context, security_group, new_rule)) except exception.Invalid as exp: raise exc.HTTPBadRequest(explanation=exp.format_message()) except exception.SecurityGroupNotFound as exp: raise exc.HTTPNotFound(explanation=exp.format_message()) except exception.SecurityGroupLimitExceeded as exp: raise exc.HTTPForbidden(explanation=exp.format_message()) formatted_rule = self._format_security_group_rule(context, security_group_rule, group_rule_data) return {"security_group_rule": formatted_rule}
def auth_filter(request, app): if request.headers.get('X-Auth-Token') != 'open-sesame': return exc.HTTPForbidden() return app(request)
def _process(self, req): """ a request URL is parsed as follow /object/resource?args object is the main python object GET /object is mapped to handle_get function(**kwargs) GET /object/resource is mapped to handle_get([resource,], **kwargs) GET /object/resource/resource2 is mapped to handle_get([resource,resource2], **kwargs) args are always passed on through **kwargs """ method = req.method object = req.path_info_pop() #do some static file serving logic first before trying functions on objects if object == None or object == "": #the root / is moved to static file serving res = exc.HTTPMovedPermanently(location="/static/") return res elif object == "static": # In here we are handling real files so be careful!!! if method == "GET": # simply serving static files #import os #print(os.getcwd()) res = static.DirectoryApp(self._httpdRoot) return res if method == "POST": # uploading new files filename = req.path_info_pop() filepath = os.path.join(os.path.join(self._httpdRoot, filename)) # if the file exists we raise an exception if filename == "": filename = req.params['file'] if os.path.exists(filepath): raise exc.HTTPForbidden("%s already exists" % filename) #print(dir(req)) #print(req.body) saveFile = open(os.path.join(self._httpdRoot, filename), 'wb') saveFile.write(req.body_file.read()) saveFile.close() return Response("ok") if method == "PUT": # This will overwrite your files # uploading files to update filename = req.path_info_pop() filepath = os.path.join(os.path.join(self._httpdRoot, filename)) # if the file exists we raise an exception if not os.path.exists(filepath): raise exc.HTTPNotFound("%s file not found" % filename) if filename == "": filename = req.params['file'] #print(dir(req)) #print(req.body) saveFile = open(os.path.join(self._httpdRoot, filename), 'wb') saveFile.write(req.body_file.read()) saveFile.close() return Response("ok") ################################################# # # After this we only handle JSON type content!!!! # ################################################# #Find the object obj = None try: obj = self._restObjects[object] except: #print(self._restObjects) #print(dir(self._restObjects)) raise exc.HTTPNotFound('No such resource: %s' % object) #Find the function func = None try: func = getattr(obj, 'handle_' + method) except: raise exc.HTTPNotFound('No %s method on resource: %s' % (method, object)) # Find resources: resources = [] # get first resource res = req.path_info_pop() while res: resources.append(res) # get next resource res = req.path_info_pop() #optional extra headers #FIXME: this shouldn't be hardcoded. The appie modules should take care of this #http://www.w3.org/TR/cors/#syntax extraHeaderList = [ ('Access-Control-Allow-Origin', '*'), ('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS'), ('Access-Control-Max-Age', '86400'), ('Access-Control-Allow-Headers', 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version' ) ] #Get args kwargs = req.GET if (method == 'POST'): #curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d #curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"test" : "help" }' http://localhost:8000/bge/IcoSphere if req.content_type == 'application/json': encoding = req.charset body = req.body.decode(encoding) data = loads(body) #print(data) #print(type(data)) kwargs = data else: kwargs = req.POST try: result = func(*resources, **kwargs) except: raise exc.HTTPInternalServerError( "Appie raised an exception while calling the method with %s %s" % (str(resources), str(kwargs))) resp = Response(content_type='application/json', charset='utf8', body=dumps(result)) resp.headerlist.extend(extraHeaderList) return resp