V2T migration: update network segment with vni
1. NSX|V admin utils: Add utility to list virtual wires 2. Add network vni field to the api_repaly extension 3. Let policy plugin set the vni value on the new segment while working in api-replay mode. Change-Id: I872edd03cdd1a7ff1422cdc12ea2a1d75b5d0bcb
This commit is contained in:
parent
7b332c1dc0
commit
c9b15c39ce
|
@ -237,6 +237,12 @@ Portgroups
|
|||
|
||||
nsxadmin -r nsx-portgroups -o nsx-cleanup <--force>
|
||||
|
||||
VirtualWires
|
||||
~~~~~~~~~~~~
|
||||
- List all NSX virtual wires with their neutron id and vni::
|
||||
|
||||
nsxadmin -r nsx-virtualwires -o list (--property map-file=<filename>)
|
||||
|
||||
Security Groups, Firewall and Spoofguard
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ class ApiReplayCli(object):
|
|||
octavia_os_auth_url=args.octavia_os_auth_url,
|
||||
neutron_conf=args.neutron_conf,
|
||||
ext_net_map=args.external_networks_map,
|
||||
net_vni_map=args.networks_vni_map,
|
||||
logfile=args.logfile,
|
||||
max_retry=args.max_retry,
|
||||
cert_file=args.cert_file)
|
||||
|
@ -181,6 +182,10 @@ class ApiReplayCli(object):
|
|||
"--external-networks-map",
|
||||
help="Path to a json file mapping external network neutron ID "
|
||||
"to tier0 ID.")
|
||||
parser.add_argument(
|
||||
"--networks-vni-map",
|
||||
help="Path to a json file mapping neutron network ID to its "
|
||||
"backend vni.")
|
||||
|
||||
parser.add_argument(
|
||||
"--max-retry",
|
||||
|
|
|
@ -57,7 +57,7 @@ class ApiReplayClient(utils.PrepareObjectForMigration):
|
|||
octavia_os_username, octavia_os_user_domain_id,
|
||||
octavia_os_tenant_name, octavia_os_tenant_domain_id,
|
||||
octavia_os_password, octavia_os_auth_url,
|
||||
neutron_conf, ext_net_map, logfile, max_retry,
|
||||
neutron_conf, ext_net_map, net_vni_map, logfile, max_retry,
|
||||
cert_file):
|
||||
|
||||
# Init config and logging
|
||||
|
@ -132,6 +132,13 @@ class ApiReplayClient(utils.PrepareObjectForMigration):
|
|||
else:
|
||||
self.ext_net_map = None
|
||||
|
||||
if net_vni_map:
|
||||
with open(net_vni_map, 'r') as myfile:
|
||||
data = myfile.read()
|
||||
self.net_vni_map = jsonutils.loads(data)
|
||||
else:
|
||||
self.net_vni_map = None
|
||||
|
||||
LOG.info("Starting NSX migration to %s.", self.dest_plugin)
|
||||
# Migrate all the objects
|
||||
self.migrate_security_groups()
|
||||
|
@ -507,7 +514,8 @@ class ApiReplayClient(utils.PrepareObjectForMigration):
|
|||
body = self.prepare_network(
|
||||
network, remove_qos=remove_qos,
|
||||
dest_default_public_net=dest_default_public_net,
|
||||
dest_azs=dest_azs, ext_net_map=self.ext_net_map)
|
||||
dest_azs=dest_azs, ext_net_map=self.ext_net_map,
|
||||
net_vni_map=self.net_vni_map)
|
||||
|
||||
# only create network if the dest server doesn't have it
|
||||
if self.have_id(network['id'], dest_networks):
|
||||
|
@ -516,10 +524,11 @@ class ApiReplayClient(utils.PrepareObjectForMigration):
|
|||
continue
|
||||
|
||||
# Ignore internal NSXV objects
|
||||
if network['project_id'] == nsxv_constants.INTERNAL_TENANT_ID:
|
||||
LOG.info("Skip network %s: Internal NSX-V network",
|
||||
network['id'])
|
||||
continue
|
||||
# TODO(asarfaty) - temporarily migrate those as well
|
||||
# if network['project_id'] == nsxv_constants.INTERNAL_TENANT_ID:
|
||||
# LOG.info("Skip network %s: Internal NSX-V network",
|
||||
# network['id'])
|
||||
# continue
|
||||
|
||||
try:
|
||||
created_net = self.dest_neutron.create_network(
|
||||
|
|
|
@ -165,7 +165,7 @@ class PrepareObjectForMigration(object):
|
|||
|
||||
def prepare_network(self, net, dest_default_public_net=True,
|
||||
remove_qos=False, dest_azs=None, direct_call=False,
|
||||
ext_net_map=None):
|
||||
ext_net_map=None, net_vni_map=None):
|
||||
self.fix_description(net)
|
||||
body = self.drop_fields(net, self.drop_network_fields)
|
||||
|
||||
|
@ -229,6 +229,10 @@ class PrepareObjectForMigration(object):
|
|||
body['availability_zone_hints'] = []
|
||||
elif direct_call:
|
||||
body['availability_zone_hints'] = []
|
||||
|
||||
if net_vni_map and body['id'] in net_vni_map:
|
||||
body['vni'] = net_vni_map[body['id']]
|
||||
|
||||
return body
|
||||
|
||||
def prepare_subnet(self, subnet, direct_call=False):
|
||||
|
|
|
@ -15,7 +15,9 @@
|
|||
# under the License.
|
||||
#
|
||||
|
||||
from neutron_lib.api import converters
|
||||
from neutron_lib.api import extensions
|
||||
from neutron_lib import constants
|
||||
from neutron_lib.db import constants as db_const
|
||||
|
||||
|
||||
|
@ -36,6 +38,10 @@ RESOURCE_ATTRIBUTE_MAP = {
|
|||
},
|
||||
'networks': {
|
||||
'id': ID_WITH_POST,
|
||||
'vni': {'allow_post': True, 'allow_put': False,
|
||||
'default': constants.ATTR_NOT_SPECIFIED,
|
||||
'convert_to': converters.convert_to_int_if_not_none,
|
||||
'is_visible': True},
|
||||
},
|
||||
'subnets': {
|
||||
'id': ID_WITH_POST,
|
||||
|
|
|
@ -601,8 +601,8 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
|
|||
network['id'])
|
||||
|
||||
def _create_network_on_backend(self, context, net_data,
|
||||
transparent_vlan,
|
||||
provider_data, az):
|
||||
transparent_vlan, provider_data, az,
|
||||
request_data):
|
||||
net_data['id'] = net_data.get('id') or uuidutils.generate_uuid()
|
||||
|
||||
# update the network name to indicate the neutron id too.
|
||||
|
@ -642,6 +642,10 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
|
|||
if az.use_policy_md:
|
||||
kwargs['metadata_proxy_id'] = az._native_md_proxy_uuid
|
||||
|
||||
# Set the segment vni for nsx-v portgroups migration
|
||||
if request_data.get('vni') and cfg.CONF.api_replay_mode:
|
||||
kwargs['overlay_id'] = request_data['vni']
|
||||
|
||||
self.nsxpolicy.segment.create_or_overwrite(
|
||||
net_name, **kwargs)
|
||||
|
||||
|
@ -755,7 +759,7 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
|
|||
if is_backend_network:
|
||||
try:
|
||||
self._create_network_on_backend(
|
||||
context, created_net, vlt, provider_data, az)
|
||||
context, created_net, vlt, provider_data, az, net_data)
|
||||
except Exception as e:
|
||||
LOG.exception("Failed to create NSX network network: %s", e)
|
||||
with excutils.save_and_reraise_exception():
|
||||
|
|
|
@ -520,6 +520,11 @@ class Vcns(object):
|
|||
uri = '/api/2.0/vdn/virtualwires/%s' % virtualwire_id
|
||||
return self.do_request(HTTP_DELETE, uri, format='xml')
|
||||
|
||||
def get_virtual_wires(self):
|
||||
"""Deletes a virtual wire."""
|
||||
uri = '/api/2.0/vdn/virtualwires'
|
||||
return self.do_request(HTTP_GET, uri)
|
||||
|
||||
def create_port_group(self, dvs_id, request):
|
||||
"""Creates a port group on a DVS
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ BGP_GW_EDGE = 'bgp-gw-edge'
|
|||
ROUTING_REDIS_RULE = 'routing-redistribution-rule'
|
||||
BGP_NEIGHBOUR = 'bgp-neighbour'
|
||||
NSX_PORTGROUPS = 'nsx-portgroups'
|
||||
NSX_VIRTUALWIRES = 'nsx-virtualwires'
|
||||
NSX_MIGRATE_V_T = 'nsx-migrate-v2t'
|
||||
|
||||
# NSXTV only Resource Constants
|
||||
|
|
|
@ -42,6 +42,17 @@ def get_networks_from_backend():
|
|||
return et.fromstring(so_list)
|
||||
|
||||
|
||||
def get_virtual_wires():
|
||||
"""Return a hash of the backend virtual wires by their id"""
|
||||
nsxv = utils.get_nsxv_client()
|
||||
h, res = nsxv.get_virtual_wires()
|
||||
vw_list = res['dataPage']['data']
|
||||
vw_hash = {}
|
||||
for vw in vw_list:
|
||||
vw_hash[vw['objectId']] = vw
|
||||
return vw_hash
|
||||
|
||||
|
||||
def get_networks():
|
||||
"""Create an array of all the backend networks and their data
|
||||
"""
|
||||
|
@ -294,6 +305,41 @@ def get_dvs_id_from_backend_name(backend_name):
|
|||
return reg.group(0)
|
||||
|
||||
|
||||
@admin_utils.output_header
|
||||
def list_nsx_virtual_wires(resource, event, trigger, **kwargs):
|
||||
filename = None
|
||||
if kwargs.get('property'):
|
||||
properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
|
||||
filename = properties.get('map-file')
|
||||
|
||||
vws = get_virtual_wires()
|
||||
table_results = []
|
||||
map_results = {}
|
||||
admin_context = context.get_admin_context()
|
||||
with utils.NsxVPluginWrapper() as plugin:
|
||||
neutron_networks = plugin.get_networks(admin_context, fields=['id'])
|
||||
for net in neutron_networks:
|
||||
# get the nsx id:
|
||||
net_morefs = nsx_db.get_nsx_switch_ids(admin_context.session,
|
||||
net['id'])
|
||||
for moref in net_morefs:
|
||||
if not moref.startswith('virtualwire'):
|
||||
continue
|
||||
vni = vws.get(moref, {}).get('vdnId')
|
||||
table_results.append({'neutron_id': net['id'],
|
||||
'nsx_id': moref,
|
||||
'vni': vni})
|
||||
map_results[net['id']] = vni
|
||||
LOG.info(formatters.output_formatter(constants.NSX_VIRTUALWIRES,
|
||||
table_results,
|
||||
['neutron_id', 'nsx_id', 'vni']))
|
||||
if filename:
|
||||
f = open(filename, "a")
|
||||
f.write("%s" % map_results)
|
||||
f.close()
|
||||
LOG.info("Mapping data saved into %s", filename)
|
||||
|
||||
|
||||
@admin_utils.output_header
|
||||
def delete_backend_network(resource, event, trigger, **kwargs):
|
||||
"""Delete a backend network by its moref
|
||||
|
@ -366,3 +412,6 @@ registry.subscribe(list_nsx_portgroups,
|
|||
registry.subscribe(delete_nsx_portgroups,
|
||||
constants.NSX_PORTGROUPS,
|
||||
shell.Operations.NSX_CLEAN.value)
|
||||
registry.subscribe(list_nsx_virtual_wires,
|
||||
constants.NSX_VIRTUALWIRES,
|
||||
shell.Operations.LIST.value)
|
||||
|
|
|
@ -209,6 +209,8 @@ nsxv_resources = {
|
|||
constants.NSX_PORTGROUPS: Resource(constants.NSX_PORTGROUPS,
|
||||
[Operations.LIST.value,
|
||||
Operations.NSX_CLEAN.value]),
|
||||
constants.NSX_VIRTUALWIRES: Resource(constants.NSX_VIRTUALWIRES,
|
||||
[Operations.LIST.value]),
|
||||
constants.SECURITY_GROUPS: Resource(constants.SECURITY_GROUPS,
|
||||
[Operations.LIST.value,
|
||||
Operations.FIX_MISMATCH.value,
|
||||
|
|
|
@ -171,6 +171,13 @@ class FakeVcns(object):
|
|||
response = {"interfaces": self._edges[edge_id].get('interfaces', [])}
|
||||
return (header, response)
|
||||
|
||||
def get_virtual_wires(self):
|
||||
header = {
|
||||
'status': 200
|
||||
}
|
||||
response = {"dataPage": {"data": []}}
|
||||
return (header, response)
|
||||
|
||||
def update_vdr_internal_interface(
|
||||
self, edge_id, interface_index, interface):
|
||||
header = {
|
||||
|
|
Loading…
Reference in New Issue