def _format_volume(self, context, volume): instance_ec2_id = None instance_data = None if volume.get('instance', None): instance_id = volume['instance']['id'] instance_ec2_id = ec2utils.id_to_ec2_id(instance_id) instance_data = '%s[%s]' % (instance_ec2_id, volume['instance']['host']) v = {} v['volumeId'] = ec2utils.id_to_ec2_id(volume['id'], 'vol-%08x') v['status'] = volume['status'] v['size'] = volume['size'] v['availabilityZone'] = volume['availability_zone'] v['createTime'] = volume['created_at'] if context.is_admin: v['status'] = '%s (%s, %s, %s, %s)' % ( volume['status'], volume['project_id'], volume['host'], instance_data, volume['mountpoint']) if volume['attach_status'] == 'attached': v['attachmentSet'] = [{'attachTime': volume['attach_time'], 'deleteOnTermination': False, 'device': volume['mountpoint'], 'instanceId': instance_ec2_id, 'status': 'attached', 'volumeId': v['volumeId']}] else: v['attachmentSet'] = [{}] v['display_name'] = volume['display_name'] v['display_description'] = volume['display_description'] return v
def _format_volume(self, context, volume): instance_ec2_id = None instance_data = None if volume.get('instance', None): instance_id = volume['instance']['id'] instance_ec2_id = ec2utils.id_to_ec2_id(instance_id) instance_data = '%s[%s]' % (instance_ec2_id, volume['instance']['host']) v = {} v['volumeId'] = ec2utils.id_to_ec2_id(volume['id'], 'vol-%08x') v['status'] = volume['status'] v['size'] = volume['size'] v['availabilityZone'] = volume['availability_zone'] v['createTime'] = volume['created_at'] if context.is_admin: v['status'] = '%s (%s, %s, %s, %s)' % ( volume['status'], volume['project_id'], volume['host'], instance_data, volume['mountpoint']) if volume['attach_status'] == 'attached': v['attachmentSet'] = [{ 'attachTime': volume['attach_time'], 'deleteOnTermination': False, 'device': volume['mountpoint'], 'instanceId': instance_ec2_id, 'status': 'attached', 'volumeId': v['volumeId'] }] else: v['attachmentSet'] = [{}] v['display_name'] = volume['display_name'] v['display_description'] = volume['display_description'] return v
def detach_volume(self, context, volume_id, **kwargs): volume_id = ec2utils.ec2_id_to_id(volume_id) LOG.audit(_("Detach volume %s"), volume_id, context=context) volume = self.volume_api.get(context, volume_id) instance = self.compute_api.detach_volume(context, volume_id=volume_id) return {'attachTime': volume['attach_time'], 'device': volume['mountpoint'], 'instanceId': ec2utils.id_to_ec2_id(instance['id']), 'requestId': context.request_id, 'status': volume['attach_status'], 'volumeId': ec2utils.id_to_ec2_id(volume_id, 'vol-%08x')}
def detach_volume(self, context, volume_id, **kwargs): volume_id = ec2utils.ec2_id_to_id(volume_id) LOG.audit(_("Detach volume %s"), volume_id, context=context) volume = self.volume_api.get(context, volume_id=volume_id) instance = self.compute_api.detach_volume(context, volume_id=volume_id) return { 'attachTime': volume['attach_time'], 'device': volume['mountpoint'], 'instanceId': ec2utils.id_to_ec2_id(instance['id']), 'requestId': context.request_id, 'status': volume['attach_status'], 'volumeId': ec2utils.id_to_ec2_id(volume_id, 'vol-%08x') }
def assert_compute_node_has_enough_disk(self, context, instance_ref, dest, disk_over_commit): """Checks if destination host has enough disk for block migration. :param context: security context :param instance_ref: nova.db.sqlalchemy.models.Instance object :param dest: destination host :param disk_over_commit: if True, consider real(not virtual) disk size. """ # Libvirt supports qcow2 disk format,which is usually compressed # on compute nodes. # Real disk image (compressed) may enlarged to "virtual disk size", # that is specified as the maximum disk size. # (See qemu-img -f path-to-disk) # Scheduler recognizes destination host still has enough disk space # if real disk size < available disk size # if disk_over_commit is True, # otherwise virtual disk size < available disk size. # Refresh compute_nodes table topic = db.queue_get_for(context, FLAGS.compute_topic, dest) rpc.call(context, topic, {"method": "update_available_resource"}) # Getting total available disk of host available_gb = self._get_compute_info(context, dest, 'disk_available_least') available = available_gb * (1024 ** 3) # Getting necessary disk size try: topic = db.queue_get_for(context, FLAGS.compute_topic, instance_ref['host']) ret = rpc.call(context, topic, {"method": 'get_instance_disk_info', "args": {'instance_name': instance_ref['name']}}) disk_infos = utils.loads(ret) except rpc.RemoteError: LOG.exception(_("host %(dest)s is not compatible with " "original host %(src)s.") % locals()) raise necessary = 0 if disk_over_commit: for info in disk_infos: necessary += int(info['disk_size']) else: for info in disk_infos: necessary += int(info['virt_disk_size']) # Check that available disk > necessary disk if (available - necessary) < 0: instance_id = ec2utils.id_to_ec2_id(instance_ref['id']) reason = _("Unable to migrate %(instance_id)s to %(dest)s: " "Lack of disk(host:%(available)s " "<= instance:%(necessary)s)") raise exception.MigrationError(reason=reason % locals())
def _live_migration_src_check(self, context, instance_ref): """Live migration check routine (for src host). :param context: security context :param instance_ref: nova.db.sqlalchemy.models.Instance object """ # Checking instance is running. if instance_ref['power_state'] != power_state.RUNNING: instance_id = ec2utils.id_to_ec2_id(instance_ref['id']) raise exception.InstanceNotRunning(instance_id=instance_id) # Checing volume node is running when any volumes are mounted # to the instance. if len(instance_ref['volumes']) != 0: services = db.service_get_all_by_topic(context, 'volume') if len(services) < 1 or not self.service_is_up(services[0]): raise exception.VolumeServiceUnavailable() # Checking src host exists and compute node src = instance_ref['host'] services = db.service_get_all_compute_by_host(context, src) # Checking src host is alive. if not self.service_is_up(services[0]): raise exception.ComputeServiceUnavailable(host=src)
def assert_compute_node_has_enough_disk(self, context, instance_ref, dest): """Checks if destination host has enough disk for block migration. :param context: security context :param instance_ref: nova.db.sqlalchemy.models.Instance object :param dest: destination host """ # Getting total available memory and disk of host avail = self._get_compute_info(context, dest, 'local_gb') # Getting total used memory and disk of host # It should be sum of disks that are assigned as max value # because overcommiting is risky. used = 0 instance_refs = db.instance_get_all_by_host(context, dest) used_list = [i['local_gb'] for i in instance_refs] if used_list: used = reduce(lambda x, y: x + y, used_list) disk_inst = instance_ref['local_gb'] avail = avail - used if avail <= disk_inst: instance_id = ec2utils.id_to_ec2_id(instance_ref['id']) reason = _("Unable to migrate %(instance_id)s to %(dest)s: " "Lack of disk(host:%(avail)s " "<= instance:%(disk_inst)s)") raise exception.MigrationError(reason=reason % locals())
def test_describe_instances(self): """Makes sure describe_instances works and filters results.""" inst1 = db.instance_create(self.context, {'reservation_id': 'a', 'image_id': 1, 'host': 'host1'}) inst2 = db.instance_create(self.context, {'reservation_id': 'a', 'image_id': 1, 'host': 'host2'}) comp1 = db.service_create(self.context, {'host': 'host1', 'availability_zone': 'zone1', 'topic': "compute"}) comp2 = db.service_create(self.context, {'host': 'host2', 'availability_zone': 'zone2', 'topic': "compute"}) result = self.cloud.describe_instances(self.context) result = result['reservationSet'][0] self.assertEqual(len(result['instancesSet']), 2) instance_id = ec2utils.id_to_ec2_id(inst2['id']) result = self.cloud.describe_instances(self.context, instance_id=[instance_id]) result = result['reservationSet'][0] self.assertEqual(len(result['instancesSet']), 1) self.assertEqual(result['instancesSet'][0]['instanceId'], instance_id) self.assertEqual(result['instancesSet'][0] ['placement']['availabilityZone'], 'zone2') db.instance_destroy(self.context, inst1['id']) db.instance_destroy(self.context, inst2['id']) db.service_destroy(self.context, comp1['id']) db.service_destroy(self.context, comp2['id'])
def assert_compute_node_has_enough_memory(self, context, instance_ref, dest): """Checks if destination host has enough memory for live migration. :param context: security context :param instance_ref: nova.db.sqlalchemy.models.Instance object :param dest: destination host """ elevated = context.elevated() # Getting total available memory and disk of host avail = self._get_compute_info(elevated, dest, 'memory_mb') # Getting total used memory and disk of host # It should be sum of memories that are assigned as max value, # because overcommiting is risky. used = 0 instance_refs = db.instance_get_all_by_host(elevated, dest) used_list = [i['memory_mb'] for i in instance_refs] if used_list: used = reduce(lambda x, y: x + y, used_list) mem_inst = instance_ref['memory_mb'] avail = avail - used - FLAGS.cs_host_reserved_memory_mb if avail <= mem_inst: instance_id = ec2utils.id_to_ec2_id(instance_ref['id']) reason = _("Lack of memory(host:%(avail)s"\ " <= instance:%(mem_inst)s)"\ "on $(dest)") raise exception.InsufficientFreeMemory(uuid=dest)
def _live_migration_dest_check(self, context, instance_ref, dest, block_migration): """Live migration check routine (for destination host). :param context: security context :param instance_ref: nova.db.sqlalchemy.models.Instance object :param dest: destination host """ # Checking dest exists and compute node. dservice_refs = db.service_get_all_compute_by_host(context, dest) dservice_ref = dservice_refs[0] # Checking dest host is alive. if not self.service_is_up(dservice_ref): raise exception.ComputeServiceUnavailable(host=dest) # Checking whether The host where instance is running # and dest is not same. src = instance_ref['host'] if dest == src: instance_id = ec2utils.id_to_ec2_id(instance_ref['id']) raise exception.UnableToMigrateToSelf(instance_id=instance_id, host=dest) # Checking dst host still has enough capacities. self.assert_compute_node_has_enough_resources(context, instance_ref, dest, block_migration)
def test_vpn_dict_state_running(self): isonow = datetime.datetime.utcnow() vpn_instance = { 'id': 1, 'created_at': isonow, 'fixed_ip': { 'address': '127.0.0.1' } } project = type('Project', (object, ), { 'id': 'project', 'vpn_ip': '127.0.0.1', 'vpn_port': 1234 }) # Returns state running for 127.0.0.1 - look at class setup expected_vpn_dict = { 'project_id': 'project', 'public_ip': '127.0.0.1', 'public_port': 1234, 'internal_ip': '127.0.0.1', 'instance_id': ec2utils.id_to_ec2_id(1), 'created_at': utils.isotime(isonow), 'state': 'running' } self.assertEqual(expected_vpn_dict, admin.vpn_dict(project, vpn_instance))
def assert_compute_node_has_enough_disk(self, context, instance_ref, dest, disk_over_commit): """Checks if destination host has enough disk for block migration. :param context: security context :param instance_ref: nova.db.sqlalchemy.models.Instance object :param dest: destination host :param disk_over_commit: if True, consider real(not virtual) disk size. """ # Libvirt supports qcow2 disk format,which is usually compressed # on compute nodes. # Real disk image (compressed) may enlarged to "virtual disk size", # that is specified as the maximum disk size. # (See qemu-img -f path-to-disk) # Scheduler recognizes destination host still has enough disk space # if real disk size < available disk size # if disk_over_commit is True, # otherwise virtual disk size < available disk size. # Refresh compute_nodes table topic = db.queue_get_for(context, FLAGS.compute_topic, dest) rpc.call(context, topic, {"method": "update_available_resource"}) # Getting total available disk of host available_gb = self._get_compute_info(context, dest, 'disk_available_least') available = available_gb * (1024 ** 3) # Getting necessary disk size try: topic = db.queue_get_for(context, FLAGS.compute_topic, instance_ref['host']) ret = rpc.call(context, topic, {"method": 'get_instance_disk_info', "args": {'instance_name': instance_ref.name}}) disk_infos = utils.loads(ret) except rpc.RemoteError: LOG.exception(_("host %(dest)s is not compatible with " "original host %(src)s.") % locals()) raise necessary = 0 if disk_over_commit: for info in disk_infos: necessary += int(info['disk_size']) else: for info in disk_infos: necessary += int(info['virt_disk_size']) # Check that available disk > necessary disk if (available - necessary) < 0: instance_id = ec2utils.id_to_ec2_id(instance_ref['id']) reason = _("Unable to migrate %(instance_id)s to %(dest)s: " "Lack of disk(host:%(available)s " "<= instance:%(necessary)s)") raise exception.MigrationError(reason=reason % locals())
def get_metadata(self, address): ctxt = context.get_admin_context() instance_ref = self.compute_api.get_all(ctxt, fixed_ip=address) if instance_ref is None: return None # This ensures that all attributes of the instance # are populated. instance_ref = db.instance_get(ctxt, instance_ref['id']) 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']}} else: keys = '' hostname = instance_ref['hostname'] host = instance_ref['host'] availability_zone = self._get_availability_zone_by_host(ctxt, host) floating_ip = db.instance_get_floating_address(ctxt, instance_ref['id']) ec2_id = ec2utils.id_to_ec2_id(instance_ref['id']) image_ec2_id = self.image_ec2_id(instance_ref['image_id']) data = { 'user-data': base64.b64decode(instance_ref['user_data']), 'meta-data': { 'ami-id': image_ec2_id, 'ami-launch-index': instance_ref['launch_index'], 'ami-manifest-path': 'FIXME', 'block-device-mapping': { # TODO(vish): replace with real data 'ami': 'sda1', 'ephemeral0': 'sda2', 'root': '/dev/sda1', 'swap': 'sda3'}, 'hostname': hostname, 'instance-action': 'none', 'instance-id': ec2_id, 'instance-type': instance_ref['instance_type'], 'local-hostname': hostname, 'local-ipv4': address, 'placement': {'availability-zone': availability_zone}, 'public-hostname': hostname, 'public-ipv4': floating_ip or '', 'public-keys': keys, 'reservation-id': instance_ref['reservation_id'], 'security-groups': '', 'mpi': mpi}} for image_type in ['kernel', 'ramdisk']: if instance_ref.get('%s_id' % image_type): ec2_id = self.image_ec2_id(instance_ref['%s_id' % image_type], self._image_type(image_type)) data['meta-data']['%s-id' % image_type] = ec2_id if False: # TODO(vish): store ancestor ids data['ancestor-ami-ids'] = [] if False: # TODO(vish): store product codes data['product-codes'] = [] return data
def assert_compute_node_has_enough_memory(self, context, instance_ref, dest): """Checks if destination host has enough memory for live migration. :param context: security context :param instance_ref: nova.db.sqlalchemy.models.Instance object :param dest: destination host """ # Getting total available memory of host avail = self._get_compute_info(context, dest, "memory_mb") # Getting total used memory and disk of host # It should be sum of memories that are assigned as max value, # because overcommiting is risky. instance_refs = db.instance_get_all_by_host(context, dest) used = sum([i["memory_mb"] for i in instance_refs]) mem_inst = instance_ref["memory_mb"] avail = avail - used if avail <= mem_inst: instance_id = ec2utils.id_to_ec2_id(instance_ref["id"]) reason = _( "Unable to migrate %(instance_id)s to %(dest)s: " "Lack of memory(host:%(avail)s <= " "instance:%(mem_inst)s)" ) raise exception.MigrationError(reason=reason % locals())
def test_update_of_volume_wont_update_private_fields(self): vol = db.volume_create(self.context, {}) self.cloud.update_volume(self.context, ec2utils.id_to_ec2_id(vol['id'], 'vol-%08x'), mountpoint='/not/here') vol = db.volume_get(self.context, vol['id']) self.assertEqual(None, vol['mountpoint']) db.volume_destroy(self.context, vol['id'])
def test_update_of_volume_display_fields(self): vol = db.volume_create(self.context, {}) self.cloud.update_volume(self.context, ec2utils.id_to_ec2_id(vol['id'], 'vol-%08x'), display_name='c00l v0lum3') vol = db.volume_get(self.context, vol['id']) self.assertEqual('c00l v0lum3', vol['display_name']) db.volume_destroy(self.context, vol['id'])
def test_update_of_instance_display_fields(self): inst = db.instance_create(self.context, {}) ec2_id = ec2utils.id_to_ec2_id(inst['id']) self.cloud.update_instance(self.context, ec2_id, display_name='c00l 1m4g3') inst = db.instance_get(self.context, inst['id']) self.assertEqual('c00l 1m4g3', inst['display_name']) db.instance_destroy(self.context, inst['id'])
def attach_volume(self, context, volume_id, instance_id, device, **kwargs): volume_id = ec2utils.ec2_id_to_id(volume_id) instance_id = ec2utils.ec2_id_to_id(instance_id) msg = _("Attach volume %(volume_id)s to instance %(instance_id)s" " at %(device)s") % locals() LOG.audit(msg, context=context) self.compute_api.attach_volume(context, instance_id=instance_id, volume_id=volume_id, device=device) volume = self.volume_api.get(context, volume_id) return {'attachTime': volume['attach_time'], 'device': volume['mountpoint'], 'instanceId': ec2utils.id_to_ec2_id(instance_id), 'requestId': context.request_id, 'status': volume['attach_status'], 'volumeId': ec2utils.id_to_ec2_id(volume_id, 'vol-%08x')}
def _assertInstance(self, instance_id): ec2_instance_id = ec2utils.id_to_ec2_id(instance_id) result = self.cloud.describe_instances(self.context, instance_id=[ec2_instance_id]) result = result["reservationSet"][0] self.assertEqual(len(result["instancesSet"]), 1) result = result["instancesSet"][0] self.assertEqual(result["instanceId"], ec2_instance_id) return result
def _assertInstance(self, instance_id): ec2_instance_id = ec2utils.id_to_ec2_id(instance_id) result = self.cloud.describe_instances(self.context, instance_id=[ec2_instance_id]) result = result['reservationSet'][0] self.assertEqual(len(result['instancesSet']), 1) result = result['instancesSet'][0] self.assertEqual(result['instanceId'], ec2_instance_id) return result
def __call__(self, req): context = req.environ['ec2.context'] api_request = req.environ['ec2.request'] result = None try: result = api_request.invoke(context) except exception.InstanceNotFound as ex: LOG.info(_('InstanceNotFound raised: %s'), unicode(ex), context=context) ec2_id = ec2utils.id_to_ec2_id(ex.instance_id) message = _('Instance %s not found') % ec2_id return self._error(req, context, type(ex).__name__, message) except exception.VolumeNotFound as ex: LOG.info(_('VolumeNotFound raised: %s'), unicode(ex), context=context) ec2_id = ec2utils.id_to_ec2_id(ex.volume_id, 'vol-%08x') message = _('Volume %s not found') % ec2_id return self._error(req, context, type(ex).__name__, message) except exception.NotFound as ex: LOG.info(_('NotFound raised: %s'), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) except exception.ApiError as ex: LOG.exception(_('ApiError raised: %s'), unicode(ex), context=context) if ex.code: return self._error(req, context, ex.code, unicode(ex)) else: return self._error(req, context, type(ex).__name__, unicode(ex)) except Exception as ex: extra = {'environment': req.environ} LOG.exception(_('Unexpected error raised: %s'), unicode(ex), extra=extra, context=context) return self._error(req, context, 'UnknownError', _('An unknown error has occurred. ' 'Please try your request again.')) else: resp = webob.Response() resp.status = 200 resp.headers['Content-Type'] = 'text/xml' resp.body = str(result) return resp
def attach_volume(self, context, volume_id, instance_id, device, **kwargs): volume_id = ec2utils.ec2_id_to_id(volume_id) instance_id = ec2utils.ec2_id_to_id(instance_id) msg = _("Attach volume %(volume_id)s to instance %(instance_id)s" " at %(device)s") % locals() LOG.audit(msg, context=context) self.compute_api.attach_volume(context, instance_id=instance_id, volume_id=volume_id, device=device) volume = self.volume_api.get(context, volume_id=volume_id) return { 'attachTime': volume['attach_time'], 'device': volume['mountpoint'], 'instanceId': ec2utils.id_to_ec2_id(instance_id), 'requestId': context.request_id, 'status': volume['attach_status'], 'volumeId': ec2utils.id_to_ec2_id(volume_id, 'vol-%08x') }
def start_vpn(self, context, project): instance = self._vpn_for(context, project) if not instance: # NOTE(vish) import delayed because of __init__.py from nova.cloudpipe import pipelib pipe = pipelib.CloudPipe() try: pipe.launch_vpn_instance(project) except db.NoMoreNetworks: raise exception.ApiError("Unable to claim IP for VPN instance" ", ensure it isn't running, and try " "again in a few minutes") instance = self._vpn_for(context, project) return {'instance_id': ec2utils.id_to_ec2_id(instance['id'])}
def test_describe_volumes(self): """Makes sure describe_volumes works and filters results.""" vol1 = db.volume_create(self.context, {}) vol2 = db.volume_create(self.context, {}) result = self.cloud.describe_volumes(self.context) self.assertEqual(len(result['volumeSet']), 2) volume_id = ec2utils.id_to_ec2_id(vol2['id'], 'vol-%08x') result = self.cloud.describe_volumes(self.context, volume_id=[volume_id]) self.assertEqual(len(result['volumeSet']), 1) self.assertEqual( ec2utils.ec2_id_to_id(result['volumeSet'][0]['volumeId']), vol2['id']) db.volume_destroy(self.context, vol1['id']) db.volume_destroy(self.context, vol2['id'])
def test_vpn_dict_state_running(self): isonow = datetime.datetime.utcnow() vpn_instance = {"id": 1, "created_at": isonow, "fixed_ip": {"address": "127.0.0.1"}} project = type("Project", (object,), {"id": "project", "vpn_ip": "127.0.0.1", "vpn_port": 1234}) # Returns state running for 127.0.0.1 - look at class setup expected_vpn_dict = { "project_id": "project", "public_ip": "127.0.0.1", "public_port": 1234, "internal_ip": "127.0.0.1", "instance_id": ec2utils.id_to_ec2_id(1), "created_at": utils.isotime(isonow), "state": "running", } self.assertEqual(expected_vpn_dict, admin.vpn_dict(project, vpn_instance))
def vpn_dict(project, vpn_instance): rv = {"project_id": project.id, "public_ip": project.vpn_ip, "public_port": project.vpn_port} if vpn_instance: rv["instance_id"] = ec2utils.id_to_ec2_id(vpn_instance["id"]) rv["created_at"] = utils.isotime(vpn_instance["created_at"]) address = vpn_instance.get("fixed_ip", None) if address: rv["internal_ip"] = address["address"] if project.vpn_ip and project.vpn_port: if utils.vpn_ping(project.vpn_ip, project.vpn_port): rv["state"] = "running" else: rv["state"] = "down" else: rv["state"] = "down - invalid project vpn config" else: rv["state"] = "pending" return rv
def vpn_dict(project, vpn_instance): rv = {'project_id': project.id, 'public_ip': project.vpn_ip, 'public_port': project.vpn_port} if vpn_instance: rv['instance_id'] = ec2utils.id_to_ec2_id(vpn_instance['id']) rv['created_at'] = utils.isotime(vpn_instance['created_at']) address = vpn_instance.get('fixed_ip', None) if address: rv['internal_ip'] = address['address'] if project.vpn_ip and project.vpn_port: if utils.vpn_ping(project.vpn_ip, project.vpn_port): rv['state'] = 'running' else: rv['state'] = 'down' else: rv['state'] = 'down - invalid project vpn config' else: rv['state'] = 'pending' return rv
def test_associate_disassociate_address(self): """Verifies associate runs cleanly without raising an exception""" address = "10.10.10.10" db.floating_ip_create(self.context, { 'address': address, 'host': self.network.host }) self.cloud.allocate_address(self.context) inst = db.instance_create(self.context, {'host': self.compute.host}) fixed = self.network.allocate_fixed_ip(self.context, inst['id']) ec2_id = ec2utils.id_to_ec2_id(inst['id']) self.cloud.associate_address(self.context, instance_id=ec2_id, public_ip=address) greenthread.sleep(0.3) self.cloud.disassociate_address(self.context, public_ip=address) self.cloud.release_address(self.context, public_ip=address) greenthread.sleep(0.3) self.network.deallocate_fixed_ip(self.context, fixed) db.instance_destroy(self.context, inst['id']) db.floating_ip_destroy(self.context, address)
def test_vpn_dict_state_running(self): isonow = datetime.datetime.utcnow() vpn_instance = {'id': 1, 'created_at': isonow, 'fixed_ip': {'address': '127.0.0.1'}} project = type('Project', (object,), {'id': 'project', 'vpn_ip': '127.0.0.1', 'vpn_port': 1234}) # Returns state running for 127.0.0.1 - look at class setup expected_vpn_dict = {'project_id': 'project', 'public_ip': '127.0.0.1', 'public_port': 1234, 'internal_ip': '127.0.0.1', 'instance_id': ec2utils.id_to_ec2_id(1), 'created_at': utils.isotime(isonow), 'state': 'running'} self.assertEqual(expected_vpn_dict, admin.vpn_dict(project, vpn_instance))
def test_associate_disassociate_address(self): """Verifies associate runs cleanly without raising an exception""" address = "10.10.10.10" db.floating_ip_create(self.context, {'address': address, 'host': self.network.host}) self.cloud.allocate_address(self.context) inst = db.instance_create(self.context, {'host': self.compute.host}) fixed = self.network.allocate_fixed_ip(self.context, inst['id']) ec2_id = ec2utils.id_to_ec2_id(inst['id']) self.cloud.associate_address(self.context, instance_id=ec2_id, public_ip=address) greenthread.sleep(0.3) self.cloud.disassociate_address(self.context, public_ip=address) self.cloud.release_address(self.context, public_ip=address) greenthread.sleep(0.3) self.network.deallocate_fixed_ip(self.context, fixed) db.instance_destroy(self.context, inst['id']) db.floating_ip_destroy(self.context, address)
def format_addresses(self, context): addresses = [] if context.is_admin: iterator = db.floating_ip_get_all(context) else: iterator = db.floating_ip_get_all_by_project(context, context.project_id) for floating_ip_ref in iterator: address = floating_ip_ref['address'] ec2_id = None if (floating_ip_ref['fixed_ip'] and floating_ip_ref['fixed_ip']['instance']): instance_id = floating_ip_ref['fixed_ip']['instance']['id'] ec2_id = ec2utils.id_to_ec2_id(instance_id) address_rv = {'public_ip': address, 'instance_id': ec2_id} if context.is_admin: details = "%s (%s)" % (address_rv['instance_id'], floating_ip_ref['project_id']) address_rv['instance_id'] = details addresses.append(address_rv) return {'addressesSet': addresses}
def __call__(self, req): context = req.environ["ec2.context"] api_request = req.environ["ec2.request"] result = None try: result = api_request.invoke(context) except exception.InstanceNotFound as ex: LOG.info(_("InstanceNotFound raised: %s"), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, ex.message) except exception.VolumeNotFound as ex: LOG.info(_("VolumeNotFound raised: %s"), unicode(ex), context=context) ec2_id = ec2utils.id_to_ec2_id(ex.volume_id, "vol-%08x") message = _("Volume %s not found") % ec2_id return self._error(req, context, type(ex).__name__, message) except exception.NotFound as ex: LOG.info(_("NotFound raised: %s"), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) except exception.ApiError as ex: LOG.exception(_("ApiError raised: %s"), unicode(ex), context=context) if ex.code: return self._error(req, context, ex.code, unicode(ex)) else: return self._error(req, context, type(ex).__name__, unicode(ex)) except exception.KeyPairExists as ex: LOG.debug(_("KeyPairExists raised: %s"), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) except Exception as ex: extra = {"environment": req.environ} LOG.exception(_("Unexpected error raised: %s"), unicode(ex), extra=extra, context=context) return self._error( req, context, "UnknownError", _("An unknown error has occurred. " "Please try your request again.") ) else: resp = webob.Response() resp.status = 200 resp.headers["Content-Type"] = "text/xml" resp.body = str(result) return resp
def format_addresses(self, context): addresses = [] if context.is_admin: iterator = db.floating_ip_get_all(context) else: iterator = db.floating_ip_get_all_by_project( context, context.project_id) for floating_ip_ref in iterator: if floating_ip_ref['project_id'] is None: continue address = floating_ip_ref['address'] ec2_id = None if (floating_ip_ref['fixed_ip'] and floating_ip_ref['fixed_ip']['instance']): instance_id = floating_ip_ref['fixed_ip']['instance']['id'] ec2_id = ec2utils.id_to_ec2_id(instance_id) address_rv = {'public_ip': address, 'instance_id': ec2_id} if context.is_admin: details = "%s (%s)" % (address_rv['instance_id'], floating_ip_ref['project_id']) address_rv['instance_id'] = details addresses.append(address_rv) return {'addressesSet': addresses}
def __init__(self, instance, address=None): self.instance = instance ctxt = context.get_admin_context() services = db.service_get_all_by_host(ctxt.elevated(), instance['host']) self.availability_zone = ec2utils.get_availability_zone_by_host( services, instance['host']) self.ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance) self.security_groups = db.security_group_get_by_instance( ctxt, instance['id']) self.mappings = _format_instance_mapping(ctxt, instance) if instance.get('user_data', None) != None: self.userdata_b64 = base64.b64decode(instance['user_data']) else: self.userdata_b64 = None self.ec2_ids = {} self.ec2_ids['instance-id'] = ec2utils.id_to_ec2_id(instance['id']) self.ec2_ids['ami-id'] = ec2utils.glance_id_to_ec2_id( ctxt, instance['image_ref']) for image_type in ['kernel', 'ramdisk']: if self.instance.get('%s_id' % image_type): image_id = self.instance['%s_id' % image_type] image_type = ec2utils.image_type(image_type) ec2_id = ec2utils.glance_id_to_ec2_id(ctxt, image_id, image_type) self.ec2_ids['%s-id' % image_type] = ec2_id self.address = address
def __init__(self, instance, address=None): self.instance = instance ctxt = context.get_admin_context() services = db.service_get_all_by_host(ctxt.elevated(), instance['host']) self.availability_zone = ec2utils.get_availability_zone_by_host( services, instance['host']) self.ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance) self.security_groups = db.security_group_get_by_instance(ctxt, instance['id']) self.mappings = _format_instance_mapping(ctxt, instance) if instance.get('user_data', None) is not None: self.userdata_b64 = base64.b64decode(instance['user_data']) else: self.userdata_b64 = None self.ec2_ids = {} self.ec2_ids['instance-id'] = ec2utils.id_to_ec2_id(instance['id']) self.ec2_ids['ami-id'] = ec2utils.glance_id_to_ec2_id(ctxt, instance['image_ref']) for image_type in ['kernel', 'ramdisk']: if self.instance.get('%s_id' % image_type): image_id = self.instance['%s_id' % image_type] image_type = ec2utils.image_type(image_type) ec2_id = ec2utils.glance_id_to_ec2_id(ctxt, image_id, image_type) self.ec2_ids['%s-id' % image_type] = ec2_id self.address = address
def test_id_to_ec2_id(self): self.assertEqual(ec2utils.id_to_ec2_id(30), "i-0000001e") self.assertEqual(ec2utils.id_to_ec2_id(29, "ami-%08x"), "ami-0000001d") self.assertEqual(ec2utils.id_to_ec2_snap_id(28), "snap-0000001c") self.assertEqual(ec2utils.id_to_ec2_vol_id(27), "vol-0000001b")
def __call__(self, req): context = req.environ['nova.context'] api_request = req.environ['ec2.request'] result = None try: result = api_request.invoke(context) except exception.InstanceNotFound as ex: LOG.info(_('InstanceNotFound raised: %s'), unicode(ex), context=context) ec2_id = ec2utils.id_to_ec2_id(ex.kwargs['instance_id']) message = ex.message % {'instance_id': ec2_id} return self._error(req, context, type(ex).__name__, message) except exception.VolumeNotFound as ex: LOG.info(_('VolumeNotFound raised: %s'), unicode(ex), context=context) ec2_id = ec2utils.id_to_ec2_vol_id(ex.kwargs['volume_id']) message = ex.message % {'volume_id': ec2_id} return self._error(req, context, type(ex).__name__, message) except exception.SnapshotNotFound as ex: LOG.info(_('SnapshotNotFound raised: %s'), unicode(ex), context=context) ec2_id = ec2utils.id_to_ec2_snap_id(ex.kwargs['snapshot_id']) message = ex.message % {'snapshot_id': ec2_id} return self._error(req, context, type(ex).__name__, message) except exception.NotFound as ex: LOG.info(_('NotFound raised: %s'), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) except exception.ApiError as ex: LOG.exception(_('ApiError raised: %s'), unicode(ex), context=context) if ex.code: return self._error(req, context, ex.code, unicode(ex)) else: return self._error(req, context, type(ex).__name__, unicode(ex)) except exception.KeyPairExists as ex: LOG.debug(_('KeyPairExists raised: %s'), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) except exception.InvalidParameterValue as ex: LOG.debug(_('InvalidParameterValue raised: %s'), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) except exception.InvalidPortRange as ex: LOG.debug(_('InvalidPortRange raised: %s'), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) except exception.NotAuthorized as ex: LOG.info(_('NotAuthorized raised: %s'), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) except exception.InvalidRequest as ex: LOG.debug(_('InvalidRequest raised: %s'), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) except Exception as ex: extra = {'environment': req.environ} LOG.exception(_('Unexpected error raised: %s'), unicode(ex), extra=extra, context=context) return self._error(req, context, 'UnknownError', _('An unknown error has occurred. ' 'Please try your request again.')) else: resp = webob.Response() resp.status = 200 resp.headers['Content-Type'] = 'text/xml' resp.body = str(result) return resp
def get_metadata(self, address): ctxt = context.get_admin_context() search_opts = {"fixed_ip": address, "deleted": False} try: instance_ref = self.compute_api.get_all(ctxt, search_opts=search_opts) except exception.NotFound: instance_ref = None if not instance_ref: return None # This ensures that all attributes of the instance # are populated. instance_ref = db.instance_get(ctxt, instance_ref[0]["id"]) mpi = self._get_mpi_data(ctxt, instance_ref["project_id"]) hostname = "%s.%s" % (instance_ref["hostname"], FLAGS.dhcp_domain) host = instance_ref["host"] services = db.service_get_all_by_host(ctxt.elevated(), host) availability_zone = ec2utils.get_availability_zone_by_host(services, host) ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance_ref) floating_ips = ip_info["floating_ips"] floating_ip = floating_ips and floating_ips[0] or "" ec2_id = ec2utils.id_to_ec2_id(instance_ref["id"]) image_ec2_id = ec2utils.image_ec2_id(instance_ref["image_ref"]) security_groups = db.security_group_get_by_instance(ctxt, instance_ref["id"]) security_groups = [x["name"] for x in security_groups] mappings = self._format_instance_mapping(ctxt, instance_ref) data = { "user-data": base64.b64decode(instance_ref["user_data"]), "meta-data": { "ami-id": image_ec2_id, "ami-launch-index": instance_ref["launch_index"], "ami-manifest-path": "FIXME", "block-device-mapping": mappings, "hostname": hostname, "instance-action": "none", "instance-id": ec2_id, "instance-type": instance_ref["instance_type"]["name"], "local-hostname": hostname, "local-ipv4": address, "placement": {"availability-zone": availability_zone}, "public-hostname": hostname, "public-ipv4": floating_ip, "reservation-id": instance_ref["reservation_id"], "security-groups": security_groups, "mpi": mpi, }, } # public-keys should be in meta-data only if user specified one if instance_ref["key_name"]: data["meta-data"]["public-keys"] = { "0": {"_name": instance_ref["key_name"], "openssh-key": instance_ref["key_data"]} } for image_type in ["kernel", "ramdisk"]: if instance_ref.get("%s_id" % image_type): ec2_id = ec2utils.image_ec2_id(instance_ref["%s_id" % image_type], ec2utils.image_type(image_type)) data["meta-data"]["%s-id" % image_type] = ec2_id if False: # TODO(vish): store ancestor ids data["ancestor-ami-ids"] = [] if False: # TODO(vish): store product codes data["product-codes"] = [] return data
def test_id_to_ec2_id(self): self.assertEqual(ec2utils.id_to_ec2_id(30), 'i-0000001e') self.assertEqual(ec2utils.id_to_ec2_id(29, 'ami-%08x'), 'ami-0000001d') self.assertEqual(ec2utils.id_to_ec2_snap_id(28), 'snap-0000001c') self.assertEqual(ec2utils.id_to_ec2_vol_id(27), 'vol-0000001b')
def get_metadata(self, address): ctxt = context.get_admin_context() search_opts = {'fixed_ip': address, 'deleted': False} try: instance_ref = self.compute_api.get_all(ctxt, search_opts=search_opts) except exception.NotFound: instance_ref = None if not instance_ref: return None # This ensures that all attributes of the instance # are populated. instance_ref = db.instance_get(ctxt, instance_ref[0]['id']) mpi = self._get_mpi_data(ctxt, instance_ref['project_id']) hostname = "%s.%s" % (instance_ref['hostname'], FLAGS.dhcp_domain) host = instance_ref['host'] services = db.service_get_all_by_host(ctxt.elevated(), host) availability_zone = ec2utils.get_availability_zone_by_host( services, host) ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance_ref) floating_ips = ip_info['floating_ips'] floating_ip = floating_ips and floating_ips[0] or '' ec2_id = ec2utils.id_to_ec2_id(instance_ref['id']) image_ec2_id = ec2utils.image_ec2_id(instance_ref['image_ref']) security_groups = db.security_group_get_by_instance( ctxt, instance_ref['id']) security_groups = [x['name'] for x in security_groups] mappings = self._format_instance_mapping(ctxt, instance_ref) data = { 'user-data': base64.b64decode(instance_ref['user_data']), 'meta-data': { 'ami-id': image_ec2_id, 'ami-launch-index': instance_ref['launch_index'], 'ami-manifest-path': 'FIXME', 'block-device-mapping': mappings, 'hostname': hostname, 'instance-action': 'none', 'instance-id': ec2_id, 'instance-type': instance_ref['instance_type']['name'], 'local-hostname': hostname, 'local-ipv4': address, 'placement': { 'availability-zone': availability_zone }, 'public-hostname': hostname, 'public-ipv4': floating_ip, 'reservation-id': instance_ref['reservation_id'], 'security-groups': security_groups, 'mpi': mpi } } # public-keys should be in meta-data only if user specified one if instance_ref['key_name']: data['meta-data']['public-keys'] = { '0': { '_name': instance_ref['key_name'], 'openssh-key': instance_ref['key_data'] } } for image_type in ['kernel', 'ramdisk']: if instance_ref.get('%s_id' % image_type): ec2_id = ec2utils.image_ec2_id( instance_ref['%s_id' % image_type], ec2utils.image_type(image_type)) data['meta-data']['%s-id' % image_type] = ec2_id if False: # TODO(vish): store ancestor ids data['ancestor-ami-ids'] = [] if False: # TODO(vish): store product codes data['product-codes'] = [] return data
def get_metadata(self, address): if not address: raise exception.FixedIpNotFoundForAddress(address=address) cache_key = 'metadata-%s' % address data = self._cache.get(cache_key) if data: return data ctxt = context.get_admin_context() try: fixed_ip = self.network_api.get_fixed_ip_by_address(ctxt, address) instance_ref = db.instance_get(ctxt, fixed_ip['instance_id']) except exception.NotFound: return None hostname = "%s.%s" % (instance_ref['hostname'], FLAGS.dhcp_domain) host = instance_ref['host'] services = db.service_get_all_by_host(ctxt.elevated(), host) availability_zone = ec2utils.get_availability_zone_by_host( services, host) ip_info = ec2utils.get_ip_info_for_instance(ctxt, instance_ref) floating_ips = ip_info['floating_ips'] floating_ip = floating_ips and floating_ips[0] or '' ec2_id = ec2utils.id_to_ec2_id(instance_ref['id']) image_id = instance_ref['image_ref'] ctxt = context.get_admin_context() image_ec2_id = ec2utils.glance_id_to_ec2_id(ctxt, image_id) security_groups = db.security_group_get_by_instance( ctxt, instance_ref['id']) security_groups = [x['name'] for x in security_groups] mappings = self._format_instance_mapping(ctxt, instance_ref) data = { 'user-data': base64.b64decode(instance_ref['user_data']), 'meta-data': { 'ami-id': image_ec2_id, 'ami-launch-index': instance_ref['launch_index'], 'ami-manifest-path': 'FIXME', 'block-device-mapping': mappings, 'hostname': hostname, 'instance-action': 'none', 'instance-id': ec2_id, 'instance-type': instance_ref['instance_type']['name'], 'local-hostname': hostname, 'local-ipv4': address, 'placement': { 'availability-zone': availability_zone }, 'public-hostname': hostname, 'public-ipv4': floating_ip, 'reservation-id': instance_ref['reservation_id'], 'security-groups': security_groups } } # public-keys should be in meta-data only if user specified one if instance_ref['key_name']: data['meta-data']['public-keys'] = { '0': { '_name': instance_ref['key_name'], 'openssh-key': instance_ref['key_data'] } } for image_type in ['kernel', 'ramdisk']: if instance_ref.get('%s_id' % image_type): image_id = instance_ref['%s_id' % image_type] image_type = ec2utils.image_type(image_type) ec2_id = ec2utils.glance_id_to_ec2_id(ctxt, image_id, image_type) data['meta-data']['%s-id' % image_type] = ec2_id if False: # TODO(vish): store ancestor ids data['ancestor-ami-ids'] = [] if False: # TODO(vish): store product codes data['product-codes'] = [] self._cache.set(cache_key, data, 15) return data
def get_metadata(self, address): ctxt = context.get_admin_context() instance_ref = self.compute_api.get_all(ctxt, fixed_ip=address) if instance_ref is None: return None # This ensures that all attributes of the instance # are populated. instance_ref = db.instance_get(ctxt, instance_ref['id']) 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'] } } else: keys = '' hostname = instance_ref['hostname'] host = instance_ref['host'] availability_zone = self._get_availability_zone_by_host(ctxt, host) floating_ip = db.instance_get_floating_address(ctxt, instance_ref['id']) ec2_id = ec2utils.id_to_ec2_id(instance_ref['id']) image_ec2_id = self.image_ec2_id(instance_ref['image_id']) data = { 'user-data': base64.b64decode(instance_ref['user_data']), 'meta-data': { 'ami-id': image_ec2_id, 'ami-launch-index': instance_ref['launch_index'], 'ami-manifest-path': 'FIXME', 'block-device-mapping': { # TODO(vish): replace with real data 'ami': 'sda1', 'ephemeral0': 'sda2', 'root': '/dev/sda1', 'swap': 'sda3' }, 'hostname': hostname, 'instance-action': 'none', 'instance-id': ec2_id, 'instance-type': instance_ref['instance_type'], 'local-hostname': hostname, 'local-ipv4': address, 'placement': { 'availability-zone': availability_zone }, 'public-hostname': hostname, 'public-ipv4': floating_ip or '', 'public-keys': keys, 'reservation-id': instance_ref['reservation_id'], 'security-groups': '', 'mpi': mpi } } for image_type in ['kernel', 'ramdisk']: if instance_ref.get('%s_id' % image_type): ec2_id = self.image_ec2_id(instance_ref['%s_id' % image_type], self._image_type(image_type)) data['meta-data']['%s-id' % image_type] = ec2_id if False: # TODO(vish): store ancestor ids data['ancestor-ami-ids'] = [] if False: # TODO(vish): store product codes data['product-codes'] = [] return data
def _format_instances(self, context, instance_id=None, **kwargs): # TODO(termie): this method is poorly named as its name does not imply # that it will be making a variety of database calls # rather than simply formatting a bunch of instances that # were handed to it reservations = {} # NOTE(vish): instance_id is an optional list of ids to filter by if instance_id: instances = [] for ec2_id in instance_id: internal_id = ec2utils.ec2_id_to_id(ec2_id) instance = self.compute_api.get(context, instance_id=internal_id) instances.append(instance) else: instances = self.compute_api.get_all(context, **kwargs) for instance in instances: if not context.is_admin: if instance['image_id'] == str(FLAGS.vpn_image_id): continue i = {} instance_id = instance['id'] ec2_id = ec2utils.id_to_ec2_id(instance_id) i['instanceId'] = ec2_id i['imageId'] = self.image_ec2_id(instance['image_id']) i['instanceState'] = { 'code': instance['state'], 'name': instance['state_description'] } fixed_addr = None floating_addr = None if instance['fixed_ip']: fixed_addr = instance['fixed_ip']['address'] if instance['fixed_ip']['floating_ips']: fixed = instance['fixed_ip'] floating_addr = fixed['floating_ips'][0]['address'] if instance['fixed_ip']['network'] and 'use_v6' in kwargs: i['dnsNameV6'] = utils.to_global_ipv6( instance['fixed_ip']['network']['cidr_v6'], instance['mac_address']) i['privateDnsName'] = fixed_addr i['privateIpAddress'] = fixed_addr i['publicDnsName'] = floating_addr i['ipAddress'] = floating_addr or fixed_addr i['dnsName'] = i['publicDnsName'] or i['privateDnsName'] i['keyName'] = instance['key_name'] if context.is_admin: i['keyName'] = '%s (%s, %s)' % ( i['keyName'], instance['project_id'], instance['host']) i['productCodesSet'] = self._convert_to_set([], 'product_codes') if instance['instance_type']: i['instanceType'] = instance['instance_type'].get('name') else: i['instanceType'] = None i['launchTime'] = instance['created_at'] i['amiLaunchIndex'] = instance['launch_index'] i['displayName'] = instance['display_name'] i['displayDescription'] = instance['display_description'] host = instance['host'] zone = self._get_availability_zone_by_host(context, host) i['placement'] = {'availabilityZone': zone} if instance['reservation_id'] not in reservations: r = {} r['reservationId'] = instance['reservation_id'] r['ownerId'] = instance['project_id'] security_group_names = [] if instance.get('security_groups'): for security_group in instance['security_groups']: security_group_names.append(security_group['name']) r['groupSet'] = self._convert_to_set(security_group_names, 'groupId') r['instancesSet'] = [] reservations[instance['reservation_id']] = r reservations[instance['reservation_id']]['instancesSet'].append(i) return list(reservations.values())
def image_ec2_id(image_id, image_type='ami'): """Returns image ec2_id using id and three letter type.""" template = image_type + '-%08x' return ec2utils.id_to_ec2_id(int(image_id), template=template)
def __call__(self, req): context = req.environ['nova.context'] request_id = context.request_id api_request = req.environ['ec2.request'] result = None try: result = api_request.invoke(context) except exception.InstanceNotFound as ex: LOG.info(_('InstanceNotFound raised: %s'), unicode(ex), context=context) ec2_id = ec2utils.id_to_ec2_id(ex.kwargs['instance_id']) message = ex.message % {'instance_id': ec2_id} return ec2_error(req, request_id, type(ex).__name__, message) except exception.VolumeNotFound as ex: LOG.info(_('VolumeNotFound raised: %s'), unicode(ex), context=context) ec2_id = ec2utils.id_to_ec2_vol_id(ex.kwargs['volume_id']) message = ex.message % {'volume_id': ec2_id} return ec2_error(req, request_id, type(ex).__name__, message) except exception.SnapshotNotFound as ex: LOG.info(_('SnapshotNotFound raised: %s'), unicode(ex), context=context) ec2_id = ec2utils.id_to_ec2_snap_id(ex.kwargs['snapshot_id']) message = ex.message % {'snapshot_id': ec2_id} return ec2_error(req, request_id, type(ex).__name__, message) except exception.NotFound as ex: LOG.info(_('NotFound raised: %s'), unicode(ex), context=context) return ec2_error(req, request_id, type(ex).__name__, unicode(ex)) except exception.EC2APIError as ex: LOG.exception(_('EC2APIError raised: %s'), unicode(ex), context=context) if ex.code: return ec2_error(req, request_id, ex.code, unicode(ex)) else: return ec2_error(req, request_id, type(ex).__name__, unicode(ex)) except exception.KeyPairExists as ex: LOG.debug(_('KeyPairExists raised: %s'), unicode(ex), context=context) return ec2_error(req, request_id, type(ex).__name__, unicode(ex)) except exception.InvalidParameterValue as ex: LOG.debug(_('InvalidParameterValue raised: %s'), unicode(ex), context=context) return ec2_error(req, request_id, type(ex).__name__, unicode(ex)) except exception.InvalidPortRange as ex: LOG.debug(_('InvalidPortRange raised: %s'), unicode(ex), context=context) return ec2_error(req, request_id, type(ex).__name__, unicode(ex)) except exception.NotAuthorized as ex: LOG.info(_('NotAuthorized raised: %s'), unicode(ex), context=context) return ec2_error(req, request_id, type(ex).__name__, unicode(ex)) except exception.InvalidRequest as ex: LOG.debug(_('InvalidRequest raised: %s'), unicode(ex), context=context) return ec2_error(req, request_id, type(ex).__name__, unicode(ex)) except exception.QuotaError as ex: LOG.debug(_('QuotaError raised: %s'), unicode(ex), context=context) return ec2_error(req, request_id, type(ex).__name__, unicode(ex)) except exception.InvalidInstanceIDMalformed as ex: LOG.debug(_('Invalid id: bogus (expecting "i-..."): %s'), unicode(ex), context=context) return ec2_error(req, request_id, type(ex).__name__, unicode(ex)) except Exception as ex: env = req.environ.copy() for k in env.keys(): if not isinstance(env[k], basestring): env.pop(k) LOG.exception(_('Unexpected error raised: %s'), unicode(ex)) LOG.error(_('Environment: %s') % utils.dumps(env)) return ec2_error(req, request_id, 'UnknownError', _('An unknown error has occurred. ' 'Please try your request again.')) else: resp = webob.Response() resp.status = 200 resp.headers['Content-Type'] = 'text/xml' resp.body = str(result) return resp
def __call__(self, req): context = req.environ['nova.context'] api_request = req.environ['ec2.request'] result = None try: result = api_request.invoke(context) except exception.InstanceNotFound as ex: LOG.info(_('InstanceNotFound raised: %s'), unicode(ex), context=context) ec2_id = ec2utils.id_to_ec2_id(ex.kwargs['instance_id']) message = ex.message % {'instance_id': ec2_id} return self._error(req, context, type(ex).__name__, message) except exception.VolumeNotFound as ex: LOG.info(_('VolumeNotFound raised: %s'), unicode(ex), context=context) ec2_id = ec2utils.id_to_ec2_vol_id(ex.kwargs['volume_id']) message = ex.message % {'volume_id': ec2_id} return self._error(req, context, type(ex).__name__, message) except exception.SnapshotNotFound as ex: LOG.info(_('SnapshotNotFound raised: %s'), unicode(ex), context=context) ec2_id = ec2utils.id_to_ec2_snap_id(ex.kwargs['snapshot_id']) message = ex.message % {'snapshot_id': ec2_id} return self._error(req, context, type(ex).__name__, message) except exception.NotFound as ex: LOG.info(_('NotFound raised: %s'), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) except exception.ApiError as ex: LOG.exception(_('ApiError raised: %s'), unicode(ex), context=context) if ex.code: return self._error(req, context, ex.code, unicode(ex)) else: return self._error(req, context, type(ex).__name__, unicode(ex)) except exception.KeyPairExists as ex: LOG.debug(_('KeyPairExists raised: %s'), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) except exception.InvalidParameterValue as ex: LOG.debug(_('InvalidParameterValue raised: %s'), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) except exception.InvalidPortRange as ex: LOG.debug(_('InvalidPortRange raised: %s'), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) except exception.NotAuthorized as ex: LOG.info(_('NotAuthorized raised: %s'), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) except exception.InvalidRequest as ex: LOG.debug(_('InvalidRequest raised: %s'), unicode(ex), context=context) return self._error(req, context, type(ex).__name__, unicode(ex)) except Exception as ex: extra = {'environment': req.environ} LOG.exception(_('Unexpected error raised: %s'), unicode(ex), extra=extra, context=context) return self._error( req, context, 'UnknownError', _('An unknown error has occurred. ' 'Please try your request again.')) else: resp = webob.Response() resp.status = 200 resp.headers['Content-Type'] = 'text/xml' resp.body = str(result) return resp