summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorTrey Morris <treyemorris@gmail.com>2012-06-15 16:35:31 -0500
committerTrey Morris <treyemorris@gmail.com>2012-06-18 13:31:56 -0500
commit82599c77346bbefd550ea4ee6c0b13a3df4950af (patch)
tree5178e194b41705fc264eca182cebe42535ff83a7 /nova/api
parent4d9545260509d238e7ba809d39b3a4e602f5777b (diff)
downloadnova-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.py45
-rw-r--r--nova/api/ec2/ec2utils.py20
-rw-r--r--nova/api/openstack/compute/contrib/floating_ips.py75
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)