diff options
-rw-r--r-- | nova/compute/api.py | 10 | ||||
-rw-r--r-- | nova/compute/manager.py | 12 | ||||
-rw-r--r-- | nova/exception.py | 4 | ||||
-rw-r--r-- | nova/network/api.py | 8 | ||||
-rw-r--r-- | nova/network/manager.py | 12 | ||||
-rw-r--r-- | nova/tests/api/openstack/contrib/test_multinic_xs.py | 10 | ||||
-rw-r--r-- | nova/tests/test_network.py | 33 | ||||
-rw-r--r-- | nova/virt/driver.py | 4 |
8 files changed, 82 insertions, 11 deletions
diff --git a/nova/compute/api.py b/nova/compute/api.py index edd1a4d64..432658bbb 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -901,8 +901,14 @@ class API(base.Base): def add_fixed_ip(self, context, instance_id, network_id): """Add fixed_ip from specified network to given instance.""" self._cast_compute_message('add_fixed_ip_to_instance', context, - instance_id, - network_id) + instance_id, + params=dict(network_id=network_id)) + + @scheduler_api.reroute_compute("remove_fixed_ip") + def remove_fixed_ip(self, context, instance_id, address): + """Remove fixed_ip from specified network to given instance.""" + self._cast_compute_message('remove_fixed_ip_from_instance', context, + instance_id, params=dict(address=address)) #TODO(tr3buchet): how to run this in the correct zone? def add_network_to_project(self, context, project_id): diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 91a604934..c627d2985 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -842,6 +842,18 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception @checks_instance_lock + def remove_fixed_ip_from_instance(self, context, instance_id, address): + """Calls network_api to remove existing fixed_ip from instance + by injecting the altered network info and resetting + instance networking. + """ + self.network_api.remove_fixed_ip_from_instance(context, instance_id, + address) + self.inject_network_info(context, instance_id) + self.reset_network(context, instance_id) + + @exception.wrap_exception + @checks_instance_lock def pause_instance(self, context, instance_id): """Pause an instance on this host.""" context = context.elevated() diff --git a/nova/exception.py b/nova/exception.py index a6776b64f..988940d6a 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -377,6 +377,10 @@ class FixedIpNotFoundForInstance(FixedIpNotFound): message = _("Instance %(instance_id)s has zero fixed ips.") +class FixedIpNotFoundForSpecificInstance(FixedIpNotFound): + message = _("Instance %(instance_id)s doesn't have fixed ip '%(ip)s'.") + + class FixedIpNotFoundForVirtualInterface(FixedIpNotFound): message = _("Virtual interface %(vif_id)s has zero associated fixed ips.") diff --git a/nova/network/api.py b/nova/network/api.py index b2b96082b..70b1099f0 100644 --- a/nova/network/api.py +++ b/nova/network/api.py @@ -156,6 +156,14 @@ class API(base.Base): {'method': 'add_fixed_ip_to_instance', 'args': args}) + def remove_fixed_ip_from_instance(self, context, instance_id, address): + """Removes a fixed ip from instance from specified network.""" + args = {'instance_id': instance_id, + 'address': address} + rpc.cast(context, FLAGS.network_topic, + {'method': 'remove_fixed_ip_from_instance', + 'args': args}) + def add_network_to_project(self, context, project_id): """Force adds another network to a project.""" rpc.cast(context, FLAGS.network_topic, diff --git a/nova/network/manager.py b/nova/network/manager.py index 21d151033..f17c86524 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -492,6 +492,16 @@ class NetworkManager(manager.SchedulerDependentManager): networks = [self.db.network_get(context, network_id)] self._allocate_fixed_ips(context, instance_id, networks) + def remove_fixed_ip_from_instance(self, context, instance_id, address): + """Removes a fixed ip from an instance from specified network.""" + fixed_ips = self.db.fixed_ip_get_by_instance(context, instance_id) + for fixed_ip in fixed_ips: + if fixed_ip['address'] == address: + self.deallocate_fixed_ip(context, address) + return + raise exception.FixedIpNotFoundForSpecificInstance( + instance_id=instance_id, ip=address) + def allocate_fixed_ip(self, context, instance_id, network, **kwargs): """Gets a fixed ip from the pool.""" # TODO(vish): when this is called by compute, we can associate compute @@ -704,7 +714,7 @@ class FlatManager(NetworkManager): def deallocate_fixed_ip(self, context, address, **kwargs): """Returns a fixed ip to the pool.""" super(FlatManager, self).deallocate_fixed_ip(context, address, - **kwargs) + **kwargs) self.db.fixed_ip_disassociate(context, address) def setup_compute_network(self, context, instance_id): diff --git a/nova/tests/api/openstack/contrib/test_multinic_xs.py b/nova/tests/api/openstack/contrib/test_multinic_xs.py index 484cd1c17..b0a9f7676 100644 --- a/nova/tests/api/openstack/contrib/test_multinic_xs.py +++ b/nova/tests/api/openstack/contrib/test_multinic_xs.py @@ -50,9 +50,8 @@ class FixedIpTest(test.TestCase): fakes.stub_out_auth(self.stubs) self.stubs.Set(compute.api.API, "add_fixed_ip", compute_api_add_fixed_ip) - # TODO(Vek): Fails until remove_fixed_ip() added - # self.stubs.Set(compute.api.API, "remove_fixed_ip", - # compute_api_remove_fixed_ip) + self.stubs.Set(compute.api.API, "remove_fixed_ip", + compute_api_remove_fixed_ip) self.context = context.get_admin_context() def tearDown(self): @@ -98,9 +97,8 @@ class FixedIpTest(test.TestCase): req.headers['content-type'] = 'application/json' resp = req.get_response(fakes.wsgi_app()) - # TODO(Vek): Fails until remove_fixed_ip() added - # self.assertEqual(resp.status_int, 202) - # self.assertEqual(last_remove_fixed_ip, ('test_inst', '10.10.10.1')) + self.assertEqual(resp.status_int, 202) + self.assertEqual(last_remove_fixed_ip, ('test_inst', '10.10.10.1')) def test_remove_fixed_ip_no_address(self): global last_remove_fixed_ip diff --git a/nova/tests/test_network.py b/nova/tests/test_network.py index 6d5166019..b09021e13 100644 --- a/nova/tests/test_network.py +++ b/nova/tests/test_network.py @@ -16,6 +16,7 @@ # under the License. from nova import db +from nova import exception from nova import flags from nova import log as logging from nova import test @@ -238,3 +239,35 @@ class VlanNetworkTestCase(test.TestCase): self.assertRaises(ValueError, self.network.create_networks, None, num_networks=100, vlan_start=1, cidr='192.168.0.1/24', network_size=100) + + +class CommonNetworkTestCase(test.TestCase): + + class FakeNetworkManager(network_manager.NetworkManager): + """This NetworkManager doesn't call the base class so we can bypass all + inherited service cruft and just perform unit tests. + """ + + class FakeDB: + def fixed_ip_get_by_instance(self, context, instance_id): + return [dict(address='10.0.0.0'), dict(address='10.0.0.1'), + dict(address='10.0.0.2')] + + def __init__(self): + self.db = self.FakeDB() + self.deallocate_called = None + + def deallocate_fixed_ip(self, context, address): + self.deallocate_called = address + + def test_remove_fixed_ip_from_instance(self): + manager = self.FakeNetworkManager() + manager.remove_fixed_ip_from_instance(None, 99, '10.0.0.1') + + self.assertEquals(manager.deallocate_called, '10.0.0.1') + + def test_remove_fixed_ip_from_instance_bad_input(self): + manager = self.FakeNetworkManager() + self.assertRaises(exception.FixedIpNotFoundForSpecificInstance, + manager.remove_fixed_ip_from_instance, + None, 99, 'bad input') diff --git a/nova/virt/driver.py b/nova/virt/driver.py index 3c4a073bf..178279d31 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -197,7 +197,7 @@ class ComputeDriver(object): def reset_network(self, instance): """reset networking for specified instance""" - raise NotImplementedError() + pass def ensure_filtering_rules_for_instance(self, instance_ref): """Setting up filtering rules and waiting for its completion. @@ -244,7 +244,7 @@ class ComputeDriver(object): def inject_network_info(self, instance, nw_info): """inject network info for specified instance""" - raise NotImplementedError() + pass def poll_rescued_instances(self, timeout): """Poll for rescued instances""" |