V2T migration: Set expected VIF id to compute ports
- Add an udmin utility to provide the mapping between compute ports and vif-ids - Add extension to the api replay mode to support setting it by the plugin - Add the mapping file as a parameter to teh api replay and use it in the ports migration - Remove post migration cleanup of ports Change-Id: Icfd3ef9f8056ee9c602ac5e85345daa59309f602
This commit is contained in:
parent
1748e7cb4b
commit
7b9fb7b6eb
@ -341,6 +341,9 @@ V2T migration
|
||||
|
||||
nsxadmin -r nsx-migrate-v2t -o validate [--property transit-network=<cidr>] [--property strict=true]
|
||||
|
||||
- Get compute ports vif ids mapping for the migration::
|
||||
|
||||
nsxadmin -r ports -o list (--property map-file=<filename>)
|
||||
Config
|
||||
~~~~~~
|
||||
|
||||
|
@ -60,6 +60,7 @@ class ApiReplayCli(object):
|
||||
ext_net_map=args.external_networks_map,
|
||||
net_vni_map=args.networks_vni_map,
|
||||
int_vni_map=args.internal_networks_vni_map,
|
||||
vif_ids_map=args.vif_ids_map,
|
||||
logfile=args.logfile,
|
||||
max_retry=args.max_retry,
|
||||
cert_file=args.cert_file)
|
||||
@ -191,6 +192,10 @@ class ApiReplayCli(object):
|
||||
"--internal-networks-vni-map",
|
||||
help="Path to a json file mapping internal network ID "
|
||||
"to its backend vni.")
|
||||
parser.add_argument(
|
||||
"--vif-ids-map",
|
||||
help="Path to a json file mapping compute ports ids to the "
|
||||
"expected vif ids.")
|
||||
|
||||
parser.add_argument(
|
||||
"--max-retry",
|
||||
|
@ -56,7 +56,7 @@ class ApiReplayClient(utils.PrepareObjectForMigration):
|
||||
octavia_os_tenant_name, octavia_os_tenant_domain_id,
|
||||
octavia_os_password, octavia_os_auth_url,
|
||||
neutron_conf, ext_net_map, net_vni_map, int_vni_map,
|
||||
logfile, max_retry, cert_file):
|
||||
vif_ids_map, logfile, max_retry, cert_file):
|
||||
|
||||
# Init config and logging
|
||||
if neutron_conf:
|
||||
@ -153,6 +153,13 @@ class ApiReplayClient(utils.PrepareObjectForMigration):
|
||||
else:
|
||||
self.int_vni_map = None
|
||||
|
||||
if vif_ids_map:
|
||||
with open(vif_ids_map, 'r') as myfile:
|
||||
data = myfile.read()
|
||||
self.vif_ids_map = jsonutils.loads(data)
|
||||
else:
|
||||
self.vif_ids_map = None
|
||||
|
||||
self.n_errors = 0
|
||||
self.errors = []
|
||||
|
||||
@ -687,7 +694,8 @@ class ApiReplayClient(utils.PrepareObjectForMigration):
|
||||
port['id'])
|
||||
continue
|
||||
|
||||
body = self.prepare_port(port, remove_qos=remove_qos)
|
||||
body = self.prepare_port(port, remove_qos=remove_qos,
|
||||
vif_ids_map=self.vif_ids_map)
|
||||
|
||||
# specify the network_id that we just created above
|
||||
port['network_id'] = network['id']
|
||||
|
@ -268,7 +268,8 @@ class PrepareObjectForMigration(object):
|
||||
body.pop(field)
|
||||
return body
|
||||
|
||||
def prepare_port(self, port, remove_qos=False, direct_call=False):
|
||||
def prepare_port(self, port, remove_qos=False, vif_ids_map=None,
|
||||
direct_call=False):
|
||||
self.fix_description(port)
|
||||
body = self.drop_fields(port, self.drop_port_fields)
|
||||
if remove_qos:
|
||||
@ -296,6 +297,9 @@ class PrepareObjectForMigration(object):
|
||||
body['port_security_enabled'] = False
|
||||
body['security_groups'] = []
|
||||
|
||||
if vif_ids_map and body['id'] in vif_ids_map:
|
||||
body['vif_id'] = vif_ids_map[body['id']]
|
||||
|
||||
if direct_call:
|
||||
if 'device_id' not in body:
|
||||
body['device_id'] = ""
|
||||
|
@ -35,6 +35,9 @@ ID_WITH_POST = {'allow_post': True, 'allow_put': False,
|
||||
RESOURCE_ATTRIBUTE_MAP = {
|
||||
'ports': {
|
||||
'id': ID_WITH_POST,
|
||||
'vif_id': {'allow_post': True, 'allow_put': False,
|
||||
'default': '',
|
||||
'is_visible': True},
|
||||
},
|
||||
'networks': {
|
||||
'id': ID_WITH_POST,
|
||||
|
@ -1716,7 +1716,12 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
|
||||
context, port_data)
|
||||
device_owner = port_data.get('device_owner')
|
||||
vif_id = None
|
||||
if not device_owner or device_owner != l3_db.DEVICE_OWNER_ROUTER_INTF:
|
||||
if (cfg.CONF.api_replay_mode and device_owner and
|
||||
device_owner.startswith('compute:') and port_data.get('vif_id')):
|
||||
# During api-replay, migrated vm port should have this vif-id
|
||||
vif_id = port_data['vif_id']
|
||||
elif (not device_owner or
|
||||
device_owner != l3_db.DEVICE_OWNER_ROUTER_INTF):
|
||||
# Set vif_id even if no device owner so that auto-generated
|
||||
# MP ports won't be created for VMs before neutron sets the vif-id
|
||||
vif_id = port_data['id']
|
||||
|
@ -53,19 +53,6 @@ def post_v2t_migration_cleanups(resource, event, trigger, **kwargs):
|
||||
section['id'])
|
||||
continue
|
||||
|
||||
# cleanup migrated DVS ports (belong to the edges that are not in use)
|
||||
segments = nsxpolicy.segment.list()
|
||||
for seg in segments:
|
||||
# skip non-neutron segments
|
||||
if not p_utils.is_neutron_resource(seg):
|
||||
continue
|
||||
ports = nsxpolicy.segment_port.list(seg['id'])
|
||||
# find the non-neutron ports and delete them
|
||||
for port in ports:
|
||||
if not p_utils.is_neutron_resource(port):
|
||||
nsxpolicy.segment_port.delete(seg['id'], port['id'])
|
||||
LOG.error("Deleted migrated non-neutron port %s", port['id'])
|
||||
|
||||
|
||||
@admin_utils.output_header
|
||||
def migration_tier0_redistribute(resource, event, trigger, **kwargs):
|
||||
|
@ -17,6 +17,7 @@ import sys
|
||||
import netaddr
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from networking_l2gw.db.l2gateway import l2gateway_models
|
||||
from neutron.services.qos import qos_plugin
|
||||
@ -37,6 +38,7 @@ from vmware_nsx.services.lbaas.nsx_v3.implementation import lb_utils
|
||||
from vmware_nsx.services.lbaas.octavia import constants as oct_const
|
||||
from vmware_nsx.services.qos.nsx_v3 import pol_utils as qos_utils
|
||||
from vmware_nsx.shell.admin.plugins.common import constants
|
||||
from vmware_nsx.shell.admin.plugins.common import formatters
|
||||
from vmware_nsx.shell.admin.plugins.common import utils as admin_utils
|
||||
from vmware_nsx.shell.admin.plugins.nsxv.resources import utils
|
||||
from vmware_nsx.shell import resources as shell
|
||||
@ -356,6 +358,47 @@ def validate_config_for_migration(resource, event, trigger, **kwargs):
|
||||
"NSX-T.")
|
||||
|
||||
|
||||
@admin_utils.output_header
|
||||
def list_ports_vif_ids(resource, event, trigger, **kwargs):
|
||||
filename = None
|
||||
if kwargs.get('property'):
|
||||
properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
|
||||
filename = properties.get('map-file')
|
||||
|
||||
admin_context = n_context.get_admin_context()
|
||||
table_results = []
|
||||
map_results = {}
|
||||
|
||||
with utils.NsxVPluginWrapper() as plugin:
|
||||
neutron_ports = plugin.get_ports(admin_context)
|
||||
for port in neutron_ports:
|
||||
# skip non compute ports
|
||||
if (not port.get('device_owner').startswith(
|
||||
nl_constants.DEVICE_OWNER_COMPUTE_PREFIX)):
|
||||
continue
|
||||
device_id = port.get('device_id')
|
||||
port_id = port['id']
|
||||
vnic_index = plugin._get_port_vnic_index(admin_context, port_id)
|
||||
table_results.append({'neutron_id': port_id,
|
||||
'instance_id': device_id,
|
||||
'vnic_index': vnic_index})
|
||||
if vnic_index is not None:
|
||||
map_results[port_id] = '%s:%s' % (device_id, 4000 + vnic_index)
|
||||
|
||||
LOG.info(formatters.output_formatter(
|
||||
"Compute ports VID IDs", table_results,
|
||||
['neutron_id', 'instance_id', 'vnic_index']))
|
||||
if filename:
|
||||
f = open(filename, "w")
|
||||
f.write("%s" % jsonutils.dumps(map_results))
|
||||
f.close()
|
||||
LOG.info("Mapping data saved into %s", filename)
|
||||
|
||||
|
||||
registry.subscribe(validate_config_for_migration,
|
||||
constants.NSX_MIGRATE_V_T,
|
||||
shell.Operations.VALIDATE.value)
|
||||
|
||||
registry.subscribe(list_ports_vif_ids,
|
||||
constants.PORTS,
|
||||
shell.Operations.LIST.value)
|
||||
|
@ -256,6 +256,8 @@ nsxv_resources = {
|
||||
Operations.DELETE.value]),
|
||||
constants.NSX_MIGRATE_V_T: Resource(constants.NSX_MIGRATE_V_T,
|
||||
[Operations.VALIDATE.value]),
|
||||
constants.PORTS: Resource(constants.PORTS,
|
||||
[Operations.LIST.value]),
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user