Ensure to remove auto delete ports from OFC in NEC plugin
When deleting a network, dhcp ports are removed automatically in db_plugin. This causes a failure network deletion since the corresponding port exists on OFC and the network on OFC cannot be deleted unless a subnet on the network is deleted explicitly. This commit gets auto-delete ports and delete the corresponding ports on the controller before deleting the network. Fixes bug #1190163 Change-Id: Ifffaa1a28b5fac0b0a98036a926550255cc25c9d
This commit is contained in:
parent
08561f35ac
commit
da6816c6c7
@ -24,6 +24,7 @@ from quantum.common import rpc as q_rpc
|
|||||||
from quantum.common import topics
|
from quantum.common import topics
|
||||||
from quantum.db import agents_db
|
from quantum.db import agents_db
|
||||||
from quantum.db import agentschedulers_db
|
from quantum.db import agentschedulers_db
|
||||||
|
from quantum.db import db_base_plugin_v2
|
||||||
from quantum.db import dhcp_rpc_base
|
from quantum.db import dhcp_rpc_base
|
||||||
from quantum.db import extraroute_db
|
from quantum.db import extraroute_db
|
||||||
from quantum.db import l3_gwmode_db
|
from quantum.db import l3_gwmode_db
|
||||||
@ -317,6 +318,15 @@ class NECPluginV2(nec_plugin_base.NECPluginV2Base,
|
|||||||
net = super(NECPluginV2, self).get_network(context, id)
|
net = super(NECPluginV2, self).get_network(context, id)
|
||||||
tenant_id = net['tenant_id']
|
tenant_id = net['tenant_id']
|
||||||
|
|
||||||
|
# Make sure auto-delete ports on OFC are deleted.
|
||||||
|
filter = {'network_id': [id],
|
||||||
|
'device_owner': db_base_plugin_v2.AUTO_DELETE_PORT_OWNERS}
|
||||||
|
auto_delete_ports = self.get_ports(context, filters=filter)
|
||||||
|
for port in auto_delete_ports:
|
||||||
|
LOG.debug(_('delete_network(): deleting auto-delete port'
|
||||||
|
' from OFC: %s'), port)
|
||||||
|
self.deactivate_port(context, port)
|
||||||
|
|
||||||
# get packet_filters associated with the network
|
# get packet_filters associated with the network
|
||||||
if self.packet_filter_enabled:
|
if self.packet_filter_enabled:
|
||||||
filters = dict(network_id=[id])
|
filters = dict(network_id=[id])
|
||||||
|
@ -288,6 +288,13 @@ class TestNecPluginOfcManager(NecPluginV2TestCase):
|
|||||||
super(TestNecPluginOfcManager, self).setUp()
|
super(TestNecPluginOfcManager, self).setUp()
|
||||||
self.ofc = self.plugin.ofc
|
self.ofc = self.plugin.ofc
|
||||||
|
|
||||||
|
def _create_resource(self, resource, data):
|
||||||
|
collection = resource + 's'
|
||||||
|
data = {resource: data}
|
||||||
|
req = self.new_create_request(collection, data)
|
||||||
|
res = self.deserialize(self.fmt, req.get_response(self.api))
|
||||||
|
return res[resource]
|
||||||
|
|
||||||
def _update_resource(self, resource, id, data):
|
def _update_resource(self, resource, id, data):
|
||||||
collection = resource + 's'
|
collection = resource + 's'
|
||||||
data = {resource: data}
|
data = {resource: data}
|
||||||
@ -496,6 +503,39 @@ class TestNecPluginOfcManager(NecPluginV2TestCase):
|
|||||||
]
|
]
|
||||||
self.ofc.assert_has_calls(expected)
|
self.ofc.assert_has_calls(expected)
|
||||||
|
|
||||||
|
def test_delete_network_with_dhcp_port(self):
|
||||||
|
self.ofc.exists_ofc_tenant.return_value = False
|
||||||
|
self.ofc.exists_ofc_port.side_effect = [False, True]
|
||||||
|
|
||||||
|
ctx = mock.ANY
|
||||||
|
with self.network() as network:
|
||||||
|
with self.subnet(network=network):
|
||||||
|
net = network['network']
|
||||||
|
p = self._create_resource('port',
|
||||||
|
{'network_id': net['id'],
|
||||||
|
'tenant_id': net['tenant_id'],
|
||||||
|
'device_owner': 'network:dhcp',
|
||||||
|
'device_id': 'dhcp-port1'})
|
||||||
|
# Make sure that the port is created on OFC.
|
||||||
|
portinfo = {'id': p['id'], 'port_no': 123}
|
||||||
|
self._rpcapi_update_ports(added=[portinfo])
|
||||||
|
# In a case of dhcp port, the port is deleted automatically
|
||||||
|
# when delete_network.
|
||||||
|
|
||||||
|
expected = [
|
||||||
|
mock.call.exists_ofc_tenant(ctx, self._tenant_id),
|
||||||
|
mock.call.create_ofc_tenant(ctx, self._tenant_id),
|
||||||
|
mock.call.create_ofc_network(ctx, self._tenant_id,
|
||||||
|
net['id'], net['name']),
|
||||||
|
mock.call.exists_ofc_port(ctx, p['id']),
|
||||||
|
mock.call.create_ofc_port(ctx, p['id'], mock.ANY),
|
||||||
|
mock.call.exists_ofc_port(ctx, p['id']),
|
||||||
|
mock.call.delete_ofc_port(ctx, p['id'], mock.ANY),
|
||||||
|
mock.call.delete_ofc_network(ctx, net['id'], mock.ANY),
|
||||||
|
mock.call.delete_ofc_tenant(ctx, self._tenant_id)
|
||||||
|
]
|
||||||
|
self.ofc.assert_has_calls(expected)
|
||||||
|
|
||||||
def test_update_port(self):
|
def test_update_port(self):
|
||||||
self._test_update_port_with_admin_state(resource='port')
|
self._test_update_port_with_admin_state(resource='port')
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user