T2P migration
This patch will allow moving neutron from using the nsx_v3 plugin to the nsx_p plugin. This includes: - admin utility to move all resources to the policy api: nsxadmin -r nsx-migrate-t2p -o import (--verbose) This utility will: -- Migrate all neutron used & created resource using the nsx migration api -- roll back all resources in case it failed -- post migration fix some of the policy resources to better match the expectation of the policy plugin - admin utility that will cleanup left overs in the nsx_v3 db: nsxadmin -r nsx-migrate-t2p -o clean-all (can be used, but everything should work without calling it as well) - Some minor changes to the policy plugin and drivers to allow it to handle migrated resource which are a bit different than those created with the policy plugin -- Delete DHCP server config once a migrated network is deleted -- Update LB L7 rules by their name suffix as their full display name is unknown Change-Id: Ic17e0de1f4b2a2d95afa61ce33ffb0bc9e667b89
This commit is contained in:
parent
bc54e93478
commit
0bad4876dc
@ -1,7 +1,7 @@
|
||||
[run]
|
||||
branch = True
|
||||
source = vmware_nsx
|
||||
omit = vmware_nsx/tests/*,vmware_nsx/*dvs*,vmware_nsx/api_replay/*,vmware_nsx/dhcp_meta/*,vmware_nsx/nsxlib/*,vmware_nsx/*lsn*,vmware_nsx/*tv*,vmware_nsx/api_client/*,vmware_nsx/common/profile*,vmware_nsx/shell/nsx_instance_if_migrate*,vmware_nsx/plugins/nsx_v/vshield/vcns.*,vmware_nsx/db/migration/alembic_migrations/*
|
||||
omit = vmware_nsx/tests/*,vmware_nsx/*dvs*,vmware_nsx/api_replay/*,vmware_nsx/dhcp_meta/*,vmware_nsx/nsxlib/*,vmware_nsx/*lsn*,vmware_nsx/*tv*,vmware_nsx/api_client/*,vmware_nsx/common/profile*,vmware_nsx/shell/nsx_instance_if_migrate*,vmware_nsx/plugins/nsx_v/vshield/vcns.*,vmware_nsx/db/migration/alembic_migrations/*,vmware_nsx/shell/admin/plugins/nsxv3/resources/migration*
|
||||
|
||||
[report]
|
||||
ignore_errors = True
|
||||
|
@ -592,6 +592,17 @@ Config
|
||||
|
||||
nsxadmin -r config -o validate
|
||||
|
||||
T2P migration
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
- Migrate NSX resources and neutron DB from NSX-T (MP) to Policy::
|
||||
|
||||
nsxadmin -r nsx-migrate-t2p -o import (--verbose)
|
||||
|
||||
- Delete DB tables related to the MP plugin after migration::
|
||||
|
||||
nsxadmin -r nsx-migrate-t2p -o clean-all
|
||||
|
||||
NSXtvd Plugin
|
||||
-------------
|
||||
|
||||
@ -643,6 +654,10 @@ NSX Policy Plugin
|
||||
- Update tags on a loadbalancer service
|
||||
nsxadmin -r lb-services -o nsx-update-tags
|
||||
|
||||
- Delete DB tables related to the MP plugin after migration from MP plugin to policy::
|
||||
|
||||
nsxadmin -r nsx-migrate-t2p -o clean-all
|
||||
|
||||
|
||||
Client Certificate
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
@ -28,6 +28,7 @@ oslo.utils==3.33.0
|
||||
oslo.vmware==2.17.0
|
||||
oslotest==3.2.0
|
||||
osc-lib==1.14.0
|
||||
paramiko==2.4.0
|
||||
pbr==4.0.0
|
||||
pika-pool==0.1.3
|
||||
pika==0.10.0
|
||||
|
@ -26,6 +26,7 @@ oslo.serialization>=2.28.1 # Apache-2.0
|
||||
oslo.service>=1.31.0 # Apache-2.0
|
||||
oslo.utils>=3.33.0 # Apache-2.0
|
||||
oslo.vmware>=2.17.0 # Apache-2.0
|
||||
paramiko>=2.4.0 # LGPLv2.1+
|
||||
PrettyTable<0.8,>=0.7.2 # BSD
|
||||
tooz>=1.58.0 # Apache-2.0
|
||||
decorator>=4.4.1 # BSD
|
||||
|
@ -104,6 +104,11 @@ def is_nsx_version_3_0_0(nsx_version):
|
||||
version.LooseVersion(v3_const.NSX_VERSION_3_0_0))
|
||||
|
||||
|
||||
def is_nsx_version_3_1_0(nsx_version):
|
||||
return (version.LooseVersion(nsx_version) >=
|
||||
version.LooseVersion(v3_const.NSX_VERSION_3_1_0))
|
||||
|
||||
|
||||
def is_nsxv_version_6_2(nsx_version):
|
||||
return (version.LooseVersion(nsx_version) >=
|
||||
version.LooseVersion('6.2'))
|
||||
|
@ -159,35 +159,44 @@ def get_nsxlib_wrapper(nsx_username=None, nsx_password=None, basic_auth=False,
|
||||
|
||||
|
||||
def get_nsxpolicy_wrapper(nsx_username=None, nsx_password=None,
|
||||
basic_auth=False):
|
||||
basic_auth=False, conf_path=None):
|
||||
if not conf_path:
|
||||
conf_path = cfg.CONF.nsx_p
|
||||
client_cert_provider = None
|
||||
if not basic_auth:
|
||||
# if basic auth requested, dont use cert file even if provided
|
||||
client_cert_provider = get_client_cert_provider(
|
||||
conf_path=cfg.CONF.nsx_p)
|
||||
conf_path=conf_path)
|
||||
|
||||
nsxlib_config = config.NsxLibConfig(
|
||||
username=nsx_username or cfg.CONF.nsx_p.nsx_api_user,
|
||||
password=nsx_password or cfg.CONF.nsx_p.nsx_api_password,
|
||||
username=nsx_username or conf_path.nsx_api_user,
|
||||
password=nsx_password or conf_path.nsx_api_password,
|
||||
client_cert_provider=client_cert_provider,
|
||||
retries=cfg.CONF.nsx_p.http_retries,
|
||||
insecure=cfg.CONF.nsx_p.insecure,
|
||||
ca_file=cfg.CONF.nsx_p.ca_file,
|
||||
concurrent_connections=cfg.CONF.nsx_p.concurrent_connections,
|
||||
http_timeout=cfg.CONF.nsx_p.http_timeout,
|
||||
http_read_timeout=cfg.CONF.nsx_p.http_read_timeout,
|
||||
conn_idle_timeout=cfg.CONF.nsx_p.conn_idle_timeout,
|
||||
retries=conf_path.http_retries,
|
||||
insecure=conf_path.insecure,
|
||||
ca_file=conf_path.ca_file,
|
||||
concurrent_connections=conf_path.concurrent_connections,
|
||||
http_timeout=conf_path.http_timeout,
|
||||
http_read_timeout=conf_path.http_read_timeout,
|
||||
conn_idle_timeout=conf_path.conn_idle_timeout,
|
||||
http_provider=None,
|
||||
max_attempts=cfg.CONF.nsx_p.retries,
|
||||
nsx_api_managers=cfg.CONF.nsx_p.nsx_api_managers,
|
||||
max_attempts=conf_path.retries,
|
||||
nsx_api_managers=conf_path.nsx_api_managers,
|
||||
plugin_scope=OS_NEUTRON_ID_SCOPE,
|
||||
plugin_tag=NSX_NEUTRON_PLUGIN,
|
||||
plugin_ver=n_version.version_info.release_string(),
|
||||
dns_nameservers=cfg.CONF.nsx_p.nameservers,
|
||||
dns_domain=cfg.CONF.nsx_p.dns_domain,
|
||||
allow_passthrough=cfg.CONF.nsx_p.allow_passthrough,
|
||||
realization_max_attempts=cfg.CONF.nsx_p.realization_max_attempts,
|
||||
realization_wait_sec=cfg.CONF.nsx_p.realization_wait_sec)
|
||||
dns_nameservers=conf_path.nameservers,
|
||||
dns_domain=conf_path.dns_domain,
|
||||
allow_passthrough=(conf_path.allow_passthrough
|
||||
if hasattr(conf_path, 'allow_passthrough')
|
||||
else False),
|
||||
realization_max_attempts=(conf_path.realization_max_attempts
|
||||
if hasattr(conf_path,
|
||||
'realization_max_attempts')
|
||||
else 50),
|
||||
realization_wait_sec=(conf_path.realization_wait_sec
|
||||
if hasattr(conf_path, 'realization_wait_sec')
|
||||
else 1))
|
||||
return policy.NsxPolicyLib(nsxlib_config)
|
||||
|
||||
|
||||
|
@ -822,13 +822,19 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
|
||||
# MP MD proxy when this network is created.
|
||||
# If not - the port will not be found, and it is ok.
|
||||
# Note(asarfaty): In the future this code can be removed.
|
||||
if not is_external_net and cfg.CONF.nsx_p.allow_passthrough:
|
||||
# TODO(asarfaty): For migrated networks when the DB was not cleaned up
|
||||
# This may actually delete a port the policy now control
|
||||
if (not is_external_net and not is_nsx_net and
|
||||
cfg.CONF.nsx_p.allow_passthrough):
|
||||
self._delete_nsx_port_by_network(network_id)
|
||||
|
||||
# Delete the network segment from the backend
|
||||
if not is_external_net and not is_nsx_net:
|
||||
try:
|
||||
self.nsxpolicy.segment.delete(network_id)
|
||||
# In case of migrated network, a dhcp server config with
|
||||
# the same id should also be deleted
|
||||
self.nsxpolicy.dhcp_server_config.delete(network_id)
|
||||
except nsx_lib_exc.ResourceNotFound:
|
||||
# If the resource was not found on the backend do not worry
|
||||
# about it. The conditions has already been logged, so there
|
||||
@ -3921,7 +3927,7 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
|
||||
rule_entry = self._create_security_group_backend_rule(
|
||||
context, sg_id, rule, secgroup_logging,
|
||||
is_provider_sg=is_provider_sg,
|
||||
create_related_resource=False)
|
||||
create_related_resource=True)
|
||||
backend_rules.append(rule_entry)
|
||||
|
||||
# Update the policy with all the rules.
|
||||
|
@ -52,6 +52,7 @@ class EdgeL7PolicyManagerFromDict(base_mgr.NsxpLoadbalancerBaseManager):
|
||||
vs_client = self.core_plugin.nsxpolicy.load_balancer.virtual_server
|
||||
policy_name = utils.get_name_and_uuid(old_policy['name'] or 'policy',
|
||||
old_policy['id'])
|
||||
short_name = utils.get_name_short_uuid(old_policy['id'])
|
||||
rule_body = lb_utils.convert_l7policy_to_lb_rule(
|
||||
self.core_plugin.nsxpolicy, new_policy)
|
||||
try:
|
||||
@ -59,6 +60,7 @@ class EdgeL7PolicyManagerFromDict(base_mgr.NsxpLoadbalancerBaseManager):
|
||||
new_policy['listener_id'],
|
||||
policy_name,
|
||||
position=new_policy.get('position', 0) - 1,
|
||||
compare_name_suffix=short_name,
|
||||
**rule_body)
|
||||
|
||||
except Exception as e:
|
||||
@ -70,11 +72,11 @@ class EdgeL7PolicyManagerFromDict(base_mgr.NsxpLoadbalancerBaseManager):
|
||||
|
||||
def delete(self, context, policy, completor):
|
||||
vs_client = self.core_plugin.nsxpolicy.load_balancer.virtual_server
|
||||
policy_name = utils.get_name_and_uuid(policy['name'] or 'policy',
|
||||
policy['id'])
|
||||
policy_name = utils.get_name_short_uuid(policy['id'])
|
||||
try:
|
||||
vs_client.remove_lb_rule(policy['listener_id'],
|
||||
policy_name)
|
||||
policy_name,
|
||||
check_name_suffix=True)
|
||||
except nsxlib_exc.ResourceNotFound:
|
||||
pass
|
||||
except nsxlib_exc.ManagerError:
|
||||
|
@ -29,6 +29,7 @@ class EdgeL7RuleManagerFromDict(base_mgr.NsxpLoadbalancerBaseManager):
|
||||
policy = rule['policy']
|
||||
policy_name = utils.get_name_and_uuid(policy['name'] or 'policy',
|
||||
policy['id'])
|
||||
short_name = utils.get_name_short_uuid(policy['id'])
|
||||
if delete:
|
||||
lb_utils.remove_rule_from_policy(rule)
|
||||
else:
|
||||
@ -39,6 +40,7 @@ class EdgeL7RuleManagerFromDict(base_mgr.NsxpLoadbalancerBaseManager):
|
||||
vs_client.update_lb_rule(policy['listener_id'],
|
||||
policy_name,
|
||||
position=policy.get('position', 0) - 1,
|
||||
compare_name_suffix=short_name,
|
||||
**rule_body)
|
||||
except Exception as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
|
@ -51,6 +51,7 @@ LB_ADVERTISEMENT = 'lb-advertisement'
|
||||
RATE_LIMIT = 'rate-limit'
|
||||
CLUSTER = 'cluster'
|
||||
ORPHANED_FIREWALL_SECTIONS = 'orphaned-firewall-sections'
|
||||
NSX_MIGRATE_T_P = 'nsx-migrate-t2p'
|
||||
|
||||
# NSXV only Resource Constants
|
||||
EDGES = 'edges'
|
||||
|
31
vmware_nsx/shell/admin/plugins/nsxp/migration.py
Normal file
31
vmware_nsx/shell/admin/plugins/nsxp/migration.py
Normal file
@ -0,0 +1,31 @@
|
||||
# Copyright 2020 VMware, Inc. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib.callbacks import registry
|
||||
|
||||
from vmware_nsx.shell.admin.plugins.common import constants
|
||||
from vmware_nsx.shell.admin.plugins.common import utils as admin_utils
|
||||
from vmware_nsx.shell.admin.plugins.nsxv3.resources import migration
|
||||
from vmware_nsx.shell import resources as shell
|
||||
|
||||
|
||||
@admin_utils.output_header
|
||||
def cleanup_db_mappings(resource, event, trigger, **kwargs):
|
||||
"""Delete all entries from nsx-t mapping tables in DB"""
|
||||
return migration.cleanup_db_mappings(resource, event, trigger, **kwargs)
|
||||
|
||||
|
||||
registry.subscribe(cleanup_db_mappings,
|
||||
constants.NSX_MIGRATE_T_P,
|
||||
shell.Operations.CLEAN_ALL.value)
|
@ -12,6 +12,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
from oslo_config import cfg
|
||||
|
||||
from neutron.db import l3_dvr_db # noqa
|
||||
@ -19,7 +20,6 @@ from neutron import manager
|
||||
from neutron_lib import context
|
||||
from neutron_lib.plugins import constants as const
|
||||
from neutron_lib.plugins import directory
|
||||
from oslo_log import log as logging
|
||||
|
||||
from vmware_nsx.common import config
|
||||
from vmware_nsx.plugins.common_v3 import utils as v3_utils
|
||||
@ -41,16 +41,28 @@ def get_nsxp_client(nsx_username=None, nsx_password=None,
|
||||
|
||||
|
||||
def get_connected_nsxpolicy(nsx_username=None, nsx_password=None,
|
||||
use_basic_auth=False):
|
||||
use_basic_auth=False, conf_path=None,
|
||||
verbose=False):
|
||||
global _NSXPOLICY
|
||||
|
||||
# for non-default agruments, initiate new lib
|
||||
if not verbose:
|
||||
# Suppress logs for nsxpolicy init
|
||||
logging.disable(logging.INFO)
|
||||
|
||||
# for non-default arguments, initiate new lib
|
||||
if nsx_username or use_basic_auth:
|
||||
if not verbose:
|
||||
# Return logs to normal
|
||||
logging.disable(logging.NOTSET)
|
||||
return v3_utils.get_nsxpolicy_wrapper(nsx_username,
|
||||
nsx_password,
|
||||
use_basic_auth)
|
||||
use_basic_auth,
|
||||
conf_path=conf_path)
|
||||
if _NSXPOLICY is None:
|
||||
_NSXPOLICY = v3_utils.get_nsxpolicy_wrapper()
|
||||
_NSXPOLICY = v3_utils.get_nsxpolicy_wrapper(conf_path=conf_path)
|
||||
if not verbose:
|
||||
# Return logs to normal
|
||||
logging.disable(logging.NOTSET)
|
||||
return _NSXPOLICY
|
||||
|
||||
|
||||
@ -76,13 +88,21 @@ def get_realization_info(resource, *realization_args):
|
||||
|
||||
|
||||
class NsxPolicyPluginWrapper(plugin.NsxPolicyPlugin):
|
||||
def __init__(self):
|
||||
def __init__(self, verbose=False):
|
||||
if not verbose:
|
||||
# Suppress logs for plugin init
|
||||
logging.disable(logging.INFO)
|
||||
|
||||
# initialize the availability zones
|
||||
config.register_nsxp_azs(cfg.CONF, cfg.CONF.nsx_p.availability_zones)
|
||||
super(NsxPolicyPluginWrapper, self).__init__()
|
||||
self.context = context.get_admin_context()
|
||||
admin_utils._init_plugin_mock_quota()
|
||||
|
||||
if not verbose:
|
||||
# Return logs to normal
|
||||
logging.disable(logging.NOTSET)
|
||||
|
||||
def __enter__(self):
|
||||
directory.add_plugin(const.CORE, self)
|
||||
return self
|
||||
|
1447
vmware_nsx/shell/admin/plugins/nsxv3/resources/migration.py
Normal file
1447
vmware_nsx/shell/admin/plugins/nsxv3/resources/migration.py
Normal file
File diff suppressed because it is too large
Load Diff
@ -12,6 +12,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import logging
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
@ -46,17 +47,29 @@ def get_nsxv3_client(nsx_username=None, nsx_password=None,
|
||||
|
||||
def get_connected_nsxlib(nsx_username=None, nsx_password=None,
|
||||
use_basic_auth=False,
|
||||
plugin_conf=None):
|
||||
plugin_conf=None,
|
||||
verbose=False):
|
||||
global _NSXLIB
|
||||
|
||||
# for non-default agruments, initiate new lib
|
||||
if not verbose:
|
||||
# Suppress logs for nsxlib init
|
||||
logging.disable(logging.INFO)
|
||||
|
||||
# for non-default arguments, initiate new lib
|
||||
if nsx_username or use_basic_auth:
|
||||
if not verbose:
|
||||
# Return logs to normal
|
||||
logging.disable(logging.NOTSET)
|
||||
return v3_utils.get_nsxlib_wrapper(nsx_username,
|
||||
nsx_password,
|
||||
use_basic_auth,
|
||||
plugin_conf)
|
||||
if _NSXLIB is None:
|
||||
_NSXLIB = v3_utils.get_nsxlib_wrapper(plugin_conf=plugin_conf)
|
||||
|
||||
if not verbose:
|
||||
# Return logs to normal
|
||||
logging.disable(logging.NOTSET)
|
||||
return _NSXLIB
|
||||
|
||||
|
||||
@ -117,13 +130,21 @@ class NeutronDbClient(db_base_plugin_v2.NeutronDbPluginV2):
|
||||
|
||||
|
||||
class NsxV3PluginWrapper(plugin.NsxV3Plugin):
|
||||
def __init__(self):
|
||||
def __init__(self, verbose=False):
|
||||
if not verbose:
|
||||
# Suppress logs for plugin init
|
||||
logging.disable(logging.INFO)
|
||||
|
||||
# initialize the availability zones
|
||||
config.register_nsxv3_azs(cfg.CONF, cfg.CONF.nsx_v3.availability_zones)
|
||||
super(NsxV3PluginWrapper, self).__init__()
|
||||
self.context = context.get_admin_context()
|
||||
admin_utils._init_plugin_mock_quota()
|
||||
|
||||
if not verbose:
|
||||
# Return logs to normal
|
||||
logging.disable(logging.NOTSET)
|
||||
|
||||
def __enter__(self):
|
||||
directory.add_plugin(const.CORE, self)
|
||||
return self
|
||||
@ -131,6 +152,10 @@ class NsxV3PluginWrapper(plugin.NsxV3Plugin):
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
directory.add_plugin(const.CORE, None)
|
||||
|
||||
def _cleanup_duplicates(self, ns_group_id, section_id):
|
||||
# Do not remove DFW sections during dummy plugin initialization
|
||||
pass
|
||||
|
||||
def _init_fwaas_plugin(self, provider, callbacks_class, plugin_callbacks):
|
||||
fwaas_plugin_class = manager.NeutronManager.load_class_for_provider(
|
||||
'neutron.service_plugins', provider)
|
||||
|
@ -154,7 +154,10 @@ nsxv3_resources = {
|
||||
constants.LB_ADVERTISEMENT: Resource(constants.LB_ADVERTISEMENT,
|
||||
[Operations.NSX_UPDATE.value]),
|
||||
constants.CLUSTER: Resource(constants.CLUSTER,
|
||||
[Operations.SHOW.value])
|
||||
[Operations.SHOW.value]),
|
||||
constants.NSX_MIGRATE_T_P: Resource(constants.NSX_MIGRATE_T_P,
|
||||
[Operations.IMPORT.value,
|
||||
Operations.CLEAN_ALL.value]),
|
||||
}
|
||||
|
||||
# Add supported NSX-V resources in this dictionary
|
||||
@ -276,6 +279,8 @@ nsxp_resources = {
|
||||
Operations.NSX_LIST.value]),
|
||||
constants.SYSTEM: Resource(constants.SYSTEM,
|
||||
[Operations.SET.value]),
|
||||
constants.NSX_MIGRATE_T_P: Resource(constants.NSX_MIGRATE_T_P,
|
||||
[Operations.CLEAN_ALL.value]),
|
||||
}
|
||||
|
||||
nsxv3_resources_names = list(nsxv3_resources.keys())
|
||||
|
@ -1893,7 +1893,8 @@ class TestEdgeLbaasV2L7Policy(BaseTestEdgeLbaasV2):
|
||||
) as mock_vs_remove_rule:
|
||||
self.edge_driver.l7policy.delete(
|
||||
self.context, self.l7policy_dict, self.completor)
|
||||
mock_vs_remove_rule.assert_called_with(LB_VS_ID, mock.ANY)
|
||||
mock_vs_remove_rule.assert_called_with(LB_VS_ID, mock.ANY,
|
||||
check_name_suffix=True)
|
||||
self.assertTrue(self.last_completor_called)
|
||||
self.assertTrue(self.last_completor_succees)
|
||||
|
||||
@ -1903,7 +1904,8 @@ class TestEdgeLbaasV2L7Policy(BaseTestEdgeLbaasV2):
|
||||
) as mock_vs_remove_rule:
|
||||
self.edge_driver.l7policy.delete_cascade(
|
||||
self.context, self.l7policy_dict, self.completor)
|
||||
mock_vs_remove_rule.assert_called_with(LB_VS_ID, mock.ANY)
|
||||
mock_vs_remove_rule.assert_called_with(LB_VS_ID, mock.ANY,
|
||||
check_name_suffix=True)
|
||||
self.assertTrue(self.last_completor_called)
|
||||
self.assertTrue(self.last_completor_succees)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user