Fix OS::Neutron::ExtraRoute delete with IPv6

currently Heat sets the resource_id of the ExtraRoute resource to
`<router_id>:<destination>:<nexthop>`
and later parses destination and nexthop out from resource_id on delete
of the resource.
However colon is an integral part of IPv6 addresses, so such parsing
fails in this case.

In this patch we use actual resource properties to find
router_id, destination and nexthop, thus avoiding the parsing error.

Change-Id: I6835efc632c38aac3466d3952f8887ef15dbd0ad
Story: 2007085
Task: 38080
This commit is contained in:
Pavlo Shchelokovskyy 2020-01-13 13:42:05 +02:00 committed by Pavlo Shchelokovskyy
parent 7b65b78c95
commit 9ed61fc666
2 changed files with 46 additions and 18 deletions

View File

@ -111,13 +111,15 @@ class ExtraRoute(neutron.NeutronResource):
def handle_delete(self):
if not self.resource_id:
return
(router_id, destination, nexthop) = self.resource_id.split(':')
router_id = self.properties[self.ROUTER_ID]
with self.client_plugin().ignore_not_found:
routes = self.client().show_router(
router_id).get('router').get('routes', [])
try:
routes.remove({'destination': destination,
'nexthop': nexthop})
routes.remove(
{'destination': self.properties[self.DESTINATION],
'nexthop': self.properties[self.NEXTHOP]}
)
except ValueError:
return
self.client().update_router(router_id,

View File

@ -74,11 +74,18 @@ class NeutronExtraRouteTest(common.HeatTestCase):
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
def test_extraroute(self):
route1 = {"destination": "192.168.0.0/24",
"nexthop": "1.1.1.1"}
route2 = {"destination": "192.168.255.0/24",
"nexthop": "1.1.1.1"}
def _test_extraroute(self, ipv6=False):
if ipv6:
route1 = {"destination": "ffff:f53b:82e4::56/46",
"nexthop": "dce7:f53b:82e4::56"}
route2 = {"destination": "ffff:f53b:ffff::56/46",
"nexthop": "dce7:f53b:82e4::56"}
else:
route1 = {"destination": "192.168.0.0/24",
"nexthop": "1.1.1.1"}
route2 = {"destination": "192.168.255.0/24",
"nexthop": "1.1.1.1"}
self.stub_RouterConstraint_validate()
@ -97,17 +104,30 @@ class NeutronExtraRouteTest(common.HeatTestCase):
t = template_format.parse(neutron_template)
stack = utils.parse_stack(t)
rsrc1 = self.create_extraroute(
t, stack, 'extraroute1', properties={
'router_id': '3e46229d-8fce-4733-819a-b5fe630550f8',
'destination': '192.168.0.0/24',
'nexthop': '1.1.1.1'})
if ipv6:
rsrc1 = self.create_extraroute(
t, stack, 'extraroute1', properties={
'router_id': '3e46229d-8fce-4733-819a-b5fe630550f8',
'destination': 'ffff:f53b:82e4::56/46',
'nexthop': 'dce7:f53b:82e4::56'})
self.create_extraroute(
t, stack, 'extraroute2', properties={
'router_id': '3e46229d-8fce-4733-819a-b5fe630550f8',
'destination': '192.168.255.0/24',
'nexthop': '1.1.1.1'})
self.create_extraroute(
t, stack, 'extraroute2', properties={
'router_id': '3e46229d-8fce-4733-819a-b5fe630550f8',
'destination': 'ffff:f53b:ffff::56/46',
'nexthop': 'dce7:f53b:82e4::56'})
else:
rsrc1 = self.create_extraroute(
t, stack, 'extraroute1', properties={
'router_id': '3e46229d-8fce-4733-819a-b5fe630550f8',
'destination': '192.168.0.0/24',
'nexthop': '1.1.1.1'})
self.create_extraroute(
t, stack, 'extraroute2', properties={
'router_id': '3e46229d-8fce-4733-819a-b5fe630550f8',
'destination': '192.168.255.0/24',
'nexthop': '1.1.1.1'})
scheduler.TaskRunner(rsrc1.delete)()
rsrc1.state_set(rsrc1.CREATE, rsrc1.COMPLETE, 'to delete again')
@ -127,3 +147,9 @@ class NeutronExtraRouteTest(common.HeatTestCase):
mock.call('3e46229d-8fce-4733-819a-b5fe630550f8',
{'router': {'routes': [route2.copy()]}}),
])
def test_extraroute_ipv4(self):
self._test_extraroute(ipv6=False)
def test_extraroute_ipv6(self):
self._test_extraroute(ipv6=True)