Pre-created port clean during subnet deletion
1. What is the problem Before creating bottom subnet, we need to create some ports to allocate ip address for bottom dhcp port and bottom gateway port. These pre-created ports are not deleted after bottom resources are deleted. 2. What is the solution to the problem Clean these pre-created ports during top subnet deletion. 3. What the features need to be implemented to the Tricircle to realize the solution Pre-created ports now can be cleaned up. Change-Id: I73c0ef87e4104f1db9926a5972c5f36be94d724a
This commit is contained in:
parent
85df9c9c5f
commit
a0482b8eb6
|
@ -121,6 +121,21 @@ def get_bottom_mappings_by_top_id(context, top_id, resource_type):
|
|||
return mappings
|
||||
|
||||
|
||||
def delete_pre_created_resource_mapping(context, name):
|
||||
with context.session.begin():
|
||||
entries = core.query_resource(
|
||||
context, models.ResourceRouting,
|
||||
filters=[{'key': 'top_id', 'comparator': 'eq',
|
||||
'value': name}], sorts=[])
|
||||
if entries:
|
||||
core.delete_resources(
|
||||
context, models.ResourceRouting,
|
||||
filters=[{'key': 'top_id', 'comparator': 'eq',
|
||||
'value': entries[0]['bottom_id']}])
|
||||
core.delete_resource(context, models.ResourceRouting,
|
||||
entries[0]['id'])
|
||||
|
||||
|
||||
def get_bottom_id_by_top_id_pod_name(context, top_id, pod_name, resource_type):
|
||||
"""Get resource bottom id by top id and bottom pod name
|
||||
|
||||
|
|
|
@ -335,6 +335,13 @@ class TricirclePlugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||
context, res, network, res['id'])
|
||||
return res
|
||||
|
||||
def _delete_pre_created_port(self, t_ctx, q_ctx, port_name):
|
||||
ports = super(TricirclePlugin, self).get_ports(
|
||||
q_ctx, {'name': [port_name]})
|
||||
if ports:
|
||||
super(TricirclePlugin, self).delete_port(q_ctx, ports[0]['id'])
|
||||
db_api.delete_pre_created_resource_mapping(t_ctx, port_name)
|
||||
|
||||
def delete_subnet(self, context, subnet_id):
|
||||
t_ctx = t_context.get_context_from_neutron_context(context)
|
||||
try:
|
||||
|
@ -345,6 +352,9 @@ class TricirclePlugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||
bottom_subnet_id = mapping[1]
|
||||
self._get_client(pod_name).delete_subnets(
|
||||
t_ctx, bottom_subnet_id)
|
||||
interface_name = t_constants.interface_port_name % (
|
||||
mapping[0]['pod_id'], subnet_id)
|
||||
self._delete_pre_created_port(t_ctx, context, interface_name)
|
||||
with t_ctx.session.begin():
|
||||
core.delete_resources(
|
||||
t_ctx, models.ResourceRouting,
|
||||
|
@ -354,6 +364,8 @@ class TricirclePlugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||
'value': mapping[0]['pod_id']}])
|
||||
except Exception:
|
||||
raise
|
||||
dhcp_port_name = t_constants.dhcp_port_name % subnet_id
|
||||
self._delete_pre_created_port(t_ctx, context, dhcp_port_name)
|
||||
super(TricirclePlugin, self).delete_subnet(context, subnet_id)
|
||||
|
||||
def update_subnet(self, context, subnet_id, subnet):
|
||||
|
|
|
@ -341,6 +341,18 @@ class FakeClient(object):
|
|||
ret_list.append(res)
|
||||
return ret_list
|
||||
|
||||
def delete_resources(self, _type, ctx, _id):
|
||||
index = -1
|
||||
if self.pod_name == 'top':
|
||||
res_list = self._res_map[self.pod_name][_type + 's']
|
||||
else:
|
||||
res_list = self._res_map[self.pod_name][_type]
|
||||
for i, res in enumerate(res_list):
|
||||
if res['id'] == _id:
|
||||
index = i
|
||||
if index != -1:
|
||||
del res_list[index]
|
||||
|
||||
def list_networks(self, ctx, filters=None):
|
||||
networks = self.list_resources('network', ctx, filters)
|
||||
if self.pod_name != 'top':
|
||||
|
@ -363,6 +375,9 @@ class FakeClient(object):
|
|||
'comparator': 'eq',
|
||||
'value': subnet_id}])[0]
|
||||
|
||||
def delete_subnets(self, ctx, subnet_id):
|
||||
self.delete_resources('subnet', ctx, subnet_id)
|
||||
|
||||
def update_subnets(self, ctx, subnet_id, body):
|
||||
pass
|
||||
|
||||
|
@ -383,16 +398,7 @@ class FakeClient(object):
|
|||
'', params={'filters': {'id': [port_id]}})['ports'][0]
|
||||
|
||||
def delete_ports(self, ctx, port_id):
|
||||
index = -1
|
||||
if self.pod_name == 'top':
|
||||
port_list = self._res_map[self.pod_name]['ports']
|
||||
else:
|
||||
port_list = self._res_map[self.pod_name]['port']
|
||||
for i, port in enumerate(port_list):
|
||||
if port['id'] == port_id:
|
||||
index = i
|
||||
if index != -1:
|
||||
del port_list[index]
|
||||
self.delete_resources('port', ctx, port_id)
|
||||
|
||||
def add_gateway_routers(self, ctx, *args, **kwargs):
|
||||
# only for mock purpose
|
||||
|
@ -797,7 +803,7 @@ class FakeSession(object):
|
|||
RES_MAP[model_obj.__tablename__].append(model_dict)
|
||||
|
||||
def _cascade_delete(self, model_dict, foreign_key, table, key):
|
||||
if foreign_key not in model_dict:
|
||||
if key not in model_dict:
|
||||
return
|
||||
index = -1
|
||||
for i, instance in enumerate(RES_MAP[table]):
|
||||
|
@ -1383,6 +1389,46 @@ class PluginTest(unittest.TestCase,
|
|||
|
||||
return t_net_id, t_subnet_id, t_router_id, b_net_id, b_subnet_id
|
||||
|
||||
@patch.object(driver.Pool, 'get_instance', new=fake_get_instance)
|
||||
@patch.object(ipam_pluggable_backend.IpamPluggableBackend,
|
||||
'_allocate_ips_for_port', new=fake_allocate_ips_for_port)
|
||||
@patch.object(db_base_plugin_common.DbBasePluginCommon,
|
||||
'_make_subnet_dict', new=fake_make_subnet_dict)
|
||||
@patch.object(context, 'get_context_from_neutron_context')
|
||||
def test_subnet_clean(self, mock_context):
|
||||
self._basic_pod_route_setup()
|
||||
|
||||
fake_plugin = FakePlugin()
|
||||
q_ctx = FakeNeutronContext()
|
||||
t_ctx = context.get_db_context()
|
||||
mock_context.return_value = t_ctx
|
||||
|
||||
tenant_id = 'test_tenant_id'
|
||||
(t_net_id, t_subnet_id,
|
||||
t_router_id, b_net_id, b_subnet_id) = self._prepare_router_test(
|
||||
tenant_id, t_ctx, 'pod_1', 1)
|
||||
t_port_id = fake_plugin.add_router_interface(
|
||||
q_ctx, t_router_id, {'subnet_id': t_subnet_id})['port_id']
|
||||
_, b_router_id = db_api.get_bottom_mappings_by_top_id(
|
||||
t_ctx, t_router_id, constants.RT_ROUTER)[0]
|
||||
|
||||
port_num = len(TOP_PORTS)
|
||||
pre_created_port_num = 0
|
||||
for port in TOP_PORTS:
|
||||
if port.get('name').startswith('dhcp_port_'):
|
||||
pre_created_port_num += 1
|
||||
elif port.get('name').startswith('interface_'):
|
||||
pre_created_port_num += 1
|
||||
elif port.get('device_owner') == 'network:router_interface':
|
||||
pre_created_port_num += 1
|
||||
|
||||
fake_plugin.remove_router_interface(
|
||||
q_ctx, t_router_id, {'port_id': t_port_id})
|
||||
fake_plugin.delete_subnet(q_ctx, t_subnet_id)
|
||||
|
||||
# check pre-created ports are all deleted
|
||||
self.assertEqual(port_num - pre_created_port_num, len(TOP_PORTS))
|
||||
|
||||
@patch.object(driver.Pool, 'get_instance', new=fake_get_instance)
|
||||
@patch.object(ipam_pluggable_backend.IpamPluggableBackend,
|
||||
'_allocate_ips_for_port', new=fake_allocate_ips_for_port)
|
||||
|
@ -1591,7 +1637,6 @@ class PluginTest(unittest.TestCase,
|
|||
'_allocate_ips_for_port', new=fake_allocate_ips_for_port)
|
||||
@patch.object(db_base_plugin_common.DbBasePluginCommon,
|
||||
'_make_subnet_dict', new=fake_make_subnet_dict)
|
||||
@patch.object(FakeRPCAPI, 'configure_extra_routes', new=mock.Mock)
|
||||
@patch.object(FakeClient, 'action_routers')
|
||||
@patch.object(context, 'get_context_from_neutron_context')
|
||||
def test_add_interface_exception(self, mock_context, mock_action):
|
||||
|
@ -1649,7 +1694,6 @@ class PluginTest(unittest.TestCase,
|
|||
'_allocate_ips_for_port', new=fake_allocate_ips_for_port)
|
||||
@patch.object(db_base_plugin_common.DbBasePluginCommon,
|
||||
'_make_subnet_dict', new=fake_make_subnet_dict)
|
||||
@patch.object(FakeBaseRPCAPI, 'configure_extra_routes', new=mock.Mock)
|
||||
@patch.object(FakeClient, '_get_connection')
|
||||
@patch.object(context, 'get_context_from_neutron_context')
|
||||
def test_add_interface_exception_port_left(self, mock_context,
|
||||
|
|
Loading…
Reference in New Issue