Allow enabling routed networks on undercloud update|upgrade

Since Rocky neutron has support to enable routed networks on
existing an network and subnet if certain conditions are met.
The tripleo undercloud does meet these conditions.

This change updates the extraconfig post script that creates
the neutron ctlplane networks. Any non routed network is
updated to a routed network if 'enable_routed_networks' = True
in the configuration.

Closes-Bug: #1790877
Change-Id: Idf2dd4c158d29b147d48153d3626cf403059d660
This commit is contained in:
Harald Jensås 2018-09-05 15:18:21 +02:00
parent c1bf5d8b10
commit 3892154d5a
2 changed files with 82 additions and 66 deletions

View File

@ -52,12 +52,6 @@ def _ensure_neutron_network(sdk):
provider_physical_network=CONF['physical_network'], provider_physical_network=CONF['physical_network'],
mtu=CONF['mtu']) mtu=CONF['mtu'])
print('INFO: Network created %s' % network) print('INFO: Network created %s' % network)
# (hjensas) Delete the default segment, we create a new segment
# per subnet later.
segments = list(sdk.network.segments(network_id=network.id))
sdk.network.delete_segment(segments[0].id)
print('INFO: Default segment on network %s deleted.' %
network.name)
else: else:
network = sdk.network.update_network( network = sdk.network.update_network(
network[0].id, network[0].id,
@ -131,6 +125,14 @@ def _neutron_subnet_update(sdk, subnet_id, cidr, gateway, host_routes,
raise raise
def _neutron_add_subnet_segment_association(sdk, subnet_id, segment_id):
try:
subnet = sdk.network.update_subnet(subnet_id, segment_id=segment_id)
print('INFO: Segment association added to Subnet %s' % subnet)
except Exception:
print('ERROR: Associationg segment with subnet %s failed.' % subnet_id)
raise
def _neutron_segment_create(sdk, name, network_id, phynet): def _neutron_segment_create(sdk, name, network_id, phynet):
try: try:
segment = sdk.network.create_segment( segment = sdk.network.create_segment(
@ -186,74 +188,76 @@ def _get_segment(sdk, phy, network_id):
return False if not segment else segment[0] return False if not segment else segment[0]
def config_neutron_segments_and_subnets(sdk, ctlplane_id): def _local_neutron_segments_and_subnets(sdk, ctlplane_id):
"""Create's and updates the ctlplane subnet on the segment that is local to
the underclud.
"""
s = CONF['subnets'][CONF['local_subnet']] s = CONF['subnets'][CONF['local_subnet']]
name = CONF['local_subnet']
subnet = _get_subnet(sdk, s['NetworkCidr'], ctlplane_id) subnet = _get_subnet(sdk, s['NetworkCidr'], ctlplane_id)
if subnet and not subnet.segment_id: segment = _get_segment(sdk, CONF['physical_network'], ctlplane_id)
print('WARNING: Local subnet %s already exists and is not associated ' host_routes = [{'destination': '169.254.169.254/32',
'with a network segment. Any additional subnets will be ' 'nexthop': CONF['local_ip']}]
'ignored.' % CONF['local_subnet']) allocation_pool = [{'start': s['DhcpRangeStart'],
host_routes = [{'destination': '169.254.169.254/32', 'end': s['DhcpRangeEnd']}]
'nexthop': CONF['local_ip']}] if subnet:
allocation_pool = [{'start': s['DhcpRangeStart'], if CONF['enable_routed_networks'] and subnet.segment_id == None:
'end': s['DhcpRangeEnd']}] # The subnet exists and does not have a segment association. Since
# routed networks is enabled in the configuration, we need to
# migrate the existing non-routed networks subnet to a routed
# networks subnet by associating the network segment_id with the
# subnet.
_neutron_add_subnet_segment_association(sdk, subnet.id, segment.id)
_neutron_subnet_update( _neutron_subnet_update(
sdk, subnet.id, s['NetworkCidr'], s['NetworkGateway'], host_routes, sdk, subnet.id, s['NetworkCidr'], s['NetworkGateway'], host_routes,
allocation_pool, CONF['local_subnet'], CONF['nameservers']) allocation_pool, name, CONF['nameservers'])
# If the subnet is IPv6 we need to start a router so that router
# advertisments are sent out for stateless IP addressing to work.
if netaddr.IPNetwork(s['NetworkCidr']).version == 6:
_ensure_neutron_router(sdk, CONF['local_subnet'], subnet.id)
else: else:
for name in CONF['subnets']: if CONF['enable_routed_networks']:
s = CONF['subnets'][name] segment_id = segment.id
else:
segment_id = None
subnet = _neutron_subnet_create(
sdk, ctlplane_id, s['NetworkCidr'], s['NetworkGateway'],
host_routes, allocation_pool, name, segment_id,
CONF['nameservers'])
# If the subnet is IPv6 we need to start a router so that router
# advertisments are sent out for stateless IP addressing to work.
if netaddr.IPNetwork(s['NetworkCidr']).version == 6:
_ensure_neutron_router(sdk, name, subnet.id)
phynet = name
metadata_nexthop = s['NetworkGateway']
if name == CONF['local_subnet']:
phynet = CONF['physical_network']
metadata_nexthop = CONF['local_ip']
host_routes = [{'destination': '169.254.169.254/32', def _remote_neutron_segments_and_subnets(sdk, ctlplane_id):
'nexthop': metadata_nexthop}] """Create's and updates the ctlplane subnet(s) on segments that is
allocation_pool = [{'start': s['DhcpRangeStart'], not local to the undercloud.
'end': s['DhcpRangeEnd']}] """
for name in CONF['subnets']:
s = CONF['subnets'][name]
if name == CONF['local_subnet']:
continue
phynet = name
metadata_nexthop = s['NetworkGateway']
host_routes = [{'destination': '169.254.169.254/32',
'nexthop': metadata_nexthop}]
allocation_pool = [{'start': s['DhcpRangeStart'],
'end': s['DhcpRangeEnd']}]
subnet = _get_subnet(sdk, s['NetworkCidr'], ctlplane_id) subnet = _get_subnet(sdk, s['NetworkCidr'], ctlplane_id)
segment = _get_segment(sdk, phynet, ctlplane_id) segment = _get_segment(sdk, phynet, ctlplane_id)
if subnet:
if name == CONF['local_subnet']: _neutron_segment_update(sdk, subnet.segment_id, name)
if ((subnet and not segment) or _neutron_subnet_update(
(subnet and segment and sdk, subnet.id, s['NetworkCidr'], s['NetworkGateway'],
subnet.segment_id != segment.id)): host_routes, allocation_pool, name, CONF['nameservers'])
raise RuntimeError( else:
'The cidr: %s of the local subnet is already used in ' if segment:
'subnet: %s which is associated with segment_id: %s.' % _neutron_segment_update(sdk, segment.id, name)
(s['NetworkCidr'], subnet.id, subnet.segment_id))
if subnet:
_neutron_segment_update(sdk, subnet.segment_id, name)
_neutron_subnet_update(
sdk, subnet.id, s['NetworkCidr'], s['NetworkGateway'],
host_routes, allocation_pool, name, CONF['nameservers'])
else: else:
if segment: segment = _neutron_segment_create(sdk, name, ctlplane_id,
_neutron_segment_update(sdk, segment.id, name) phynet)
else: subnet = _neutron_subnet_create(
segment = _neutron_segment_create(sdk, name, sdk, ctlplane_id, s['NetworkCidr'], s['NetworkGateway'],
ctlplane_id, phynet) host_routes, allocation_pool, name, segment.id,
CONF['nameservers'])
if CONF['enable_routed_networks']:
subnet = _neutron_subnet_create(
sdk, ctlplane_id, s['NetworkCidr'],
s['NetworkGateway'], host_routes, allocation_pool,
name, segment.id, CONF['nameservers'])
else:
subnet = _neutron_subnet_create(
sdk, ctlplane_id, s['NetworkCidr'],
s['NetworkGateway'], host_routes, allocation_pool,
name, None, CONF['nameservers'])
# If the subnet is IPv6 we need to start a router so that router # If the subnet is IPv6 we need to start a router so that router
# advertisments are sent out for stateless IP addressing to work. # advertisments are sent out for stateless IP addressing to work.
if netaddr.IPNetwork(s['NetworkCidr']).version == 6: if netaddr.IPNetwork(s['NetworkCidr']).version == 6:
@ -273,4 +277,9 @@ else:
user_domain_name='Default') user_domain_name='Default')
network = _ensure_neutron_network(sdk) network = _ensure_neutron_network(sdk)
config_neutron_segments_and_subnets(sdk, network.id) # Always create/update the local_subnet first to ensure it is can have the
# subnet associated with a segment prior to creating the remote subnets if
# the user enabled routed networks support on undercloud update.
_local_neutron_segments_and_subnets(sdk, network.id)
if CONF['enable_routed_networks']:
_remote_neutron_segments_and_subnets(sdk, network.id)

View File

@ -0,0 +1,7 @@
---
features:
- |
It is now possible to enable support for routed networks in the undercloud
when the undercloud is updated or upgraded. To enable support for routed
networks set ``enable_routed_networks`` to ``True`` in ``undercloud.conf``
and re-run the undercloud installer.