NSX migration fix nosnat + keep ips
Few improvments to the nsx migrations: - support no-snat routers - keep the original ips of routers gw & interfaces - catch errors in floating ips creation Change-Id: I73aacc26a013f45bcb2e857d19e505a20ddd37a1
This commit is contained in:
parent
66935845a3
commit
92246b7f19
@ -65,8 +65,8 @@ class ApiReplayClient(object):
|
|||||||
# Migrate all the objects
|
# Migrate all the objects
|
||||||
self.migrate_security_groups()
|
self.migrate_security_groups()
|
||||||
self.migrate_qos_policies()
|
self.migrate_qos_policies()
|
||||||
routers_routes = self.migrate_routers()
|
routers_routes, routers_gw_info = self.migrate_routers()
|
||||||
self.migrate_networks_subnets_ports()
|
self.migrate_networks_subnets_ports(routers_gw_info)
|
||||||
self.migrate_floatingips()
|
self.migrate_floatingips()
|
||||||
self.migrate_routers_routes(routers_routes)
|
self.migrate_routers_routes(routers_routes)
|
||||||
|
|
||||||
@ -281,6 +281,7 @@ class ApiReplayClient(object):
|
|||||||
Also return a dictionary of the routes that should be added to
|
Also return a dictionary of the routes that should be added to
|
||||||
each router. Static routes must be added later, after the router
|
each router. Static routes must be added later, after the router
|
||||||
ports are set.
|
ports are set.
|
||||||
|
And return a dictionary of external gateway info per router
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
source_routers = self.source_neutron.list_routers()['routers']
|
source_routers = self.source_neutron.list_routers()['routers']
|
||||||
@ -290,6 +291,18 @@ class ApiReplayClient(object):
|
|||||||
|
|
||||||
dest_routers = self.dest_neutron.list_routers()['routers']
|
dest_routers = self.dest_neutron.list_routers()['routers']
|
||||||
update_routes = {}
|
update_routes = {}
|
||||||
|
gw_info = {}
|
||||||
|
|
||||||
|
drop_router_fields = self.basic_ignore_fields + [
|
||||||
|
'status',
|
||||||
|
'routes',
|
||||||
|
'ha',
|
||||||
|
'external_gateway_info',
|
||||||
|
'router_type',
|
||||||
|
'availability_zone_hints',
|
||||||
|
'availability_zones',
|
||||||
|
'distributed',
|
||||||
|
'flavor_id']
|
||||||
|
|
||||||
for router in source_routers:
|
for router in source_routers:
|
||||||
dest_router = self.have_id(router['id'], dest_routers)
|
dest_router = self.have_id(router['id'], dest_routers)
|
||||||
@ -297,22 +310,15 @@ class ApiReplayClient(object):
|
|||||||
if router.get('routes'):
|
if router.get('routes'):
|
||||||
update_routes[router['id']] = router['routes']
|
update_routes[router['id']] = router['routes']
|
||||||
|
|
||||||
drop_router_fields = self.basic_ignore_fields + [
|
if router.get('external_gateway_info'):
|
||||||
'status',
|
gw_info[router['id']] = router['external_gateway_info']
|
||||||
'routes',
|
|
||||||
'ha',
|
|
||||||
'external_gateway_info',
|
|
||||||
'router_type',
|
|
||||||
'availability_zone_hints',
|
|
||||||
'availability_zones',
|
|
||||||
'distributed',
|
|
||||||
'flavor_id']
|
|
||||||
body = self.drop_fields(router, drop_router_fields)
|
body = self.drop_fields(router, drop_router_fields)
|
||||||
self.fix_description(body)
|
self.fix_description(body)
|
||||||
new_router = (self.dest_neutron.create_router(
|
new_router = (self.dest_neutron.create_router(
|
||||||
{'router': body}))
|
{'router': body}))
|
||||||
print("created router %s" % new_router)
|
print("created router %s" % new_router)
|
||||||
return update_routes
|
return update_routes, gw_info
|
||||||
|
|
||||||
def migrate_routers_routes(self, routers_routes):
|
def migrate_routers_routes(self, routers_routes):
|
||||||
"""Add static routes to the created routers."""
|
"""Add static routes to the created routers."""
|
||||||
@ -393,7 +399,7 @@ class ApiReplayClient(object):
|
|||||||
print('Public network ' + body['id'] +
|
print('Public network ' + body['id'] +
|
||||||
'was set to non default network')
|
'was set to non default network')
|
||||||
|
|
||||||
def migrate_networks_subnets_ports(self):
|
def migrate_networks_subnets_ports(self, routers_gw_info):
|
||||||
"""Migrates networks/ports/router-uplinks from src to dest neutron."""
|
"""Migrates networks/ports/router-uplinks from src to dest neutron."""
|
||||||
source_ports = self.source_neutron.list_ports()['ports']
|
source_ports = self.source_neutron.list_ports()['ports']
|
||||||
source_subnets = self.source_neutron.list_subnets()['subnets']
|
source_subnets = self.source_neutron.list_subnets()['subnets']
|
||||||
@ -497,12 +503,20 @@ class ApiReplayClient(object):
|
|||||||
# only create port if the dest server doesn't have it
|
# only create port if the dest server doesn't have it
|
||||||
if self.have_id(port['id'], dest_ports) is False:
|
if self.have_id(port['id'], dest_ports) is False:
|
||||||
if port['device_owner'] == 'network:router_gateway':
|
if port['device_owner'] == 'network:router_gateway':
|
||||||
body = {
|
router_id = port['device_id']
|
||||||
|
enable_snat = True
|
||||||
|
if router_id in routers_gw_info:
|
||||||
|
# keep the original snat status of the router
|
||||||
|
enable_snat = routers_gw_info[router_id].get(
|
||||||
|
'enable_snat', True)
|
||||||
|
rtr_body = {
|
||||||
"external_gateway_info":
|
"external_gateway_info":
|
||||||
{"network_id": port['network_id']}}
|
{"network_id": port['network_id'],
|
||||||
|
"enable_snat": enable_snat,
|
||||||
|
# keep the original GW IP
|
||||||
|
"external_fixed_ips": port.get('fixed_ips')}}
|
||||||
router_uplink = self.dest_neutron.update_router(
|
router_uplink = self.dest_neutron.update_router(
|
||||||
port['device_id'], # router_id
|
router_id, {'router': rtr_body})
|
||||||
{'router': body})
|
|
||||||
print("Uplinked router %s" % router_uplink)
|
print("Uplinked router %s" % router_uplink)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -517,12 +531,18 @@ class ApiReplayClient(object):
|
|||||||
if (port['device_owner'] == 'network:router_interface' and
|
if (port['device_owner'] == 'network:router_interface' and
|
||||||
created_subnet is not None):
|
created_subnet is not None):
|
||||||
try:
|
try:
|
||||||
# uplink router_interface ports
|
# uplink router_interface ports by creating the
|
||||||
|
# port, and attaching it to the router
|
||||||
|
router_id = port['device_id']
|
||||||
|
del body['device_owner']
|
||||||
|
del body['device_id']
|
||||||
|
created_port = self.dest_neutron.create_port(
|
||||||
|
{'port': body})['port']
|
||||||
self.dest_neutron.add_interface_router(
|
self.dest_neutron.add_interface_router(
|
||||||
port['device_id'],
|
router_id,
|
||||||
{'subnet_id': created_subnet['id']})
|
{'port_id': created_port['id']})
|
||||||
print("Uplinked router %s to subnet %s" %
|
print("Uplinked router %s to subnet %s" %
|
||||||
(port['device_id'], created_subnet['id']))
|
(router_id, created_subnet['id']))
|
||||||
continue
|
continue
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# NOTE(arosen): this occurs here if you run the
|
# NOTE(arosen): this occurs here if you run the
|
||||||
@ -547,9 +567,14 @@ class ApiReplayClient(object):
|
|||||||
# L3 might be disabled in the source
|
# L3 might be disabled in the source
|
||||||
source_fips = []
|
source_fips = []
|
||||||
|
|
||||||
drop_fip_fields = ['status', 'router_id', 'id', 'revision']
|
drop_fip_fields = self.basic_ignore_fields + [
|
||||||
|
'status', 'router_id', 'id', 'revision']
|
||||||
|
|
||||||
for source_fip in source_fips:
|
for source_fip in source_fips:
|
||||||
body = self.drop_fields(source_fip, drop_fip_fields)
|
body = self.drop_fields(source_fip, drop_fip_fields)
|
||||||
fip = self.dest_neutron.create_floatingip({'floatingip': body})
|
try:
|
||||||
print("Created floatingip %s" % fip)
|
fip = self.dest_neutron.create_floatingip({'floatingip': body})
|
||||||
|
print("Created floatingip %s" % fip)
|
||||||
|
except Exception as e:
|
||||||
|
print("Failed to create floating ip (%s) : %s" %
|
||||||
|
(source_fip, str(e)))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user