diff options
| author | Trey Morris <treyemorris@gmail.com> | 2012-06-15 16:35:31 -0500 |
|---|---|---|
| committer | Trey Morris <treyemorris@gmail.com> | 2012-06-18 13:31:56 -0500 |
| commit | 82599c77346bbefd550ea4ee6c0b13a3df4950af (patch) | |
| tree | 5178e194b41705fc264eca182cebe42535ff83a7 /nova/api | |
| parent | 4d9545260509d238e7ba809d39b3a4e602f5777b (diff) | |
| download | nova-82599c77346bbefd550ea4ee6c0b13a3df4950af.tar.gz nova-82599c77346bbefd550ea4ee6c0b13a3df4950af.tar.xz nova-82599c77346bbefd550ea4ee6c0b13a3df4950af.zip | |
moved update cache functionality to the network api
previously the network manager get_instance_nw_info
was responsible for updating the cache. This is to
prevent calling that function in a confusing way.
part 2 of this patch was fixing bug997763
floating_ip_associate was removed from the compute
api. network api associate is now called directly.
network api floating_ip functions now require
instance as an argument in order to update cache.
Change-Id: Ie8daa017b99e48769afbac4862696ef0a8eb1067
Diffstat (limited to 'nova/api')
| -rw-r--r-- | nova/api/ec2/cloud.py | 45 | ||||
| -rw-r--r-- | nova/api/ec2/ec2utils.py | 20 | ||||
| -rw-r--r-- | nova/api/openstack/compute/contrib/floating_ips.py | 75 |
3 files changed, 108 insertions, 32 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 037a84783..fb6768d4c 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -1111,17 +1111,48 @@ class CloudController(object): " instance %(instance_id)s") % locals(), context=context) instance_id = ec2utils.ec2_id_to_id(instance_id) instance = self.compute_api.get(context, instance_id) + + cached_ipinfo = ec2utils.get_ip_info_for_instance(context, instance) + fixed_ips = cached_ipinfo['fixed_ips'] + cached_ipinfo['fixed_ip6s'] + if not fixed_ips: + msg = _('Unable to associate IP Address, no fixed_ips.') + raise exception.EC2APIError(msg) + + # TODO(tr3buchet): this will associate the floating IP with the + # first fixed_ip an instance has. This should be + # changed to support specifying a particular fixed_ip if + # multiple exist but this may not apply to ec2.. + if len(fixed_ips) > 1: + msg = _('multiple fixed_ips exist, using the first: %s') + LOG.warning(msg, fixed_ips[0]) + try: - self.compute_api.associate_floating_ip(context, - instance, - address=public_ip) - return {'return': "true"} - except exception.FloatingIpNotFound: - raise exception.EC2APIError(_('Unable to associate IP Address.')) + self.network_api.associate_floating_ip(context, instance, + floating_address=public_ip, + fixed_address=fixed_ips[0]) + return {'return': 'true'} + except exception.FloatingIpAssociated: + msg = _('Floating ip is already associated.') + raise exception.EC2APIError(msg) + except exception.NoFloatingIpInterface: + msg = _('l3driver call to add floating ip failed.') + raise exception.EC2APIError(msg) + except: + msg = _('Error, unable to associate floating ip.') + raise exception.EC2APIError(msg) def disassociate_address(self, context, public_ip, **kwargs): + instance_id = self.network_api.get_instance_id_by_floating_address( + context, public_ip) + instance = self.compute_api.get(context, instance_id) LOG.audit(_("Disassociate address %s"), public_ip, context=context) - self.network_api.disassociate_floating_ip(context, address=public_ip) + try: + self.network_api.disassociate_floating_ip(context, instance, + address=public_ip) + except exception.FloatingIpNotAssociated: + msg = _('Floating ip is not associated.') + raise exception.EC2APIError(msg) + return {'return': "true"} def run_instances(self, context, **kwargs): diff --git a/nova/api/ec2/ec2utils.py b/nova/api/ec2/ec2utils.py index ceb695a5e..c12e65dd3 100644 --- a/nova/api/ec2/ec2utils.py +++ b/nova/api/ec2/ec2utils.py @@ -93,19 +93,13 @@ def image_ec2_id(image_id, image_type='ami'): def get_ip_info_for_instance_from_nw_info(nw_info): - ip_info = dict(fixed_ips=[], fixed_ip6s=[], floating_ips=[]) - for vif in nw_info: - vif_fixed_ips = vif.fixed_ips() - - fixed_ips = [ip['address'] - for ip in vif_fixed_ips if ip['version'] == 4] - fixed_ip6s = [ip['address'] - for ip in vif_fixed_ips if ip['version'] == 6] - floating_ips = [ip['address'] - for ip in vif.floating_ips()] - ip_info['fixed_ips'].extend(fixed_ips) - ip_info['fixed_ip6s'].extend(fixed_ip6s) - ip_info['floating_ips'].extend(floating_ips) + ip_info = {} + fixed_ips = nw_info.fixed_ips() + ip_info['fixed_ips'] = [ip['address'] for ip in fixed_ips + if ip['version'] == 4] + ip_info['fixed_ip6s'] = [ip['address'] for ip in fixed_ips + if ip['version'] == 6] + ip_info['floating_ips'] = [ip['address'] for ip in nw_info.floating_ips()] return ip_info diff --git a/nova/api/openstack/compute/contrib/floating_ips.py b/nova/api/openstack/compute/contrib/floating_ips.py index 11da0d770..a3dac71ae 100644 --- a/nova/api/openstack/compute/contrib/floating_ips.py +++ b/nova/api/openstack/compute/contrib/floating_ips.py @@ -23,6 +23,7 @@ from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova.api.openstack import xmlutil from nova import compute +from nova.compute import utils as compute_utils from nova import exception from nova import log as logging from nova import network @@ -79,6 +80,23 @@ def _translate_floating_ips_view(floating_ips): for ip in floating_ips]} +def get_instance_by_floating_ip_addr(self, context, address): + snagiibfa = self.network_api.get_instance_id_by_floating_address + instance_id = snagiibfa(context, address) + if instance_id: + return self.compute_api.get(context, instance_id) + + +def disassociate_floating_ip(self, context, instance, address): + try: + self.network_api.disassociate_floating_ip(context, instance, address) + except exception.NotAuthorized: + raise webob.exc.HTTPUnauthorized() + except exception.FloatingIpNotAssociated: + msg = _('Floating ip is not associated') + raise webob.exc.HTTPBadRequest(explanation=msg) + + class FloatingIPController(object): """The Floating IPs API controller for the OpenStack API.""" @@ -163,14 +181,20 @@ class FloatingIPController(object): def delete(self, req, id): context = req.environ['nova.context'] authorize(context) + + # get the floating ip object floating_ip = self.network_api.get_floating_ip(context, id) + address = floating_ip['address'] + + # get the associated instance object (if any) + instance = get_instance_by_floating_ip_addr(self, context, address) + # disassociate if associated if floating_ip.get('fixed_ip_id'): - self.network_api.disassociate_floating_ip(context, - floating_ip['address']) + disassociate_floating_ip(self, context, instance, address) - self.network_api.release_floating_ip(context, - address=floating_ip['address']) + # release ip from project + self.network_api.release_floating_ip(context, address) return webob.Response(status_int=202) def _get_ip_by_id(self, context, value): @@ -201,11 +225,36 @@ class FloatingIPActionController(wsgi.Controller): instance = self.compute_api.get(context, id) + cached_nwinfo = compute_utils.get_nw_info_for_instance(instance) + if not cached_nwinfo: + msg = _('No nw_info cache associated with instance') + raise webob.exc.HTTPBadRequest(explanation=msg) + + fixed_ips = cached_nwinfo.fixed_ips() + if not fixed_ips: + msg = _('No fixed ips associated to instance') + raise webob.exc.HTTPBadRequest(explanation=msg) + + # TODO(tr3buchet): this will associate the floating IP with the + # first fixed_ip an instance has. This should be + # changed to support specifying a particular fixed_ip if + # multiple exist. + if len(fixed_ips) > 1: + msg = _('multiple fixed_ips exist, using the first: %s') + LOG.warning(msg, fixed_ips[0]['address']) + try: - self.compute_api.associate_floating_ip(context, instance, - address) - except exception.FixedIpNotFoundForInstance: - msg = _("No fixed ips associated to instance") + self.network_api.associate_floating_ip(context, instance, + floating_address=address, + fixed_address=fixed_ips[0]['address']) + except exception.FloatingIpAssociated: + msg = _('floating ip is already associated') + raise webob.exc.HTTPBadRequest(explanation=msg) + except exception.NoFloatingIpInterface: + msg = _('l3driver call to add floating ip failed') + raise webob.exc.HTTPBadRequest(explanation=msg) + except: + msg = _('Error. Unable to associate floating ip') raise webob.exc.HTTPBadRequest(explanation=msg) return webob.Response(status_int=202) @@ -225,13 +274,15 @@ class FloatingIPActionController(wsgi.Controller): msg = _("Address not specified") raise webob.exc.HTTPBadRequest(explanation=msg) + # get the floating ip object floating_ip = self.network_api.get_floating_ip_by_address(context, address) + # get the associated instance object (if any) + instance = get_instance_by_floating_ip_addr(self, context, address) + + # disassociate if associated if floating_ip.get('fixed_ip_id'): - try: - self.network_api.disassociate_floating_ip(context, address) - except exception.NotAuthorized: - raise webob.exc.HTTPUnauthorized() + disassociate_floating_ip(self, context, instance, address) return webob.Response(status_int=202) |
