diff options
| author | jaypipes@gmail.com <> | 2010-10-15 16:24:19 -0400 |
|---|---|---|
| committer | jaypipes@gmail.com <> | 2010-10-15 16:24:19 -0400 |
| commit | 3fdced0a19315732fec0ead200604e396f06823c (patch) | |
| tree | cf4675fdf71e8c126888432007e15d1bbf9c2360 /nova/api | |
| parent | ff60af51cc2990c7b60ca97cc899f0719560bc6f (diff) | |
| parent | b70742cd442e8477d15c82a825641d934529bedf (diff) | |
Merge trunk
Diffstat (limited to 'nova/api')
| -rw-r--r-- | nova/api/cloud.py | 14 | ||||
| -rw-r--r-- | nova/api/context.py | 46 | ||||
| -rw-r--r-- | nova/api/ec2/__init__.py | 7 | ||||
| -rw-r--r-- | nova/api/ec2/cloud.py | 202 | ||||
| -rw-r--r-- | nova/api/openstack/auth.py | 42 | ||||
| -rw-r--r-- | nova/api/openstack/context.py | 33 | ||||
| -rw-r--r-- | nova/api/openstack/servers.py | 63 |
7 files changed, 172 insertions, 235 deletions
diff --git a/nova/api/cloud.py b/nova/api/cloud.py index 57e94a17a..aa84075dc 100644 --- a/nova/api/cloud.py +++ b/nova/api/cloud.py @@ -29,14 +29,10 @@ FLAGS = flags.FLAGS def reboot(instance_id, context=None): - """Reboot the given instance. - - #TODO(gundlach) not actually sure what context is used for by ec2 here - -- I think we can just remove it and use None all the time. - """ - instance_ref = db.instance_get_by_internal_id(None, instance_id) + """Reboot the given instance.""" + instance_ref = db.instance_get_by_internal_id(context, instance_id) host = instance_ref['host'] - rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host), + rpc.cast(context, + db.queue_get_for(context, FLAGS.compute_topic, host), {"method": "reboot_instance", - "args": {"context": None, - "instance_id": instance_ref['id']}}) + "args": {"instance_id": instance_ref['id']}}) diff --git a/nova/api/context.py b/nova/api/context.py deleted file mode 100644 index b66cfe468..000000000 --- a/nova/api/context.py +++ /dev/null @@ -1,46 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -APIRequestContext -""" - -import random - - -class APIRequestContext(object): - def __init__(self, user, project): - self.user = user - self.project = project - self.request_id = ''.join( - [random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-') - for x in xrange(20)] - ) - if user: - self.is_admin = user.is_admin() - else: - self.is_admin = False - self.read_deleted = False - - -def get_admin_context(user=None, read_deleted=False): - context_ref = APIRequestContext(user=user, project=None) - context_ref.is_admin = True - context_ref.read_deleted = read_deleted - return context_ref - diff --git a/nova/api/ec2/__init__.py b/nova/api/ec2/__init__.py index 6e771f064..5735eb956 100644 --- a/nova/api/ec2/__init__.py +++ b/nova/api/ec2/__init__.py @@ -25,9 +25,9 @@ import webob.dec import webob.exc from nova import exception +from nova import context from nova import flags from nova import wsgi -from nova.api import context from nova.api.ec2 import apirequest from nova.api.ec2 import admin from nova.api.ec2 import cloud @@ -78,7 +78,10 @@ class Authenticate(wsgi.Middleware): raise webob.exc.HTTPForbidden() # Authenticated! - req.environ['ec2.context'] = context.APIRequestContext(user, project) + ctxt = context.RequestContext(user=user, + project=project, + remote_address=req.remote_addr) + req.environ['ec2.context'] = ctxt return self.application diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index a7693cadd..6d4f58499 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -28,6 +28,7 @@ import logging import os import time +from nova import context import IPy from nova import crypto @@ -117,9 +118,9 @@ class CloudController(object): utils.runthis("Generating root CA: %s", "sh genrootca.sh") os.chdir(start) - def _get_mpi_data(self, project_id): + def _get_mpi_data(self, context, project_id): result = {} - for instance in db.instance_get_all_by_project(None, project_id): + for instance in db.instance_get_all_by_project(context, project_id): if instance['fixed_ip']: line = '%s slots=%d' % (instance['fixed_ip']['address'], INSTANCE_TYPES[instance['instance_type']]['vcpus']) @@ -130,20 +131,21 @@ class CloudController(object): result[key] = [line] return result - def _trigger_refresh_security_group(self, security_group): + def _trigger_refresh_security_group(self, context, security_group): nodes = set([instance['host'] for instance in security_group.instances if instance['host'] is not None]) for node in nodes: - rpc.call('%s.%s' % (FLAGS.compute_topic, node), + rpc.cast(context, + '%s.%s' % (FLAGS.compute_topic, node), { "method": "refresh_security_group", - "args": { "context": None, - "security_group_id": security_group.id}}) + "args": {"security_group_id": security_group.id}}) def get_metadata(self, address): - instance_ref = db.fixed_ip_get_instance(None, address) + ctxt = context.get_admin_context() + instance_ref = db.fixed_ip_get_instance(ctxt, address) if instance_ref is None: return None - mpi = self._get_mpi_data(instance_ref['project_id']) + mpi = self._get_mpi_data(ctxt, instance_ref['project_id']) if instance_ref['key_name']: keys = { '0': { @@ -154,7 +156,7 @@ class CloudController(object): else: keys = '' hostname = instance_ref['hostname'] - floating_ip = db.instance_get_floating_address(None, + floating_ip = db.instance_get_floating_address(ctxt, instance_ref['id']) data = { 'user-data': base64.b64decode(instance_ref['user_data']), @@ -162,7 +164,7 @@ class CloudController(object): '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', @@ -244,7 +246,7 @@ class CloudController(object): return {'keypairsSet': result} def create_key_pair(self, context, key_name, **kwargs): - data = _gen_key(None, context.user.id, key_name) + data = _gen_key(context, context.user.id, key_name) return {'keyName': key_name, 'keyFingerprint': data['fingerprint'], 'keyMaterial': data['private_key']} @@ -264,7 +266,7 @@ class CloudController(object): groups = db.security_group_get_all(context) else: groups = db.security_group_get_by_project(context, - context.project.id) + context.project_id) groups = [self._format_security_group(context, g) for g in groups] if not group_name is None: groups = [g for g in groups if g.name in group_name] @@ -308,7 +310,7 @@ class CloudController(object): source_security_group_owner_id) source_security_group = \ - db.security_group_get_by_name(context, + db.security_group_get_by_name(context.elevated(), source_project_id, source_security_group_name) values['group_id'] = source_security_group['id'] @@ -364,7 +366,7 @@ class CloudController(object): 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, + context.project_id, group_name) criteria = self._authorize_revoke_rule_args_to_dict(context, **kwargs) @@ -378,7 +380,7 @@ class CloudController(object): match = False if match: db.security_group_rule_destroy(context, rule['id']) - self._trigger_refresh_security_group(security_group) + self._trigger_refresh_security_group(context, security_group) return True raise exception.ApiError("No rule for the specified parameters.") @@ -389,7 +391,7 @@ class CloudController(object): def authorize_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, + context.project_id, group_name) values = self._authorize_revoke_rule_args_to_dict(context, **kwargs) @@ -401,7 +403,7 @@ class CloudController(object): security_group_rule = db.security_group_rule_create(context, values) - self._trigger_refresh_security_group(security_group) + self._trigger_refresh_security_group(context, security_group) return True @@ -419,18 +421,18 @@ class CloudController(object): else: source_project_id = source_parts[0] else: - source_project_id = context.project.id + source_project_id = context.project_id 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): + 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, - 'project_id': context.project.id, + 'project_id': context.project_id, 'name': group_name, 'description': group_description} group_ref = db.security_group_create(context, group) @@ -441,7 +443,7 @@ class CloudController(object): def delete_security_group(self, context, group_name, **kwargs): security_group = db.security_group_get_by_name(context, - context.project.id, + context.project_id, group_name) db.security_group_destroy(context, security_group.id) return True @@ -452,11 +454,11 @@ class CloudController(object): ec2_id = instance_id[0] internal_id = ec2_id_to_internal_id(ec2_id) instance_ref = db.instance_get_by_internal_id(context, internal_id) - output = rpc.call('%s.%s' % (FLAGS.compute_topic, - instance_ref['host']), - { "method" : "get_console_output", - "args" : { "context": None, - "instance_id": instance_ref['id']}}) + output = rpc.call(context, + '%s.%s' % (FLAGS.compute_topic, + instance_ref['host']), + {"method" : "get_console_output", + "args" : {"instance_id": instance_ref['id']}}) now = datetime.datetime.utcnow() return { "InstanceId" : ec2_id, @@ -467,7 +469,7 @@ class CloudController(object): if context.user.is_admin(): volumes = db.volume_get_all(context) else: - volumes = db.volume_get_all_by_project(context, context.project.id) + volumes = db.volume_get_all_by_project(context, context.project_id) volumes = [self._format_volume(context, v) for v in volumes] @@ -505,14 +507,14 @@ class CloudController(object): # check quota if quota.allowed_volumes(context, 1, size) < 1: logging.warn("Quota exceeeded for %s, tried to create %sG volume", - context.project.id, size) + context.project_id, size) raise QuotaError("Volume quota exceeded. You cannot " "create a volume of size %s" % size) vol = {} vol['size'] = size vol['user_id'] = context.user.id - vol['project_id'] = context.project.id + vol['project_id'] = context.project_id vol['availability_zone'] = FLAGS.storage_availability_zone vol['status'] = "creating" vol['attach_status'] = "detached" @@ -520,10 +522,10 @@ class CloudController(object): vol['display_description'] = kwargs.get('display_description') volume_ref = db.volume_create(context, vol) - rpc.cast(FLAGS.scheduler_topic, + rpc.cast(context, + FLAGS.scheduler_topic, {"method": "create_volume", - "args": {"context": None, - "topic": FLAGS.volume_topic, + "args": {"topic": FLAGS.volume_topic, "volume_id": volume_ref['id']}}) return {'volumeSet': [self._format_volume(context, volume_ref)]} @@ -539,12 +541,12 @@ class CloudController(object): internal_id = ec2_id_to_internal_id(instance_id) instance_ref = db.instance_get_by_internal_id(context, internal_id) host = instance_ref['host'] - rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host), - {"method": "attach_volume", - "args": {"context": None, - "volume_id": volume_ref['id'], - "instance_id": instance_ref['id'], - "mountpoint": device}}) + rpc.cast(context, + db.queue_get_for(context, FLAGS.compute_topic, host), + {"method": "attach_volume", + "args": {"volume_id": volume_ref['id'], + "instance_id": instance_ref['id'], + "mountpoint": device}}) return {'attachTime': volume_ref['attach_time'], 'device': volume_ref['mountpoint'], 'instanceId': instance_ref['id'], @@ -554,7 +556,8 @@ class CloudController(object): def detach_volume(self, context, volume_id, **kwargs): volume_ref = db.volume_get_by_ec2_id(context, volume_id) - instance_ref = db.volume_get_instance(context, volume_ref['id']) + instance_ref = db.volume_get_instance(context.elevated(), + volume_ref['id']) if not instance_ref: raise exception.ApiError("Volume isn't attached to anything!") # TODO(vish): abstract status checking? @@ -562,11 +565,11 @@ class CloudController(object): raise exception.ApiError("Volume is already detached") try: host = instance_ref['host'] - rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host), - {"method": "detach_volume", - "args": {"context": None, - "instance_id": instance_ref['id'], - "volume_id": volume_ref['id']}}) + rpc.cast(context, + db.queue_get_for(context, FLAGS.compute_topic, host), + {"method": "detach_volume", + "args": {"instance_id": instance_ref['id'], + "volume_id": volume_ref['id']}}) except exception.NotFound: # If the instance doesn't exist anymore, # then we need to call detach blind @@ -601,7 +604,7 @@ class CloudController(object): return self._format_describe_instances(context) def _format_describe_instances(self, context): - return { 'reservationSet': self._format_instances(context) } + return {'reservationSet': self._format_instances(context)} def _format_run_instances(self, context, reservation_id): i = self._format_instances(context, reservation_id) @@ -618,7 +621,7 @@ class CloudController(object): instances = db.instance_get_all(context) else: instances = db.instance_get_all_by_project(context, - context.project.id) + context.project_id) for instance in instances: if not context.user.is_admin(): if instance['image_id'] == FLAGS.vpn_image_id: @@ -673,7 +676,7 @@ class CloudController(object): iterator = db.floating_ip_get_all(context) else: iterator = db.floating_ip_get_all_by_project(context, - context.project.id) + context.project_id) for floating_ip_ref in iterator: address = floating_ip_ref['address'] instance_id = None @@ -694,24 +697,24 @@ class CloudController(object): # check quota if quota.allowed_floating_ips(context, 1) < 1: logging.warn("Quota exceeeded for %s, tried to allocate address", - context.project.id) + context.project_id) raise QuotaError("Address quota exceeded. You cannot " "allocate any more addresses") network_topic = self._get_network_topic(context) - public_ip = rpc.call(network_topic, - {"method": "allocate_floating_ip", - "args": {"context": None, - "project_id": context.project.id}}) + public_ip = rpc.call(context, + network_topic, + {"method": "allocate_floating_ip", + "args": {"project_id": context.project_id}}) return {'addressSet': [{'publicIp': public_ip}]} def release_address(self, context, public_ip, **kwargs): # NOTE(vish): Should we make sure this works? floating_ip_ref = db.floating_ip_get_by_address(context, public_ip) network_topic = self._get_network_topic(context) - rpc.cast(network_topic, + rpc.cast(context, + network_topic, {"method": "deallocate_floating_ip", - "args": {"context": None, - "floating_address": floating_ip_ref['address']}}) + "args": {"floating_address": floating_ip_ref['address']}}) return {'releaseResponse': ["Address released."]} def associate_address(self, context, ec2_id, public_ip, **kwargs): @@ -721,20 +724,20 @@ class CloudController(object): instance_ref['id']) floating_ip_ref = db.floating_ip_get_by_address(context, public_ip) network_topic = self._get_network_topic(context) - rpc.cast(network_topic, + rpc.cast(context, + network_topic, {"method": "associate_floating_ip", - "args": {"context": None, - "floating_address": floating_ip_ref['address'], + "args": {"floating_address": floating_ip_ref['address'], "fixed_address": fixed_address}}) return {'associateResponse': ["Address associated."]} def disassociate_address(self, context, public_ip, **kwargs): floating_ip_ref = db.floating_ip_get_by_address(context, public_ip) network_topic = self._get_network_topic(context) - rpc.cast(network_topic, + rpc.cast(context, + network_topic, {"method": "disassociate_floating_ip", - "args": {"context": None, - "floating_address": floating_ip_ref['address']}}) + "args": {"floating_address": floating_ip_ref['address']}}) return {'disassociateResponse': ["Address disassociated."]} def _get_network_topic(self, context): @@ -742,22 +745,22 @@ class CloudController(object): network_ref = self.network_manager.get_network(context) host = network_ref['host'] if not host: - host = rpc.call(FLAGS.network_topic, - {"method": "set_network_host", - "args": {"context": None, - "network_id": network_ref['id']}}) + host = rpc.call(context, + FLAGS.network_topic, + {"method": "set_network_host", + "args": {"network_id": network_ref['id']}}) return db.queue_get_for(context, FLAGS.network_topic, host) def _ensure_default_security_group(self, context): try: db.security_group_get_by_name(context, - context.project.id, + context.project_id, 'default') except exception.NotFound: values = { 'name' : 'default', 'description' : 'default', 'user_id' : context.user.id, - 'project_id' : context.project.id } + 'project_id' : context.project_id } group = db.security_group_create(context, values) def run_instances(self, context, **kwargs): @@ -773,7 +776,7 @@ class CloudController(object): instance_type) if num_instances < min_instances: logging.warn("Quota exceeeded for %s, tried to run %s instances", - context.project.id, min_instances) + context.project_id, min_instances) raise QuotaError("Instance quota exceeded. You can only " "run %s more instances of this type." % num_instances, "InstanceLimitExceeded") @@ -815,7 +818,7 @@ class CloudController(object): self._ensure_default_security_group(context) for security_group_name in security_group_arg: group = db.security_group_get_by_name(context, - context.project.id, + context.project_id, security_group_name) security_groups.append(group['id']) @@ -829,7 +832,7 @@ class CloudController(object): base_options['key_data'] = key_data base_options['key_name'] = kwargs.get('key_name', None) base_options['user_id'] = context.user.id - base_options['project_id'] = context.project.id + base_options['project_id'] = context.project_id base_options['user_data'] = kwargs.get('user_data', '') base_options['display_name'] = kwargs.get('display_name') @@ -840,13 +843,15 @@ class CloudController(object): base_options['memory_mb'] = type_data['memory_mb'] base_options['vcpus'] = type_data['vcpus'] base_options['local_gb'] = type_data['local_gb'] + elevated = context.elevated() for num in range(num_instances): instance_ref = db.instance_create(context, base_options) inst_id = instance_ref['id'] for security_group_id in security_groups: - db.instance_add_security_group(context, inst_id, + db.instance_add_security_group(elevated, + inst_id, security_group_id) inst = {} @@ -864,15 +869,15 @@ class CloudController(object): inst_id, vpn) network_topic = self._get_network_topic(context) - rpc.call(network_topic, + rpc.cast(elevated, + network_topic, {"method": "setup_fixed_ip", - "args": {"context": None, - "address": address}}) + "args": {"address": address}}) - rpc.cast(FLAGS.scheduler_topic, + rpc.cast(context, + FLAGS.scheduler_topic, {"method": "run_instance", - "args": {"context": None, - "topic": FLAGS.compute_topic, + "args": {"topic": FLAGS.compute_topic, "instance_id": inst_id}}) logging.debug("Casting to scheduler for %s/%s's instance %s" % (context.project.name, context.user.name, inst_id)) @@ -890,17 +895,23 @@ class CloudController(object): internal_id = ec2_id_to_internal_id(id_str) logging.debug("Going to try and terminate %s" % id_str) try: - instance_ref = db.instance_get_by_internal_id(context, + instance_ref = db.instance_get_by_internal_id(context, internal_id) except exception.NotFound: - logging.warning("Instance %s was not found during terminate" - % id_str) + logging.warning("Instance %s was not found during terminate", + id_str) continue + if (instance_ref['state_description'] == 'terminating'): + logging.warning("Instance %s is already being terminated", + id_str) + continue now = datetime.datetime.utcnow() db.instance_update(context, instance_ref['id'], - {'terminated_at': now}) + {'state_description': 'terminating', + 'state': 0, + 'terminated_at': now}) # FIXME(ja): where should network deallocate occur? address = db.instance_get_floating_address(context, instance_ref['id']) @@ -910,10 +921,10 @@ class CloudController(object): # disassociated. We may need to worry about # checking this later. Perhaps in the scheduler? network_topic = self._get_network_topic(context) - rpc.cast(network_topic, + rpc.cast(context, + network_topic, {"method": "disassociate_floating_ip", - "args": {"context": None, - "floating_address": address}}) + "args": {"floating_address": address}}) address = db.instance_get_fixed_address(context, instance_ref['id']) @@ -922,14 +933,15 @@ class CloudController(object): # NOTE(vish): Currently, nothing needs to be done on the # network node until release. If this changes, # we will need to cast here. - self.network_manager.deallocate_fixed_ip(context, address) + self.network_manager.deallocate_fixed_ip(context.elevated(), + address) host = instance_ref['host'] if host: - rpc.cast(db.queue_get_for(context, FLAGS.compute_topic, host), + rpc.cast(context, + db.queue_get_for(context, FLAGS.compute_topic, host), {"method": "terminate_instance", - "args": {"context": None, - "instance_id": instance_ref['id']}}) + "args": {"instance_id": instance_ref['id']}}) else: db.instance_destroy(context, instance_ref['id']) return True @@ -947,10 +959,9 @@ class CloudController(object): if field in kwargs: changes[field] = kwargs[field] if changes: - db_context = {} internal_id = ec2_id_to_internal_id(ec2_id) - inst = db.instance_get_by_internal_id(db_context, internal_id) - db.instance_update(db_context, inst['id'], kwargs) + inst = db.instance_get_by_internal_id(context, internal_id) + db.instance_update(context, inst['id'], kwargs) return True def delete_volume(self, context, volume_id, **kwargs): @@ -959,12 +970,13 @@ class CloudController(object): if volume_ref['status'] != "available": raise exception.ApiError("Volume status must be available") now = datetime.datetime.utcnow() - db.volume_update(context, volume_ref['id'], {'terminated_at': now}) + db.volume_update(context, volume_ref['id'], {'status': 'deleting', + 'terminated_at': now}) host = volume_ref['host'] - rpc.cast(db.queue_get_for(context, FLAGS.volume_topic, host), + rpc.cast(context, + db.queue_get_for(context, FLAGS.volume_topic, host), {"method": "delete_volume", - "args": {"context": None, - "volume_id": volume_ref['id']}}) + "args": {"volume_id": volume_ref['id']}}) return True def describe_images(self, context, image_id=None, **kwargs): diff --git a/nova/api/openstack/auth.py b/nova/api/openstack/auth.py index 4c909293e..7aba55728 100644 --- a/nova/api/openstack/auth.py +++ b/nova/api/openstack/auth.py @@ -24,9 +24,9 @@ class BasicApiAuthManager(object): def __init__(self, host=None, db_driver=None): if not host: host = FLAGS.host - self.host = host + self.host = host if not db_driver: - db_driver = FLAGS.db_driver + db_driver = FLAGS.db_driver self.db = utils.import_object(db_driver) self.auth = auth.manager.AuthManager() self.context = Context() @@ -40,20 +40,19 @@ class BasicApiAuthManager(object): return faults.Fault(webob.exc.HTTPUnauthorized()) try: - username, key = req.headers['X-Auth-User'], \ - req.headers['X-Auth-Key'] + username = req.headers['X-Auth-User'] + key = req.headers['X-Auth-Key'] except KeyError: return faults.Fault(webob.exc.HTTPUnauthorized()) - username, key = req.headers['X-Auth-User'], req.headers['X-Auth-Key'] token, user = self._authorize_user(username, key) if user and token: res = webob.Response() - res.headers['X-Auth-Token'] = token['token_hash'] + res.headers['X-Auth-Token'] = token.token_hash res.headers['X-Server-Management-Url'] = \ - token['server_management_url'] - res.headers['X-Storage-Url'] = token['storage_url'] - res.headers['X-CDN-Management-Url'] = token['cdn_management_url'] + token.server_management_url + res.headers['X-Storage-Url'] = token.storage_url + res.headers['X-CDN-Management-Url'] = token.cdn_management_url res.content_type = 'text/plain' res.status = '204' return res @@ -65,34 +64,35 @@ class BasicApiAuthManager(object): If the token has expired, returns None If the token is not found, returns None - Otherwise returns the token + Otherwise returns dict(id=(the authorized user's id)) 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) if token: - delta = datetime.datetime.now() - token['created_at'] + delta = datetime.datetime.now() - token.created_at if delta.days >= 2: self.db.auth_destroy_token(self.context, token) else: - user = self.auth.get_user(token['user_id']) - return { 'id':user['uid'] } + #TODO(gundlach): Why not just return dict(id=token.user_id)? + user = self.auth.get_user(token.user_id) + return {'id': user.id} return None def _authorize_user(self, username, key): """ Generates a new token and assigns it to a user """ user = self.auth.get_user_from_access_key(key) - if user and user['name'] == username: + if user and user.name == username: token_hash = hashlib.sha1('%s%s%f' % (username, key, time.time())).hexdigest() - token = {} - token['token_hash'] = token_hash - token['cdn_management_url'] = '' - token['server_management_url'] = self._get_server_mgmt_url() - token['storage_url'] = '' - token['user_id'] = user['uid'] - self.db.auth_create_token(self.context, token) + token_dict = {} + token_dict['token_hash'] = token_hash + token_dict['cdn_management_url'] = '' + token_dict['server_management_url'] = self._get_server_mgmt_url() + token_dict['storage_url'] = '' + token_dict['user_id'] = user.id + token = self.db.auth_create_token(self.context, token_dict) return token, user return None, None diff --git a/nova/api/openstack/context.py b/nova/api/openstack/context.py deleted file mode 100644 index 77394615b..000000000 --- a/nova/api/openstack/context.py +++ /dev/null @@ -1,33 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 OpenStack LLC. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -APIRequestContext -""" - -import random - -class Project(object): - def __init__(self, user_id): - self.id = user_id - -class APIRequestContext(object): - """ This is an adapter class to get around all of the assumptions made in - the FlatNetworking """ - def __init__(self, user_id): - self.user_id = user_id - self.project = Project(user_id) diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index cb5132635..a73591ccc 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -24,8 +24,8 @@ from nova import flags from nova import rpc from nova import utils from nova import wsgi +from nova import context from nova.api import cloud -from nova.api.openstack import context from nova.api.openstack import faults from nova.compute import instance_types from nova.compute import power_state @@ -93,6 +93,7 @@ class Controller(wsgi.Controller): if not db_driver: db_driver = FLAGS.db_driver self.db_driver = utils.import_object(db_driver) + self.network_manager = utils.import_object(FLAGS.network_manager) super(Controller, self).__init__() def index(self, req): @@ -109,7 +110,8 @@ class Controller(wsgi.Controller): entity_maker - either _entity_detail or _entity_inst """ user_id = req.environ['nova.context']['user']['id'] - instance_list = self.db_driver.instance_get_all_by_user(None, user_id) + ctxt = context.RequestContext(user_id, user_id) + instance_list = self.db_driver.instance_get_all_by_user(ctxt, user_id) limited_list = nova.api.openstack.limited(instance_list, req) res = [entity_maker(inst)['server'] for inst in limited_list] return _entity_list(res) @@ -117,7 +119,8 @@ class Controller(wsgi.Controller): def show(self, req, id): """ Returns server details by server id """ user_id = req.environ['nova.context']['user']['id'] - inst = self.db_driver.instance_get_by_internal_id(None, int(id)) + ctxt = context.RequestContext(user_id, user_id) + inst = self.db_driver.instance_get_by_internal_id(ctxt, int(id)) if inst: if inst.user_id == user_id: return _entity_detail(inst) @@ -126,9 +129,10 @@ class Controller(wsgi.Controller): def delete(self, req, id): """ Destroys a server """ user_id = req.environ['nova.context']['user']['id'] - instance = self.db_driver.instance_get_by_internal_id(None, int(id)) + ctxt = context.RequestContext(user_id, user_id) + instance = self.db_driver.instance_get_by_internal_id(ctxt, int(id)) if instance and instance['user_id'] == user_id: - self.db_driver.instance_destroy(None, id) + self.db_driver.instance_destroy(ctxt, id) return faults.Fault(exc.HTTPAccepted()) return faults.Fault(exc.HTTPNotFound()) @@ -144,39 +148,43 @@ class Controller(wsgi.Controller): #except Exception, e: # return faults.Fault(exc.HTTPUnprocessableEntity()) - rpc.cast( - FLAGS.compute_topic, { - "method": "run_instance", - "args": {"instance_id": inst['id']}}) + user_id = req.environ['nova.context']['user']['id'] + rpc.cast(context.RequestContext(user_id, user_id), + FLAGS.compute_topic, + {"method": "run_instance", + "args": {"instance_id": inst['id']}}) return _entity_inst(inst) def update(self, req, id): """ Updates the server name or password """ user_id = req.environ['nova.context']['user']['id'] + ctxt = context.RequestContext(user_id, user_id) inst_dict = self._deserialize(req.body, req) if not inst_dict: return faults.Fault(exc.HTTPUnprocessableEntity()) - instance = self.db_driver.instance_get_by_internal_id(None, int(id)) + instance = self.db_driver.instance_get_by_internal_id(ctxt, int(id)) if not instance or instance.user_id != user_id: return faults.Fault(exc.HTTPNotFound()) - self.db_driver.instance_update(None, int(id), - _filter_params(inst_dict['server'])) + self.db_driver.instance_update(ctxt, + int(id), + _filter_params(inst_dict['server'])) return faults.Fault(exc.HTTPNoContent()) def action(self, req, id): """ multi-purpose method used to reboot, rebuild, and resize a server """ user_id = req.environ['nova.context']['user']['id'] + ctxt = context.RequestContext(user_id, user_id) input_dict = self._deserialize(req.body, req) try: reboot_type = input_dict['reboot']['type'] except Exception: raise faults.Fault(webob.exc.HTTPNotImplemented()) - inst_ref = self.db.instance_get_by_internal_id(None, int(id)) + inst_ref = self.db.instance_get_by_internal_id(ctxt, int(id)) if not inst_ref or (inst_ref and not inst_ref.user_id == user_id): return faults.Fault(exc.HTTPUnprocessableEntity()) cloud.reboot(id) @@ -187,6 +195,7 @@ class Controller(wsgi.Controller): inst = {} user_id = req.environ['nova.context']['user']['id'] + ctxt = context.RequestContext(user_id, user_id) flavor_id = env['server']['flavorId'] @@ -233,12 +242,8 @@ class Controller(wsgi.Controller): inst['vcpus'] = flavor['vcpus'] inst['local_gb'] = flavor['local_gb'] - ref = self.db_driver.instance_create(None, inst) + ref = self.db_driver.instance_create(ctxt, inst) inst['id'] = ref.internal_id - # TODO(dietz): this isn't explicitly necessary, but the networking - # calls depend on an object with a project_id property, and therefore - # should be cleaned up later - api_context = context.APIRequestContext(user_id) inst['mac_address'] = utils.generate_mac() @@ -246,19 +251,19 @@ class Controller(wsgi.Controller): inst['launch_index'] = 0 inst['hostname'] = str(ref.internal_id) - self.db_driver.instance_update(api_context, inst['id'], inst) + self.db_driver.instance_update(ctxt, inst['id'], inst) network_manager = utils.import_object(FLAGS.network_manager) - address = network_manager.allocate_fixed_ip(api_context, + address = network_manager.allocate_fixed_ip(ctxt, inst['id']) # TODO(vish): This probably should be done in the scheduler # network is setup when host is assigned - network_topic = self._get_network_topic(api_context, network_manager) - rpc.call(network_topic, + network_topic = self._get_network_topic(ctxt, network_manager) + rpc.call(ctxt, + network_topic, {"method": "setup_fixed_ip", - "args": {"context": api_context, - "address": address}}) + "args": {"address": address}}) return inst def _get_network_topic(self, context, network_manager): @@ -266,8 +271,8 @@ class Controller(wsgi.Controller): network_ref = network_manager.get_network(context) host = network_ref['host'] if not host: - host = rpc.call(FLAGS.network_topic, - {"method": "set_network_host", - "args": {"context": context, - "network_id": network_ref['id']}}) - return self.db_driver.queue_get_for(None, FLAGS.network_topic, host) + host = rpc.call(context, + FLAGS.network_topic, + {"method": "set_network_host", + "args": {"network_id": network_ref['id']}}) + return self.db_driver.queue_get_for(context, FLAGS.network_topic, host) |
