summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGary Kotton <gkotton@redhat.com>2013-01-14 13:44:34 +0000
committerGary Kotton <gkotton@redhat.com>2013-01-14 16:23:03 +0000
commit1ff3afc67f97ff28c6ca1c3884a90b97ee1cf9dd (patch)
tree32f4af3bdd61b9559fc50607955129a09fc9d087
parentca4b1303804e94f10f0e4e6c4a9e09c049efd1ee (diff)
downloadnova-1ff3afc67f97ff28c6ca1c3884a90b97ee1cf9dd.tar.gz
nova-1ff3afc67f97ff28c6ca1c3884a90b97ee1cf9dd.tar.xz
nova-1ff3afc67f97ff28c6ca1c3884a90b97ee1cf9dd.zip
Implement Quantum support for addition and removal of fixed IPs
Fixes bug 1099378 Change-Id: I696d1f702cf99ef15af47c261844febd8a6e7ffc
-rw-r--r--nova/network/quantumv2/api.py55
-rw-r--r--nova/tests/network/test_quantumv2.py48
2 files changed, 101 insertions, 2 deletions
diff --git a/nova/network/quantumv2/api.py b/nova/network/quantumv2/api.py
index e04d10edb..53a6e8150 100644
--- a/nova/network/quantumv2/api.py
+++ b/nova/network/quantumv2/api.py
@@ -204,11 +204,62 @@ class API(base.Base):
def add_fixed_ip_to_instance(self, context, instance, network_id):
"""Add a fixed ip to the instance from specified network."""
- raise NotImplementedError()
+ search_opts = {'network_id': network_id}
+ data = quantumv2.get_client(context).list_subnets(**search_opts)
+ ipam_subnets = data.get('subnets', [])
+ if not ipam_subnets:
+ raise exception.NetworkNotFoundForInstance(
+ instance_id=instance['uuid'])
+
+ zone = 'compute:%s' % instance['availability_zone']
+ search_opts = {'device_id': instance['uuid'],
+ 'device_owner': zone,
+ 'network_id': network_id}
+ data = quantumv2.get_client(context).list_ports(**search_opts)
+ ports = data['ports']
+ for p in ports:
+ fixed_ips = p['fixed_ips']
+ for subnet in ipam_subnets:
+ fixed_ip = {'subnet_id': subnet['id']}
+ fixed_ips.append(fixed_ip)
+ port_req_body = {'port': {'fixed_ips': fixed_ips}}
+ try:
+ quantumv2.get_client(context).update_port(p['id'],
+ port_req_body)
+ except Exception as ex:
+ msg = _("Unable to update port %(portid)s with"
+ " failure: %(exception)s")
+ LOG.debug(msg, {'portid': p['id'], 'exception': ex})
+ return
+ raise exception.NetworkNotFoundForInstance(
+ instance_id=instance['uuid'])
def remove_fixed_ip_from_instance(self, context, instance, address):
"""Remove a fixed ip from the instance."""
- raise NotImplementedError()
+ zone = 'compute:%s' % instance['availability_zone']
+ search_opts = {'device_id': instance['uuid'],
+ 'device_owner': zone,
+ 'fixed_ips': 'ip_address=%s' % address}
+ data = quantumv2.get_client(context).list_ports(**search_opts)
+ ports = data['ports']
+ for p in ports:
+ fixed_ips = p['fixed_ips']
+ new_fixed_ips = []
+ for fixed_ip in fixed_ips:
+ if fixed_ip['ip_address'] != address:
+ new_fixed_ips.append(fixed_ip)
+ port_req_body = {'port': {'fixed_ips': new_fixed_ips}}
+ try:
+ quantumv2.get_client(context).update_port(p['id'],
+ port_req_body)
+ except Exception as ex:
+ msg = _("Unable to update port %(portid)s with"
+ " failure: %(exception)s")
+ LOG.debug(msg, {'portid': p['id'], 'exception': ex})
+ return
+
+ raise exception.FixedIpNotFoundForSpecificInstance(
+ instance_uuid=instance['uuid'], ip=address)
def validate_networks(self, context, requested_networks):
"""Validate that the tenant can use the requested networks."""
diff --git a/nova/tests/network/test_quantumv2.py b/nova/tests/network/test_quantumv2.py
index 004e76071..232b22761 100644
--- a/nova/tests/network/test_quantumv2.py
+++ b/nova/tests/network/test_quantumv2.py
@@ -916,6 +916,54 @@ class TestQuantumv2(test.TestCase):
self.mox.ReplayAll()
api.disassociate_floating_ip(self.context, self.instance, address)
+ def test_add_fixed_ip_to_instance(self):
+ api = quantumapi.API()
+ network_id = 'my_netid1'
+ search_opts = {'network_id': network_id}
+ self.moxed_client.list_subnets(
+ **search_opts).AndReturn({'subnets': self.subnet_data1})
+
+ zone = 'compute:%s' % self.instance['availability_zone']
+ search_opts = {'device_id': self.instance['uuid'],
+ 'device_owner': 'compute:nova',
+ 'network_id': network_id}
+ self.moxed_client.list_ports(
+ **search_opts).AndReturn({'ports': self.port_data1})
+ port_req_body = {
+ 'port': {
+ 'fixed_ips': [{'subnet_id': 'my_subid1'}],
+ },
+ }
+ port = self.port_data1[0]
+ port['fixed_ips'] = [{'subnet_id': 'my_subid1'}]
+ self.moxed_client.update_port('my_portid1',
+ MyComparator(port_req_body)).AndReturn({'port': port})
+
+ self.mox.ReplayAll()
+ api.add_fixed_ip_to_instance(self.context, self.instance, network_id)
+
+ def test_remove_fixed_ip_from_instance(self):
+ api = quantumapi.API()
+ address = '10.0.0.3'
+ zone = 'compute:%s' % self.instance['availability_zone']
+ search_opts = {'device_id': self.instance['uuid'],
+ 'device_owner': zone,
+ 'fixed_ips': 'ip_address=%s' % address}
+ self.moxed_client.list_ports(
+ **search_opts).AndReturn({'ports': self.port_data1})
+ port_req_body = {
+ 'port': {
+ 'fixed_ips': [],
+ },
+ }
+ port = self.port_data1[0]
+ port['fixed_ips'] = []
+ self.moxed_client.update_port('my_portid1',
+ MyComparator(port_req_body)).AndReturn({'port': port})
+
+ self.mox.ReplayAll()
+ api.remove_fixed_ip_from_instance(self.context, self.instance, address)
+
class TestQuantumv2ModuleMethods(test.TestCase):
def test_ensure_requested_network_ordering_no_preference(self):