diff --git a/nova/api/__init__.py b/nova/api/__init__.py index 8ec7094d7d41..8a1d9fe320d0 100644 --- a/nova/api/__init__.py +++ b/nova/api/__init__.py @@ -31,12 +31,13 @@ from nova.api import openstack from nova.api.ec2 import metadatarequesthandler -flags.DEFINE_string('osapi_subdomain', 'api', +flags.DEFINE_string('osapi_subdomain', 'api', 'subdomain running the OpenStack API') -flags.DEFINE_string('ec2api_subdomain', 'ec2', +flags.DEFINE_string('ec2api_subdomain', 'ec2', 'subdomain running the EC2 API') -flags.DEFINE_string('FAKE_subdomain', None, - 'set to api or ec2 to fake the subdomain of the host for testing') +flags.DEFINE_string('FAKE_subdomain', None, + 'set to api or ec2 to fake the subdomain of the host ' + 'for testing') FLAGS = flags.FLAGS @@ -44,7 +45,7 @@ class API(wsgi.Router): """Routes top-level requests to the appropriate controller.""" def __init__(self): - osapidomain = {'sub_domain': [FLAGS.osapi_subdomain]} + osapidomain = {'sub_domain': [FLAGS.osapi_subdomain]} ec2domain = {'sub_domain': [FLAGS.ec2api_subdomain]} # If someone wants to pretend they're hitting the OSAPI subdomain # on their local box, they can set FAKE_subdomain to 'api', which @@ -55,7 +56,7 @@ class API(wsgi.Router): ec2domain = {} mapper = routes.Mapper() mapper.sub_domains = True - mapper.connect("/", controller=self.osapi_versions, + mapper.connect("/", controller=self.osapi_versions, conditions=osapidomain) mapper.connect("/v1.0/{path_info:.*}", controller=openstack.API(), conditions=osapidomain) @@ -107,5 +108,3 @@ class API(wsgi.Router): '2009-04-04', ] return ''.join('%s\n' % v for v in versions) - - diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py index 5735eb9567f2..0df4d37105a2 100644 --- a/nova/api/ec2/__init__.py +++ b/nova/api/ec2/__init__.py @@ -62,7 +62,8 @@ class Authenticate(wsgi.Middleware): # Make a copy of args for authentication and signature verification. auth_params = dict(req.params) - auth_params.pop('Signature') # not part of authentication args + # Not part of authentication args + auth_params.pop('Signature') # Authenticate the request. try: @@ -109,9 +110,11 @@ class Router(wsgi.Middleware): 'SignatureVersion', 'Version', 'Timestamp'] args = dict(req.params) try: - action = req.params['Action'] # raise KeyError if omitted + # Raise KeyError if omitted + action = req.params['Action'] for non_arg in non_args: - args.pop(non_arg) # remove, but raise KeyError if omitted + # Remove, but raise KeyError if omitted + args.pop(non_arg) except: raise webob.exc.HTTPBadRequest() @@ -184,7 +187,8 @@ class Authorizer(wsgi.Middleware): context = req.environ['ec2.context'] controller_name = req.environ['ec2.controller'].__class__.__name__ action = req.environ['ec2.action'] - allowed_roles = self.action_roles[controller_name].get(action, ['none']) + allowed_roles = self.action_roles[controller_name].get(action, + ['none']) if self._matches_any_role(context, allowed_roles): return self.application else: @@ -242,4 +246,3 @@ class Executor(wsgi.Application): '%s' '?') % (code, message) return resp - diff --git a/nova/api/ec2/admin.py b/nova/api/ec2/admin.py index 36feae4513ee..1c6ab688d470 100644 --- a/nova/api/ec2/admin.py +++ b/nova/api/ec2/admin.py @@ -73,7 +73,7 @@ class AdminController(object): def describe_users(self, _context, **_kwargs): """Returns all users - should be changed to deal with a list.""" return {'userSet': - [user_dict(u) for u in manager.AuthManager().get_users()] } + [user_dict(u) for u in manager.AuthManager().get_users()]} def register_user(self, _context, name, **_kwargs): """Creates a new user, and returns generated credentials.""" @@ -91,7 +91,7 @@ class AdminController(object): def describe_roles(self, context, project_roles=True, **kwargs): """Returns a list of allowed roles.""" roles = manager.AuthManager().get_roles(project_roles) - return { 'roles': [{'role': r} for r in roles]} + return {'roles': [{'role': r} for r in roles]} def describe_user_roles(self, context, user, project=None, **kwargs): """Returns a list of roles for the given user. @@ -99,7 +99,7 @@ class AdminController(object): Specifying project will return only project specific roles. """ roles = manager.AuthManager().get_user_roles(user, project=project) - return { 'roles': [{'role': r} for r in roles]} + return {'roles': [{'role': r} for r in roles]} def modify_user_role(self, context, user, role, project=None, operation='add', **kwargs): @@ -155,9 +155,10 @@ class AdminController(object): 'members': [{'member': m} for m in project.member_ids]} return result - def modify_project_member(self, context, user, project, operation, **kwargs): + def modify_project_member(self, context, user, project, operation, + **kwargs): """Add or remove a user from a project.""" - if operation =='add': + if operation == 'add': manager.AuthManager().add_to_project(user, project) elif operation == 'remove': manager.AuthManager().remove_from_project(user, project) diff --git a/nova/api/ec2/apirequest.py b/nova/api/ec2/apirequest.py index 3c8651582d25..5758781b69a3 100644 --- a/nova/api/ec2/apirequest.py +++ b/nova/api/ec2/apirequest.py @@ -44,6 +44,7 @@ def _underscore_to_xmlcase(str): res = _underscore_to_camelcase(str) return res[:1].lower() + res[1:] + def _try_convert(value): """Return a non-string if possible""" if value == 'None': @@ -59,12 +60,12 @@ def _try_convert(value): return value if valueneg[0] == '0': if valueneg[1] in 'xX': - return int(value,16) + return int(value, 16) elif valueneg[1] in 'bB': - return int(value,2) + return int(value, 2) else: try: - return int(value,8) + return int(value, 8) except ValueError: pass try: @@ -80,6 +81,7 @@ def _try_convert(value): except ValueError: return value + class APIRequest(object): def __init__(self, controller, action): self.controller = controller diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 6d4f584992b4..784697b01cdd 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -48,6 +48,7 @@ flags.DECLARE('storage_availability_zone', 'nova.volume.manager') InvalidInputException = exception.InvalidInputException + class QuotaError(exception.ApiError): """Quota Exceeeded""" pass @@ -137,8 +138,8 @@ class CloudController(object): for node in nodes: rpc.cast(context, '%s.%s' % (FLAGS.compute_topic, node), - { "method": "refresh_security_group", - "args": {"security_group_id": security_group.id}}) + {"method": "refresh_security_group", + "args": {"security_group_id": security_group.id}}) def get_metadata(self, address): ctxt = context.get_admin_context() @@ -147,48 +148,42 @@ class CloudController(object): return None mpi = self._get_mpi_data(ctxt, instance_ref['project_id']) if instance_ref['key_name']: - keys = { - '0': { - '_name': instance_ref['key_name'], - 'openssh-key': instance_ref['key_data'] - } - } + keys = {'0': {'_name': instance_ref['key_name'], + 'openssh-key': instance_ref['key_data']}} else: keys = '' hostname = instance_ref['hostname'] floating_ip = db.instance_get_floating_address(ctxt, instance_ref['id']) + ec2_id = internal_id_to_ec2_id(instance_ref['internal_id']) data = { 'user-data': base64.b64decode(instance_ref['user_data']), 'meta-data': { 'ami-id': instance_ref['image_id'], 'ami-launch-index': instance_ref['launch_index'], 'ami-manifest-path': 'FIXME', - 'block-device-mapping': { # TODO(vish): replace with real data + 'block-device-mapping': { + # TODO(vish): replace with real data 'ami': 'sda1', 'ephemeral0': 'sda2', 'root': '/dev/sda1', - 'swap': 'sda3' - }, + 'swap': 'sda3'}, 'hostname': hostname, 'instance-action': 'none', - 'instance-id': internal_id_to_ec2_id(instance_ref['internal_id']), + 'instance-id': ec2_id, 'instance-type': instance_ref['instance_type'], 'local-hostname': hostname, 'local-ipv4': address, 'kernel-id': instance_ref['kernel_id'], - 'placement': { - 'availability-zone': 'nova' # TODO(vish): real zone - }, + # TODO(vish): real zone + 'placement': {'availability-zone': 'nova'}, 'public-hostname': hostname, 'public-ipv4': floating_ip or '', 'public-keys': keys, 'ramdisk-id': instance_ref['ramdisk_id'], 'reservation-id': instance_ref['reservation_id'], 'security-groups': '', - 'mpi': mpi - } - } + 'mpi': mpi}} if False: # TODO(vish): store ancestor ids data['ancestor-ami-ids'] = [] if False: # TODO(vish): store product codes @@ -211,7 +206,7 @@ class CloudController(object): 'regionEndpoint': FLAGS.ec2_url}] if region_name: regions = [r for r in regions if r['regionName'] in region_name] - return {'regionInfo': regions } + return {'regionInfo': regions} def describe_snapshots(self, context, @@ -237,7 +232,8 @@ class CloudController(object): for key_pair in key_pairs: # filter out the vpn keys suffix = FLAGS.vpn_key_suffix - if context.user.is_admin() or not key_pair['name'].endswith(suffix): + if context.user.is_admin() or \ + not key_pair['name'].endswith(suffix): result.append({ 'keyName': key_pair['name'], 'keyFingerprint': key_pair['fingerprint'], @@ -271,7 +267,7 @@ class CloudController(object): if not group_name is None: groups = [g for g in groups if g.name in group_name] - return {'securityGroupInfo': groups } + return {'securityGroupInfo': groups} def _format_security_group(self, context, group): g = {} @@ -295,13 +291,10 @@ class CloudController(object): g['ipPermissions'] += [r] return g - - def _authorize_revoke_rule_args_to_dict(self, context, - to_port=None, from_port=None, - ip_protocol=None, cidr_ip=None, - user_id=None, - source_security_group_name=None, - source_security_group_owner_id=None): + def _revoke_rule_args_to_dict(self, context, to_port=None, from_port=None, + ip_protocol=None, cidr_ip=None, user_id=None, + source_security_group_name=None, + source_security_group_owner_id=None): values = {} @@ -322,16 +315,16 @@ class CloudController(object): values['cidr'] = '0.0.0.0/0' if ip_protocol and from_port and to_port: - from_port = int(from_port) - to_port = int(to_port) + from_port = int(from_port) + to_port = int(to_port) ip_protocol = str(ip_protocol) - if ip_protocol.upper() not in ['TCP','UDP','ICMP']: - raise InvalidInputException('%s is not a valid ipProtocol' % - (ip_protocol,)) + if ip_protocol.upper() not in ['TCP', 'UDP', 'ICMP']: + raise InvalidInputException('%s is not a valid ipProtocol' % + (ip_protocol,)) if ((min(from_port, to_port) < -1) or (max(from_port, to_port) > 65535)): - raise InvalidInputException('Invalid port range') + raise InvalidInputException('Invalid port range') values['protocol'] = ip_protocol values['from_port'] = from_port @@ -343,7 +336,6 @@ class CloudController(object): return values - def _security_group_rule_exists(self, security_group, values): """Indicates whether the specified rule values are already defined in the given security group. @@ -362,20 +354,19 @@ class CloudController(object): return True return False - def revoke_security_group_ingress(self, context, group_name, **kwargs): self._ensure_default_security_group(context) security_group = db.security_group_get_by_name(context, context.project_id, group_name) - criteria = self._authorize_revoke_rule_args_to_dict(context, **kwargs) + criteria = self._revoke_rule_args_to_dict(context, **kwargs) if criteria == None: raise exception.ApiError("No rule for the specified parameters.") for rule in security_group.rules: match = True - for (k,v) in criteria.iteritems(): + for (k, v) in criteria.iteritems(): if getattr(rule, k, False) != v: match = False if match: @@ -394,7 +385,7 @@ class CloudController(object): context.project_id, group_name) - values = self._authorize_revoke_rule_args_to_dict(context, **kwargs) + values = self._revoke_rule_args_to_dict(context, **kwargs) values['parent_group_id'] = security_group.id if self._security_group_rule_exists(security_group, values): @@ -407,7 +398,6 @@ class CloudController(object): return True - def _get_source_project_id(self, context, source_security_group_owner_id): if source_security_group_owner_id: # Parse user:project for source group. @@ -425,13 +415,12 @@ class CloudController(object): return source_project_id - def create_security_group(self, context, group_name, group_description): self._ensure_default_security_group(context) if db.security_group_exists(context, context.project_id, group_name): raise exception.ApiError('group %s already exists' % group_name) - group = {'user_id' : context.user.id, + group = {'user_id': context.user.id, 'project_id': context.project_id, 'name': group_name, 'description': group_description} @@ -440,7 +429,6 @@ class CloudController(object): return {'securityGroupSet': [self._format_security_group(context, group_ref)]} - def delete_security_group(self, context, group_name, **kwargs): security_group = db.security_group_get_by_name(context, context.project_id, @@ -448,7 +436,6 @@ class CloudController(object): db.security_group_destroy(context, security_group.id) return True - def get_console_output(self, context, instance_id, **kwargs): # instance_id is passed in as a list of instances ec2_id = instance_id[0] @@ -457,13 +444,13 @@ class CloudController(object): output = rpc.call(context, '%s.%s' % (FLAGS.compute_topic, instance_ref['host']), - {"method" : "get_console_output", - "args" : {"instance_id": instance_ref['id']}}) + {"method": "get_console_output", + "args": {"instance_id": instance_ref['id']}}) now = datetime.datetime.utcnow() - return { "InstanceId" : ec2_id, - "Timestamp" : now, - "output" : base64.b64encode(output) } + return {"InstanceId": ec2_id, + "Timestamp": now, + "output": base64.b64encode(output)} def describe_volumes(self, context, **kwargs): if context.user.is_admin(): @@ -530,7 +517,6 @@ class CloudController(object): return {'volumeSet': [self._format_volume(context, volume_ref)]} - def attach_volume(self, context, volume_id, instance_id, device, **kwargs): volume_ref = db.volume_get_by_ec2_id(context, volume_id) # TODO(vish): abstract status checking? @@ -633,8 +619,7 @@ class CloudController(object): i['imageId'] = instance['image_id'] i['instanceState'] = { 'code': instance['state'], - 'name': instance['state_description'] - } + 'name': instance['state_description']} fixed_addr = None floating_addr = None if instance['fixed_ip']: @@ -656,7 +641,7 @@ class CloudController(object): i['amiLaunchIndex'] = instance['launch_index'] i['displayName'] = instance['display_name'] i['displayDescription'] = instance['display_description'] - if not reservations.has_key(instance['reservation_id']): + if instance['reservation_id'] not in reservations: r = {} r['reservationId'] = instance['reservation_id'] r['ownerId'] = instance['project_id'] @@ -757,10 +742,10 @@ class CloudController(object): context.project_id, 'default') except exception.NotFound: - values = { 'name' : 'default', - 'description' : 'default', - 'user_id' : context.user.id, - 'project_id' : context.project_id } + values = {'name': 'default', + 'description': 'default', + 'user_id': context.user.id, + 'project_id': context.project_id} group = db.security_group_create(context, values) def run_instances(self, context, **kwargs): @@ -804,7 +789,7 @@ class CloudController(object): logging.debug("Going to run %s instances...", num_instances) launch_time = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()) key_data = None - if kwargs.has_key('key_name'): + if 'key_name' in kwargs: key_pair_ref = db.key_pair_get(context, context.user.id, kwargs['key_name']) @@ -883,7 +868,6 @@ class CloudController(object): (context.project.name, context.user.name, inst_id)) return self._format_run_instances(context, reservation_id) - def terminate_instances(self, context, instance_id, **kwargs): """Terminate each instance in instance_id, which is a list of ec2 ids. @@ -991,7 +975,7 @@ class CloudController(object): def register_image(self, context, image_location=None, **kwargs): # FIXME: should the objectstore be doing these authorization checks? - if image_location is None and kwargs.has_key('name'): + if image_location is None and 'name' in kwargs: image_location = kwargs['name'] image_id = images.register(context, image_location) logging.debug("Registered %s as %s" % (image_location, image_id)) @@ -1009,7 +993,8 @@ class CloudController(object): result['launchPermission'].append({'group': 'all'}) return result - def modify_image_attribute(self, context, image_id, attribute, operation_type, **kwargs): + def modify_image_attribute(self, context, image_id, attribute, + operation_type, **kwargs): # TODO(devcamcar): Support users and groups other than 'all'. if attribute != 'launchPermission': raise exception.ApiError('attribute not supported: %s' % attribute) diff --git a/nova/api/ec2/images.py b/nova/api/ec2/images.py index f0a43dad68a6..60f9008e9495 100644 --- a/nova/api/ec2/images.py +++ b/nova/api/ec2/images.py @@ -43,6 +43,7 @@ def modify(context, image_id, operation): return True + def update(context, image_id, attributes): """update an image's attributes / info.json""" attributes.update({"image_id": image_id}) @@ -52,6 +53,7 @@ def update(context, image_id, attributes): query_args=qs(attributes)) return True + def register(context, image_location): """ rpc call to register a new image based from a manifest """ @@ -64,13 +66,14 @@ def register(context, image_location): return image_id + def list(context, filter_list=[]): """ return a list of all images that a user can see optionally filtered by a list of image_id """ if FLAGS.connection_type == 'fake': - return [{ 'imageId' : 'bar'}] + return [{'imageId': 'bar'}] # FIXME: send along the list of only_images to check for response = conn(context).make_request( @@ -82,6 +85,7 @@ def list(context, filter_list=[]): return [i for i in result if i['imageId'] in filter_list] return result + def get(context, image_id): """return a image object if the context has permissions""" result = list(context, [image_id]) diff --git a/nova/api/ec2/metadatarequesthandler.py b/nova/api/ec2/metadatarequesthandler.py index 08a8040ca66c..2f4f414ccb5c 100644 --- a/nova/api/ec2/metadatarequesthandler.py +++ b/nova/api/ec2/metadatarequesthandler.py @@ -27,7 +27,6 @@ from nova.api.ec2 import cloud class MetadataRequestHandler(object): - """Serve metadata from the EC2 API.""" def print_data(self, data): @@ -43,7 +42,8 @@ class MetadataRequestHandler(object): else: output += '/' output += '\n' - return output[:-1] # cut off last \n + # Cut off last \n + return output[:-1] elif isinstance(data, list): return '\n'.join(data) else: @@ -65,7 +65,8 @@ class MetadataRequestHandler(object): cc = cloud.CloudController() meta_data = cc.get_metadata(req.remote_addr) if meta_data is None: - logging.error('Failed to get metadata for ip: %s' % req.remote_addr) + logging.error('Failed to get metadata for ip: %s' % + req.remote_addr) raise webob.exc.HTTPNotFound() data = self.lookup(req.path_info, meta_data) if data is None: diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 5706dbc09806..bb86f08dd993 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -43,9 +43,10 @@ from nova.auth import manager FLAGS = flags.FLAGS flags.DEFINE_string('nova_api_auth', - 'nova.api.openstack.auth.BasicApiAuthManager', + 'nova.api.openstack.auth.BasicApiAuthManager', 'The auth mechanism to use for the OpenStack API implemenation') + class API(wsgi.Middleware): """WSGI entry point for all OpenStack API requests.""" @@ -53,6 +54,7 @@ class API(wsgi.Middleware): app = AuthMiddleware(RateLimitingMiddleware(APIRouter())) super(API, self).__init__(app) + class AuthMiddleware(wsgi.Middleware): """Authorize the openstack API request or return an HTTP Forbidden.""" @@ -62,7 +64,7 @@ class AuthMiddleware(wsgi.Middleware): @webob.dec.wsgify def __call__(self, req): - if not req.headers.has_key("X-Auth-Token"): + if 'X-Auth-Token' not in req.headers: return self.auth_driver.authenticate(req) user = self.auth_driver.authorize_token(req.headers["X-Auth-Token"]) @@ -70,11 +72,12 @@ class AuthMiddleware(wsgi.Middleware): if not user: return faults.Fault(webob.exc.HTTPUnauthorized()) - if not req.environ.has_key('nova.context'): + if 'nova.context' not in req.environ: req.environ['nova.context'] = {} req.environ['nova.context']['user'] = user return self.application + class RateLimitingMiddleware(wsgi.Middleware): """Rate limit incoming requests according to the OpenStack rate limits.""" @@ -87,7 +90,7 @@ class RateLimitingMiddleware(wsgi.Middleware): """ super(RateLimitingMiddleware, self).__init__(application) if not service_host: - #TODO(gundlach): These limits were based on limitations of Cloud + #TODO(gundlach): These limits were based on limitations of Cloud #Servers. We should revisit them in Nova. self.limiter = ratelimiting.Limiter(limits={ 'DELETE': (100, ratelimiting.PER_MINUTE), @@ -102,13 +105,14 @@ class RateLimitingMiddleware(wsgi.Middleware): @webob.dec.wsgify def __call__(self, req): """Rate limit the request. - - If the request should be rate limited, return a 413 status with a + + If the request should be rate limited, return a 413 status with a Retry-After header giving the time when the request would succeed. """ user_id = req.environ['nova.context']['user']['id'] action_name = self.get_action_name(req) - if not action_name: # not rate limited + if not action_name: + # Not rate limited return self.application delay = self.get_delay(action_name, user_id) if delay: @@ -152,13 +156,13 @@ class APIRouter(wsgi.Router): def __init__(self): mapper = routes.Mapper() mapper.resource("server", "servers", controller=servers.Controller(), - collection={ 'detail': 'GET'}, - member={'action':'POST'}) + collection={'detail': 'GET'}, + member={'action': 'POST'}) - mapper.resource("backup_schedule", "backup_schedules", + mapper.resource("backup_schedule", "backup_schedules", controller=backup_schedules.Controller(), - parent_resource=dict(member_name='server', - collection_name = 'servers')) + parent_resource=dict(member_name='server', + collection_name='servers')) mapper.resource("image", "images", controller=images.Controller(), collection={'detail': 'GET'}) @@ -172,7 +176,7 @@ class APIRouter(wsgi.Router): def limited(items, req): """Return a slice of items according to requested offset and limit. - + items - a sliceable req - wobob.Request possibly containing offset and limit GET variables. offset is where to start in the list, and limit is the maximum number @@ -187,4 +191,3 @@ def limited(items, req): limit = min(1000, limit) range_end = offset + limit return items[offset:range_end] - diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py index 7aba55728ff7..ff428ff701a9 100644 --- a/nova/api/openstack/auth.py +++ b/nova/api/openstack/auth.py @@ -15,9 +15,11 @@ from nova.api.openstack import faults FLAGS = flags.FLAGS + class Context(object): pass + class BasicApiAuthManager(object): """ Implements a somewhat rudimentary version of OpenStack Auth""" @@ -61,7 +63,7 @@ class BasicApiAuthManager(object): def authorize_token(self, token_hash): """ retrieves user information from the datastore given a token - + If the token has expired, returns None If the token is not found, returns None Otherwise returns dict(id=(the authorized user's id)) @@ -69,7 +71,7 @@ class BasicApiAuthManager(object): This method will also remove the token if the timestamp is older than 2 days ago. """ - token = self.db.auth_get_token(self.context, token_hash) + token = self.db.auth_get_token(self.context, token_hash) if token: delta = datetime.datetime.now() - token.created_at if delta.days >= 2: @@ -94,8 +96,7 @@ class BasicApiAuthManager(object): token_dict['user_id'] = user.id token = self.db.auth_create_token(self.context, token_dict) return token, user - return None, None + return None, None def _get_server_mgmt_url(self): return 'https://%s/v1.0/' % self.host - diff --git a/nova/api/openstack/backup_schedules.py b/nova/api/openstack/backup_schedules.py index db240c65ac84..3ed691d7b023 100644 --- a/nova/api/openstack/backup_schedules.py +++ b/nova/api/openstack/backup_schedules.py @@ -22,6 +22,7 @@ from nova import wsgi from nova.api.openstack import faults import nova.image.service + class Controller(wsgi.Controller): def __init__(self): pass diff --git a/nova/api/openstack/faults.py b/nova/api/openstack/faults.py index 32e5c866f120..e69e514390ae 100644 --- a/nova/api/openstack/faults.py +++ b/nova/api/openstack/faults.py @@ -55,7 +55,7 @@ class Fault(webob.exc.HTTPException): if code == 413: retry = self.wrapped_exc.headers['Retry-After'] fault_data[fault_name]['retryAfter'] = retry - # 'code' is an attribute on the fault tag itself + # 'code' is an attribute on the fault tag itself metadata = {'application/xml': {'attributes': {fault_name: 'code'}}} serializer = wsgi.Serializer(req.environ, metadata) self.wrapped_exc.body = serializer.to_content_type(fault_data) diff --git a/nova/api/openstack/flavors.py b/nova/api/openstack/flavors.py index 793984a5dff3..f23f74fd11ce 100644 --- a/nova/api/openstack/flavors.py +++ b/nova/api/openstack/flavors.py @@ -22,16 +22,14 @@ from nova.compute import instance_types from nova import wsgi import nova.api.openstack + class Controller(wsgi.Controller): """Flavor controller for the OpenStack API.""" _serialization_metadata = { 'application/xml': { "attributes": { - "flavor": [ "id", "name", "ram", "disk" ] - } - } - } + "flavor": ["id", "name", "ram", "disk"]}}} def index(self, req): """Return all flavors in brief.""" diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py index 5ccf659f72c8..5bc915e633fe 100644 --- a/nova/api/openstack/images.py +++ b/nova/api/openstack/images.py @@ -27,16 +27,14 @@ from nova.api.openstack import faults FLAGS = flags.FLAGS + class Controller(wsgi.Controller): _serialization_metadata = { 'application/xml': { "attributes": { - "image": [ "id", "name", "updated", "created", "status", - "serverId", "progress" ] - } - } - } + "image": ["id", "name", "updated", "created", "status", + "serverId", "progress"]}}} def __init__(self): self._service = utils.import_object(FLAGS.image_service) @@ -72,6 +70,6 @@ class Controller(wsgi.Controller): raise faults.Fault(exc.HTTPNotFound()) def update(self, req, id): - # Users may not modify public images, and that's all that + # Users may not modify public images, and that's all that # we support for now. raise faults.Fault(exc.HTTPNotFound()) diff --git a/nova/api/openstack/ratelimiting/__init__.py b/nova/api/openstack/ratelimiting/__init__.py index f843bac0f29b..9e028ecf528f 100644 --- a/nova/api/openstack/ratelimiting/__init__.py +++ b/nova/api/openstack/ratelimiting/__init__.py @@ -13,6 +13,7 @@ PER_MINUTE = 60 PER_HOUR = 60 * 60 PER_DAY = 60 * 60 * 24 + class Limiter(object): """Class providing rate limiting of arbitrary actions.""" @@ -101,7 +102,8 @@ class WSGIApp(object): return webob.exc.HTTPForbidden( headers={'X-Wait-Seconds': "%.2f" % delay}) else: - return '' # 200 OK + # 200 OK + return '' class WSGIAppProxy(object): @@ -109,7 +111,7 @@ class WSGIAppProxy(object): """Limiter lookalike that proxies to a ratelimiting.WSGIApp.""" def __init__(self, service_host): - """Creates a proxy pointing to a ratelimiting.WSGIApp at the given + """Creates a proxy pointing to a ratelimiting.WSGIApp at the given host.""" self.service_host = service_host @@ -118,5 +120,6 @@ class WSGIAppProxy(object): conn.request('POST', '/limiter/%s/%s' % (username, action)) resp = conn.getresponse() if resp.status == 200: - return None # no delay + # No delay + return None return float(resp.getheader('X-Wait-Seconds')) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index a73591ccc886..ef773c3be3fc 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -34,30 +34,32 @@ import nova.image.service FLAGS = flags.FLAGS + def _filter_params(inst_dict): """ Extracts all updatable parameters for a server update request """ keys = dict(name='name', admin_pass='adminPass') new_attrs = {} for k, v in keys.items(): - if inst_dict.has_key(v): + if v in inst_dict: new_attrs[k] = inst_dict[v] return new_attrs + def _entity_list(entities): """ Coerces a list of servers into proper dictionary format """ return dict(servers=entities) + def _entity_detail(inst): """ Maps everything to Rackspace-like attributes for return""" power_mapping = { - power_state.NOSTATE: 'build', - power_state.RUNNING: 'active', - power_state.BLOCKED: 'active', - power_state.PAUSED: 'suspended', + power_state.NOSTATE: 'build', + power_state.RUNNING: 'active', + power_state.BLOCKED: 'active', + power_state.PAUSED: 'suspended', power_state.SHUTDOWN: 'active', - power_state.SHUTOFF: 'active', - power_state.CRASHED: 'error' - } + power_state.SHUTOFF: 'active', + power_state.CRASHED: 'error'} inst_dict = {} mapped_keys = dict(status='state', imageId='image_id', @@ -73,21 +75,20 @@ def _entity_detail(inst): return dict(server=inst_dict) + def _entity_inst(inst): """ Filters all model attributes save for id and name """ return dict(server=dict(id=inst['id'], name=inst['server_name'])) + class Controller(wsgi.Controller): """ The Server API controller for the OpenStack API """ _serialization_metadata = { 'application/xml': { "attributes": { - "server": [ "id", "imageId", "name", "flavorId", "hostId", - "status", "progress", "progress" ] - } - } - } + "server": ["id", "imageId", "name", "flavorId", "hostId", + "status", "progress", "progress"]}}} def __init__(self, db_driver=None): if not db_driver: @@ -209,7 +210,7 @@ class Controller(wsgi.Controller): image = img_service.show(image_id) if not image: - raise Exception, "Image not found" + raise Exception("Image not found") inst['server_name'] = env['server']['name'] inst['image_id'] = image_id diff --git a/nova/api/openstack/sharedipgroups.py b/nova/api/openstack/sharedipgroups.py index 4d2d0ede1109..e805ca9f7bf9 100644 --- a/nova/api/openstack/sharedipgroups.py +++ b/nova/api/openstack/sharedipgroups.py @@ -17,4 +17,6 @@ from nova import wsgi -class Controller(wsgi.Controller): pass + +class Controller(wsgi.Controller): + pass