Merge "Delete nic metadata when detaching interface"
This commit is contained in:
commit
6813365825
@ -162,7 +162,8 @@ class InterfaceAttachmentController(wsgi.Controller):
|
||||
context.can(ai_policies.POLICY_ROOT % 'delete')
|
||||
port_id = id
|
||||
|
||||
instance = common.get_instance(self.compute_api, context, server_id)
|
||||
instance = common.get_instance(self.compute_api, context, server_id,
|
||||
expected_attrs=['device_metadata'])
|
||||
try:
|
||||
self.compute_api.detach_interface(context,
|
||||
instance, port_id=port_id)
|
||||
|
@ -1224,6 +1224,8 @@ class API(base_api.NetworkAPI):
|
||||
# Delete the VirtualInterface for the given port_id.
|
||||
vif = objects.VirtualInterface.get_by_uuid(context, port_id)
|
||||
if vif:
|
||||
if 'tag' in vif and vif.tag:
|
||||
self._delete_nic_metadata(self, instance, vif)
|
||||
vif.destroy()
|
||||
else:
|
||||
LOG.debug('VirtualInterface not found for port: %s',
|
||||
@ -1231,6 +1233,14 @@ class API(base_api.NetworkAPI):
|
||||
|
||||
return self.get_instance_nw_info(context, instance)
|
||||
|
||||
def _delete_nic_metadata(self, instance, vif):
|
||||
for device in instance.device_metadata.devices:
|
||||
if (isinstance(device, objects.NetworkInterfaceMetadata)
|
||||
and device.mac == vif.address):
|
||||
instance.device_metadata.devices.remove(device)
|
||||
instance.save()
|
||||
break
|
||||
|
||||
def list_ports(self, context, **search_opts):
|
||||
"""List ports for the client based on search options."""
|
||||
return get_client(context).list_ports(**search_opts)
|
||||
|
@ -16,6 +16,7 @@
|
||||
import mock
|
||||
from webob import exc
|
||||
|
||||
from nova.api.openstack import common
|
||||
from nova.api.openstack.compute import attach_interfaces \
|
||||
as attach_interfaces_v21
|
||||
from nova.compute import api as compute_api
|
||||
@ -177,7 +178,11 @@ class InterfaceAttachTestsV21(test.NoDBTestCase):
|
||||
self.stub_out('nova.compute.api.API.detach_interface',
|
||||
fake_detach_interface)
|
||||
|
||||
result = self.attachments.delete(self.req, FAKE_UUID1, FAKE_PORT_ID1)
|
||||
inst = objects.Instance(uuid=FAKE_UUID1)
|
||||
with mock.patch.object(common, 'get_instance',
|
||||
return_value=inst) as mock_get_instance:
|
||||
result = self.attachments.delete(self.req, FAKE_UUID1,
|
||||
FAKE_PORT_ID1)
|
||||
# NOTE: on v2.1, http status code is set as wsgi_code of API
|
||||
# method instead of status_int in a response object.
|
||||
if isinstance(self.attachments,
|
||||
@ -186,6 +191,10 @@ class InterfaceAttachTestsV21(test.NoDBTestCase):
|
||||
else:
|
||||
status_int = result.status_int
|
||||
self.assertEqual(202, status_int)
|
||||
ctxt = self.req.environ['nova.context']
|
||||
mock_get_instance.assert_called_with(
|
||||
self.attachments.compute_api, ctxt, FAKE_UUID1,
|
||||
expected_attrs=['device_metadata'])
|
||||
|
||||
def test_detach_interface_instance_locked(self):
|
||||
def fake_detach_interface_from_locked_server(self, context,
|
||||
|
@ -4501,6 +4501,7 @@ class TestNeutronv2WithMock(test.TestCase):
|
||||
raise_if_fail=True)
|
||||
mock_delete_vifs.assert_called_once_with(mock.sentinel.ctx, 'inst-1')
|
||||
|
||||
@mock.patch('nova.network.neutronv2.api.API._delete_nic_metadata')
|
||||
@mock.patch('nova.network.neutronv2.api.API.get_instance_nw_info')
|
||||
@mock.patch('nova.network.neutronv2.api.API._unbind_ports')
|
||||
@mock.patch('nova.objects.Instance.get_network_info')
|
||||
@ -4511,7 +4512,8 @@ class TestNeutronv2WithMock(test.TestCase):
|
||||
mock_ntrn,
|
||||
mock_inst_get_nwinfo,
|
||||
mock_unbind,
|
||||
mock_netinfo):
|
||||
mock_netinfo,
|
||||
mock_del_nic_meta):
|
||||
mock_inst = mock.Mock(project_id="proj-1",
|
||||
availability_zone='zone-1',
|
||||
uuid='inst-1')
|
||||
@ -4521,14 +4523,29 @@ class TestNeutronv2WithMock(test.TestCase):
|
||||
id='3', preserve_on_delete=True)]
|
||||
mock_client = mock.Mock()
|
||||
mock_ntrn.return_value = mock_client
|
||||
mock_vif = mock.MagicMock(spec=objects.VirtualInterface)
|
||||
mock_get_vif_by_uuid.return_value = mock_vif
|
||||
vif = objects.VirtualInterface()
|
||||
vif.tag = 'foo'
|
||||
vif.destroy = mock.MagicMock()
|
||||
mock_get_vif_by_uuid.return_value = vif
|
||||
self.api.deallocate_port_for_instance(mock.sentinel.ctx,
|
||||
mock_inst, '2')
|
||||
mock_unbind.assert_called_once_with(mock.sentinel.ctx, ['2'],
|
||||
mock_client)
|
||||
mock_get_vif_by_uuid.assert_called_once_with(mock.sentinel.ctx, '2')
|
||||
mock_vif.destroy.assert_called_once_with()
|
||||
mock_del_nic_meta.assert_called_once_with(self.api, mock_inst,
|
||||
vif)
|
||||
vif.destroy.assert_called_once_with()
|
||||
|
||||
def test_delete_nic_metadata(self):
|
||||
vif = objects.VirtualInterface(address='aa:bb:cc:dd:ee:ff', tag='foo')
|
||||
instance = fake_instance.fake_instance_obj(self.context)
|
||||
instance.device_metadata = objects.InstanceDeviceMetadata(
|
||||
devices=[objects.NetworkInterfaceMetadata(
|
||||
mac='aa:bb:cc:dd:ee:ff', tag='foo')])
|
||||
instance.save = mock.Mock()
|
||||
self.api._delete_nic_metadata(instance, vif)
|
||||
self.assertEqual(0, len(instance.device_metadata.devices))
|
||||
instance.save.assert_called_once_with()
|
||||
|
||||
@mock.patch('nova.network.neutronv2.api.API.'
|
||||
'_check_external_network_attach')
|
||||
|
Loading…
x
Reference in New Issue
Block a user