def get(self, request): """Get a list of nova services. Will return HTTP 501 status code if the service_list extension is not supported. """ if api.base.is_service_enabled(request, 'compute') \ and api.nova.extension_supported('Services', request): result = api.nova.service_list(request) return {'items': [u.to_dict() for u in result]} else: raise rest_utils.AjaxError(501, '')
def post(self, request): form = UploadObjectForm(request.DATA, request.FILES) if not form.is_valid(): raise rest_utils.AjaxError(500, 'Invalid request') data = form.clean() meta = create_image_metadata(request.DATA) meta['data'] = data['data'] image = api.glance.image_create(request, **meta) return rest_utils.CreatedResponse('/api/glance/images/%s' % image.name, image.to_dict())
def handle_visibility(visibility, meta): mapping_to_v1 = {'public': True, 'private': False, 'shared': False} # note: presence of 'visibility' previously checked for in general call try: is_public = mapping_to_v1[visibility] if api.glance.VERSIONS.active >= 2: meta['visibility'] = visibility else: meta['is_public'] = is_public except KeyError as e: raise rest_utils.AjaxError(400, 'invalid visibility option: %s' % e.args[0])
def handle_visibility(visibility, meta): # The following expects a 'visibility' parameter to be passed via # the AJAX call, then translates this to a Glance API v1 is_public # parameter. In the future, if the 'visibility' param is exposed on the # glance API, you can check for version, e.g.: # if float(api.glance.get_version()) < 2.0: mapping_to_v1 = {'public': True, 'private': False, 'shared': False} # note: presence of 'visibility' previously checked for in general call try: meta['is_public'] = mapping_to_v1[visibility] except KeyError as e: raise rest_utils.AjaxError(400, 'invalid visibility option: %s' % e.args[0])
def patch(self, request): """Update the values for Cinder specific quotas This method returns HTTP 204 (no content) on success. """ if api.cinder.is_volume_service_enabled(request): cinder_data = { key: request.DATA[key] for key in quotas.CINDER_QUOTA_FIELDS } api.cinder.default_quota_update(request, **cinder_data) else: raise rest_utils.AjaxError(501, _('Service Cinder is disabled.'))
def post(self, request): """Create a server. Create a server using the parameters supplied in the POST application/json object. The required parameters as specified by the underlying novaclient are: :param name: The new server name. :param source_id: The ID of the image to use. :param flavor_id: The ID of the flavor to use. :param key_name: (optional extension) name of previously created keypair to inject into the instance. :param user_data: user data to pass to be exposed by the metadata server this can be a file type object as well or a string. :param security_groups: An array of one or more objects with a "name" attribute. Other parameters are accepted as per the underlying novaclient: "block_device_mapping", "block_device_mapping_v2", "nics", "meta", "availability_zone", "instance_count", "admin_pass", "disk_config", "config_drive", "scheduler_hints", "min_inst_count" This returns the new server object on success. """ try: args = ( request, request.DATA['name'], request.DATA['source_id'], request.DATA['flavor_id'], request.DATA['key_name'], request.DATA['user_data'], request.DATA['security_groups'], ) except KeyError as e: raise rest_utils.AjaxError(400, 'missing required parameter ' "'%s'" % e.args[0]) kw = {} for name in self._optional_create: if name in request.DATA: data = request.DATA[name] kw[name] = data new = api.nova.server_create(*args, **kw) return rest_utils.CreatedResponse( '/api/nova/servers/%s' % utils_http.urlquote(new.id), new.to_dict() )
def post(self, request): """Perform some action on the collection of users. The POST data should be an application/json object with two parameters: "action" and "data". action = "delete" This action deletes multiple users in one call, using the list of ids (strings) passed in as data. This action returns HTTP 204 (no content) on success. action = "create" This action creates a user using the parameters supplied in "data". The base parameters are name (string), email (string, optional), password (string, optional), project_id (string, optional), enabled (boolean, defaults to true). The user will be created in the default domain. This action returns the new user object on success. This action returns HTTP 204 (no content) on success. """ action = request.DATA['action'] data = request.DATA['data'] if action == 'delete': for user_id in data: if user_id != request.user.id: api.keystone.user_delete(request, user_id) elif action == 'create': # not sure why email is forced to None, but other code does it domain = api.keystone.get_default_domain(request) new_user = api.keystone.user_create( request, name=data['name'], email=data.get('email') or None, password=data.get('password'), project=data.get('project_id'), enabled=True, domain=domain.id ) return rest_utils.CreatedResponse( '/api/keystone/users/%s' % new_user.id, new_user.to_dict() ) else: raise rest_utils.AjaxError(400, 'invalid action')
def _verify_arguments(self, security_groups): try: args = ( self.request, self.request.DATA['name'], self.request.DATA['source_id'], self.request.DATA['flavor'], self.request.DATA['key_name'], None, security_groups, ) except KeyError as e: raise rest_utils.AjaxError(400, 'missing required parameter ' "'%s'" % e.args[0]) return args
def get(self, request): if api.base.is_service_enabled(request, 'network'): quota_set = api.neutron.tenant_quota_get( request, request.user.tenant_id) result = [{ 'display_name': quotas.QUOTA_NAMES.get( quota.name, quota.name.replace('_', ' ').title() ) + '', 'name': quota.name, 'limit': quota.limit } for quota in quota_set] return {'items': result} else: raise rest_utils.AjaxError(501, _('Service Neutron is disabled.'))
def post(self, request): """Perform some action on the collection of roles. The POST data should be an application/json object with two parameters: "action" and "data". action = "delete" This action deletes multiple roles in one call, using the list of ids (strings) passed in as data. This method returns HTTP 204 (no content) on success. action = "create" This action creates a role using the "name" (string) parameter supplied in the "data" object. This method returns the new role object on success. action = "grant" This action adds a role to a user using the parameters "user_id" (string), "project_id" (string) and "role_id" (string). This method returns HTTP 204 (no content) on success. """ action = request.DATA['action'] data = request.DATA['data'] if action == 'delete': for role_id in data: api.keystone.role_delete(request, role_id) elif action == 'create': new_role = api.keystone.role_create(request, data['name']) return rest_utils.CreatedResponse( '/api/keystone/roles/%s' % new_role.id, new_role.to_dict() ) elif action == 'grant': api.keystone.add_tenant_user_role( request, data['project_id'], data['user_id'], data['role_id'] ) else: raise rest_utils.AjaxError(400, 'invalid (unrecognised) action')
def get(self, request): """Provides a list with the user's servers Example GET: http://localhost/api/extension/servers """ try: instances, _more = server_list( request, search_opts=rest_utils.parse_filters_kwargs(request)[0]) except Exception as e: raise rest_utils.AjaxError(400, 'Unable to retrieve instances. ' "'%s'" % e.args[0]) all_servers = [u.to_dict() for u in instances] return { 'items': all_servers }
def post(self, request, container, object_name): """Create or replace an object or pseudo-folder :param request: :param container: :param object_name: If the object_name (ie. POST path) ends in a '/' then a folder is created, rather than an object. Any file content passed along with the request will be ignored in that case. POST parameter: :param file: the file data for the upload. :return: """ form = UploadObjectForm(request.POST, request.FILES) if not form.is_valid(): raise rest_utils.AjaxError(500, 'Invalid request') data = form.clean() if object_name[-1] == '/': try: result = api.swift.swift_create_pseudo_folder( request, container, object_name ) except exceptions.AlreadyExists as e: return rest_utils.JSONResponse(str(e), 409) else: result = api.swift.swift_upload_object( request, container, object_name, data['file'] ) return rest_utils.CreatedResponse( u'/api/swift/containers/%s/object/%s' % (container, result.name) )
def patch(self, request, project_id): """Update a single project quota data. The PATCH data should be an application/json object with the attributes to set to new quota values. This method returns HTTP 204 (no content) on success. """ disabled_quotas = quotas.get_disabled_quotas(request) if api.base.is_service_enabled(request, 'compute'): nova_data = { key: request.DATA[key] for key in quotas.NOVA_QUOTA_FIELDS if key not in disabled_quotas } api.nova.tenant_quota_update(request, project_id, **nova_data) else: raise rest_utils.AjaxError(501, _('Service Nova is disabled.'))
def delete(self, request): """Delete a list of servers. Example GET: http://localhost/api/nova/servers """ try: args = ( request, request.DATA['instances_ids'], ) except KeyError as e: raise rest_utils.AjaxError( 400, 'missing required parameter ' "'%s'" % e.args[0]) for id in request.DATA['instances_ids']: api.nova.reset_state(request, id, 'active') api.nova.server_delete(request, id)
def get(self, request): """Get a list of cinder services. Will return HTTP 501 status code if the service_list extension is not supported. """ if api.base.is_service_enabled(request, 'volume') and \ api.cinder.extension_supported(request, 'Services'): result = api.cinder.service_list(request) return {'items': [{ 'binary': u.binary, 'host': u.host, 'zone': u.zone, 'updated_at': u.updated_at, 'status': u.status, 'state': u.state, 'id': idx + 1 } for idx, u in enumerate(result)]} else: raise rest_utils.AjaxError(501, '')
def post(self, request): """Create a project (tenant). Create a project using parameters supplied in the POST application/json object. The "name" (string) parameter is required, others are optional: "description" (string), "domain_id" (string) and "enabled" (boolean, defaults to true). Additional, undefined parameters may also be provided, but you'll have to look deep into keystone to figure out what they might be. This method returns the new project object on success. """ kwargs = _tenant_kwargs_from_DATA(request.DATA) if not kwargs['name']: raise rest_utils.AjaxError(400, '"name" is required') new_project = api.keystone.tenant_create(request, **kwargs) return rest_utils.CreatedResponse( '/api/keystone/projects/%s' % new_project.id, new_project.to_dict())
def create_instance(self, request, suffix=""): # Instances need to be created one by one, because each instance # needs to have it's own GBP port kw = {'instance_count': 1} # Mandatory creation arguments and port creation try: instance_name = request.DATA['name'] + suffix if "group_policy_targets" in request.DATA and ( request.DATA["group_policy_targets"]): meta_data, nics = self.create_ports(request, instance_name) kw['meta'] = meta_data kw['nics'] = nics else: if 'nics' in request.DATA: kw['nics'] = request.DATA['nics'] if 'meta' in request.DATA: kw['meta'] = request.DATA['meta'] args = ( request, instance_name, request.DATA['source_id'], request.DATA['flavor_id'], request.DATA['key_name'], request.DATA['user_data'], request.DATA['security_groups'], ) except KeyError as e: raise rest_utils.AjaxError( 400, 'Missing required parameter ' "'%s'" % e.args[0]) # Optional creation arguments for name in self.optional_arguments: if name in request.DATA: kw[name] = request.DATA[name] return api.nova.server_create(*args, **kw)
def post(self, request): try: args = (request, request.DATA['selected_range'], request.DATA['instance_count']) except KeyError as e: raise rest_utils.AjaxError( 400, 'missing required parameter' "'%s'" % e.args[0]) selected_range = request.DATA['selected_range'] instance_count = request.DATA['instance_count'] unassigned_ips = set([ addr.ip for addr in api.network.tenant_floating_ip_list(request) if addr.instance_id is None ]) allocated_ips = set( [addr.ip for addr in api.network.tenant_floating_ip_list(request)]) already_associated = list(allocated_ips - unassigned_ips) already_associated_set = IPSet(already_associated) already_associated_ranges = list( already_associated_set.iter_ipranges()) ranges_set = IPSet( IPRange(selected_range['start'], selected_range['end'])) for associated_range in already_associated_ranges: print(associated_range) ranges_set.remove(associated_range) available_ips = [] for ip in ranges_set: if len(available_ips) < instance_count: available_ips.append(ip) else: break return {"available_ips": available_ips}
def patch(self, request, project_id): """Update a single project quota data. The PATCH data should be an application/json object with the attributes to set to new quota values. This method returns HTTP 204 (no content) on success. """ # Filters cinder quota fields disabled_quotas = quotas.get_disabled_quotas(request) if api.cinder.is_volume_service_enabled(request): cinder_data = { key: request.DATA[key] for key in quotas.CINDER_QUOTA_FIELDS if key not in disabled_quotas } api.cinder.tenant_quota_update(request, project_id, **cinder_data) else: raise rest_utils.AjaxError(501, _('Service Cinder is disabled.'))
def post(self, request): instance_count = request.DATA['instance_count'] try: if instance_count == 1: self.create_instance(request) elif instance_count > 1: for i in range(0, instance_count): self.create_instance(request, "_" + str(i)) except Exception: instance_name = request.DATA['name'] error = _("Unable to launch member %(count)s with name %(name)s") message = error % {'count': instance_count, 'name': instance_name} LOG.exception(message) raise rest_utils.AjaxError(400, message) return rest_utils.CreatedResponse('/api/nova/servers/%s')
def patch(self, request): """Update the values for Nova specific quotas This method returns HTTP 204 (no content) on success. """ if api.base.is_service_enabled(request, 'compute'): disabled_quotas = quotas.get_disabled_quotas(request) filtered_quotas = [quota for quota in quotas.NOVA_QUOTA_FIELDS if quota not in disabled_quotas] request_data = { key: request.DATA.get(key, None) for key in filtered_quotas } nova_data = {key: value for key, value in request_data.items() if value is not None} api.nova.default_quota_update(request, **nova_data) else: raise rest_utils.AjaxError(501, _('Service Nova is disabled.'))
def post(self, request): """Perform some action on the collection of domains. The POST data should be an application/json object with two parameters: "action" and "data". action = "delete" This action deletes multiple domains in one call, using the list of ids (strings) passed in as data. This method returns HTTP 204 (no content) on success. action = "create" This action creates a domain using parameters supplied in the "data" object. The "name" (string) parameter is required, others are optional: "description" (string) and "enabled" (boolean, defaults to true). This method returns the new domain object on success. """ action = request.DATA['action'] data = request.DATA['data'] if action == 'delete': for domain_id in data: api.keystone.domain_delete(request, domain_id) elif action == 'create': new_domain = api.keystone.domain_create( request, data['name'], description=data.get('description'), enabled=data.get('enabled', True), ) return rest_utils.CreatedResponse( '/api/keystone/domains/%s' % new_domain.id, new_domain.to_dict() ) else: raise rest_utils.AjaxError(400, 'invalid action')
def create_image_metadata(data): try: """Use the given dict of image form data to generate the metadata used for creating the image in glance. """ meta = { 'protected': data.get('protected'), 'min_disk': data.get('min_disk', 0), 'min_ram': data.get('min_ram', 0), 'name': data.get('name'), 'disk_format': data.get('disk_format'), 'container_format': data.get('container_format') } properties = {} # 'architecture' will be directly mapped # into the .properties by the handle_unknown_properties function. # 'kernel' and 'ramdisk' need to get specifically mapped for backwards # compatibility. props = data.get('properties') if props and props.get('description'): properties['description'] = props.get('description') if data.get('kernel'): properties['kernel_id'] = data.get('kernel') if data.get('ramdisk'): properties['ramdisk_id'] = data.get('ramdisk') handle_unknown_properties(data, properties) if api.glance.VERSIONS.active >= 2: meta.update(properties) else: meta['properties'] = properties handle_visibility(data.get('visibility'), meta) except KeyError as e: raise rest_utils.AjaxError(400, 'missing required parameter %s' % e.args[0]) return meta
def post(self, request): """Get a list of servers. The listing result is an object with property "items". Each item is a server. Example GET: http://localhost/api/nova/recover_servers/ """ try: args = (request, request.DATA['selectedInstances']) except KeyError as e: raise rest_utils.AjaxError( 400, 'missing required parameter' "'%s'" % e.args[0]) for ins in request.DATA['selectedInstances']: bdm = {'vda': ins['instance_volume_id'] + ':vol::false'} nic = [{ 'net-id': ins['net_id'], 'v4-fixed-ip': ins['internal_ip'] }] time.sleep(3) api.nova.server_create(request, name=ins['instance_name'], image='', flavor=ins['flavor_id'], key_name=None, user_data='', security_groups=[], block_device_mapping=bdm, nics=nic, disk_config="AUTO", config_drive=False) time.sleep(2) if ins['floating_ip'] is not None: api.nova.addExisitingFloatingIp(request, ins['instance_name'], ins['floating_ip'])
def get(self, request): """Get the values for Cinder specific quotas Example GET: http://localhost/api/cinder/quota-sets/defaults/ """ if api.cinder.is_volume_service_enabled(request): quota_set = api.cinder.default_quota_get(request, request.user.tenant_id) result = [{ 'display_name': quotas.QUOTA_NAMES.get(quota.name, quota.name.replace("_", " ").title()) + '', 'name': quota.name, 'limit': quota.limit } for quota in quota_set] return {'items': result} else: raise rest_utils.AjaxError(501, _('Service Cinder is disabled.'))
def post(self, request): '''Check policy rules. Check the group of policy rules supplied in the POST application/json object. The policy target, if specified will also be passed in to the policy check method as well. The action returns an object with one key: "allowed" and the value is the result of the policy check, True or False. ''' rules = [] try: rules_in = request.DATA['rules'] rules = tuple([tuple(rule) for rule in rules_in]) except Exception: raise rest_utils.AjaxError(400, 'unexpected parameter format') policy_target = request.DATA.get('target') or {} result = policy.check(rules, request, policy_target) return {"allowed": result}
def post(self, request): """Export an EC2 instance to OpenStack :param request: HTTP request """ try: args = (request, request.DATA['name'], request.DATA['source_id'], request.DATA['flavor_id'], request.DATA['key_name'], request.DATA['user_data'], request.DATA['security_groups'], request.DATA.get('leave_original_instance'), request.DATA.get('leave_instance_snapshot')) except KeyError as e: raise rest_utils.AjaxError( 400, 'missing required parameter ' "'%s'" % e.args[0]) kw = {} for name in self._optional_create: if name in request.DATA: kw[name] = request.DATA[name] new = taskflow.run_export_instance_tasks(*args, **kw) return rest_utils.CreatedResponse( '/api/nova/servers/%s' % utils_http.urlquote(new.id), new.to_dict())
def post(self, request): """Import an EC2 instance from OpenStack :param request: HTTP request """ try: taskflow.run_import_instance_tasks( request, source_type=request.DATA.get("source_type", {}).get("type"), source_id=request.DATA.get("source_id"), flavor=request.DATA.get("flavor_id"), key_name=request.DATA.get("key_name"), security_groups=request.DATA.get("security_groups"), availability_zone=request.DATA.get("availability_zone"), instance_count=request.DATA.get("instance_count"), leave_original_instance=request.DATA.get( "leave_original_instance"), leave_instance_snapshot=request.DATA.get( "leave_instance_snapshot")) except KeyError as e: raise rest_utils.AjaxError( 400, "missing required parameter " "'%s'" % e.args[0]) return rest_utils.CreatedResponse("aws/ec2/instances", {})
def post(self, request): """Create an EC2 instance :param request: HTTP request """ try: instance_id = ec2.create_instance( request, name=request.DATA["name"], image_id=request.DATA["source_id"], flavor=request.DATA["flavor_id"], key_name=request.DATA["key_name"], security_groups=request.DATA.get("security_groups"), availability_zone=request.DATA.get("availability_zone", None), instance_count=request.DATA["instance_count"]) except KeyError as e: raise rest_utils.AjaxError( 400, "missing required parameter " "'%s'" % e.args[0]) instance = ec2.get_instance(request, instance_id) return rest_utils.CreatedResponse( "aws/ec2/instances/%s" % utils_http.urlquote(instance_id), instance.to_dict())
def f(self, request): raise utils.AjaxError(404, 'b0rk')