Add function to nsxadmin tool
Add these functions to auto-recover the nsxt tier1 router's binding info, segment's metadata proxy config and dhcp profile edge cluster binding. Change-Id: Id4c2d98c9666ba69da06a3375bf8284cd64f5ef4
This commit is contained in:
parent
83d59be2c8
commit
8bb72b792c
|
@ -671,6 +671,10 @@ NSX Policy Plugin
|
||||||
|
|
||||||
nsxadmin -r networks -o nsx-update-state
|
nsxadmin -r networks -o nsx-update-state
|
||||||
|
|
||||||
|
- Update the metadata proxy configuration of all segments for specified availability zone::
|
||||||
|
|
||||||
|
nsxadmin -r networks -o update-metadata --property metadata-proxy=<id> --property az=<name>
|
||||||
|
|
||||||
- List all the neutron routers together with their NSX Policy objects and realization state::
|
- List all the neutron routers together with their NSX Policy objects and realization state::
|
||||||
|
|
||||||
nsxadmin -r routers -o list
|
nsxadmin -r routers -o list
|
||||||
|
@ -687,9 +691,17 @@ NSX Policy Plugin
|
||||||
|
|
||||||
nsxadmin -r routers -o update-nat-firewall-match --property firewall-match=external/internal
|
nsxadmin -r routers -o update-nat-firewall-match --property firewall-match=external/internal
|
||||||
|
|
||||||
|
- Reconfigure the tier1 routers with tier0 GW at NSX backend and update the network binding neutron DB with new tier0 GW for an availability zone::
|
||||||
|
|
||||||
|
nsxadmin -r routers -o recover-tier0 --property tier0=<id> --property az=<name>
|
||||||
|
|
||||||
- Migrate networks DHCP from MP to Policy (for NSX 3.0 upgrades)::
|
- Migrate networks DHCP from MP to Policy (for NSX 3.0 upgrades)::
|
||||||
nsxadmin -r dhcp-binding -o migrate-to-policy --property dhcp-config=<id>
|
nsxadmin -r dhcp-binding -o migrate-to-policy --property dhcp-config=<id>
|
||||||
|
|
||||||
|
- Bind the specified dhcp profile to the edge clusters of the specified tier0 GW::
|
||||||
|
|
||||||
|
nsxadmin -r dhcp-binding -o update-dhcp-profile-edge --property dhcp-profile=<id> --property tier0=<id>
|
||||||
|
|
||||||
- Update tags on a loadbalancer service
|
- Update tags on a loadbalancer service
|
||||||
nsxadmin -r lb-services -o nsx-update-tags
|
nsxadmin -r lb-services -o nsx-update-tags
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,92 @@ def update_admin_state(resource, event, trigger, **kwargs):
|
||||||
nsxpolicy.segment_port.set_admin_state(seg_id, port['id'], False)
|
nsxpolicy.segment_port.set_admin_state(seg_id, port['id'], False)
|
||||||
|
|
||||||
|
|
||||||
|
@admin_utils.output_header
|
||||||
|
def update_metadata(resource, event, trigger, **kwargs):
|
||||||
|
"""
|
||||||
|
Update the metadata proxy configuration of segments
|
||||||
|
"""
|
||||||
|
errmsg = ("Need to specify metadata proxy ID and availability-zone. "
|
||||||
|
"Add --property metadata-proxy=<id> --property az=<name>")
|
||||||
|
if not kwargs.get('property'):
|
||||||
|
LOG.error("%s", errmsg)
|
||||||
|
return
|
||||||
|
properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
|
||||||
|
metaproxy = properties.get('metadata-proxy')
|
||||||
|
az = properties.get('az')
|
||||||
|
if not metaproxy or not az:
|
||||||
|
LOG.error("%s", errmsg)
|
||||||
|
raise SystemExit(errmsg)
|
||||||
|
nsxpolicy = p_utils.get_connected_nsxpolicy()
|
||||||
|
try:
|
||||||
|
nsxpolicy.md_proxy.get(metaproxy)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error("Error while retrieving NSX metadata proxy %s: %s",
|
||||||
|
metaproxy, e)
|
||||||
|
raise SystemExit(e)
|
||||||
|
ctx = context.get_admin_context()
|
||||||
|
with p_utils.NsxPolicyPluginWrapper() as plugin:
|
||||||
|
nets = plugin.get_networks(ctx)
|
||||||
|
for net in nets:
|
||||||
|
if plugin._network_is_external(ctx, net['id']):
|
||||||
|
continue
|
||||||
|
network_az = plugin.get_network_az_by_net_id(ctx, net['id'])
|
||||||
|
if az == network_az.name:
|
||||||
|
seg_id = plugin._get_network_nsx_segment_id(ctx, net['id'])
|
||||||
|
try:
|
||||||
|
nsxpolicy.segment.update(seg_id,
|
||||||
|
metadata_proxy_id=metaproxy)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error("Failed to update segment %s metadata proxy"
|
||||||
|
" configuration: %s",
|
||||||
|
seg_id, e)
|
||||||
|
raise SystemExit(e)
|
||||||
|
else:
|
||||||
|
LOG.info("Updated segment %s to metadata proxy %s",
|
||||||
|
seg_id, metaproxy)
|
||||||
|
LOG.info("Successfully updated all the networks' metadata proxy"
|
||||||
|
" configuration.")
|
||||||
|
|
||||||
|
|
||||||
|
@admin_utils.output_header
|
||||||
|
def update_dhcp_profile_edge(resource, event, trigger, **kwargs):
|
||||||
|
"""
|
||||||
|
Bind the specified dhcp profile to the edge clusters of tier0 GW
|
||||||
|
"""
|
||||||
|
errmsg = ("Need to specify dhcp profile ID and tier0 GW ID. Add "
|
||||||
|
"--property dhcp-profile=<id> --property tier0=<id>")
|
||||||
|
if not kwargs.get('property'):
|
||||||
|
LOG.error("%s", errmsg)
|
||||||
|
return
|
||||||
|
properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
|
||||||
|
dhcp_profile = properties.get('dhcp-profile')
|
||||||
|
tier0 = properties.get('tier0')
|
||||||
|
if not dhcp_profile or not tier0:
|
||||||
|
LOG.error("%s", errmsg)
|
||||||
|
raise SystemExit(errmsg)
|
||||||
|
nsxpolicy = p_utils.get_connected_nsxpolicy()
|
||||||
|
try:
|
||||||
|
nsxpolicy.tier0.get(tier0)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error("Tier0 logical router %s was not found: %s", tier0, e)
|
||||||
|
raise SystemExit(e)
|
||||||
|
edge_path = nsxpolicy.tier0.get_edge_cluster_path(tier0)
|
||||||
|
if edge_path:
|
||||||
|
try:
|
||||||
|
nsxpolicy.dhcp_server_config.update(dhcp_profile,
|
||||||
|
edge_cluster_path=edge_path)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error("Failed to bind dhcp profile %s to edge cluster %s: %s",
|
||||||
|
dhcp_profile, edge_path, e)
|
||||||
|
raise SystemExit(e)
|
||||||
|
else:
|
||||||
|
LOG.info("Successfully updated dhcp profile %s to edge cluster %s",
|
||||||
|
dhcp_profile, edge_path)
|
||||||
|
else:
|
||||||
|
LOG.error("Tier0 logical router %s miss the edge clusters binding."
|
||||||
|
"Skip the dhcp profile update action", tier0)
|
||||||
|
|
||||||
|
|
||||||
registry.subscribe(update_admin_state,
|
registry.subscribe(update_admin_state,
|
||||||
constants.NETWORKS,
|
constants.NETWORKS,
|
||||||
shell.Operations.NSX_UPDATE_STATE.value)
|
shell.Operations.NSX_UPDATE_STATE.value)
|
||||||
|
@ -150,3 +236,11 @@ registry.subscribe(update_admin_state,
|
||||||
registry.subscribe(migrate_dhcp_to_policy,
|
registry.subscribe(migrate_dhcp_to_policy,
|
||||||
constants.DHCP_BINDING,
|
constants.DHCP_BINDING,
|
||||||
shell.Operations.MIGRATE_TO_POLICY.value)
|
shell.Operations.MIGRATE_TO_POLICY.value)
|
||||||
|
|
||||||
|
registry.subscribe(update_metadata,
|
||||||
|
constants.NETWORKS,
|
||||||
|
shell.Operations.UPDATE_METADATA.value)
|
||||||
|
|
||||||
|
registry.subscribe(update_dhcp_profile_edge,
|
||||||
|
constants.DHCP_BINDING,
|
||||||
|
shell.Operations.UPDATE_DHCP_EDGE.value)
|
||||||
|
|
|
@ -119,6 +119,94 @@ def update_tier0(resource, event, trigger, **kwargs):
|
||||||
LOG.info("Done.")
|
LOG.info("Done.")
|
||||||
|
|
||||||
|
|
||||||
|
@admin_utils.output_header
|
||||||
|
def recover_tier0(resource, event, trigger, **kwargs):
|
||||||
|
"""
|
||||||
|
Reconfigure the tier1 routers with tier0 GW at NSX backend and update the
|
||||||
|
neutron external network's physical network binding
|
||||||
|
"""
|
||||||
|
errmsg = ("Need to specify tier0 ID and availability-zone. "
|
||||||
|
"Add --property tier0=<id> --property az=<name>")
|
||||||
|
if not kwargs.get('property'):
|
||||||
|
LOG.error("%s", errmsg)
|
||||||
|
return
|
||||||
|
properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
|
||||||
|
tier0 = properties.get('tier0')
|
||||||
|
az = properties.get('az')
|
||||||
|
if not tier0 or not az:
|
||||||
|
LOG.error("%s", errmsg)
|
||||||
|
raise SystemExit(errmsg)
|
||||||
|
# Verify the id of the tier0
|
||||||
|
nsxpolicy = p_utils.get_connected_nsxpolicy()
|
||||||
|
try:
|
||||||
|
nsxpolicy.tier0.get(tier0)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error("An error occurred while retrieving Tier0 gw router %s: %s",
|
||||||
|
tier0, e)
|
||||||
|
raise SystemExit(e)
|
||||||
|
tier0_edge_cluster = nsxpolicy.tier0.get_edge_cluster_path(tier0)
|
||||||
|
if not tier0_edge_cluster:
|
||||||
|
LOG.error("Tier0 gw router %s does not have an edge cluster "
|
||||||
|
"configured", tier0)
|
||||||
|
return
|
||||||
|
ctx = context.get_admin_context()
|
||||||
|
plugin = RoutersPlugin()
|
||||||
|
neutron_routers = plugin.get_routers(ctx)
|
||||||
|
if not neutron_routers:
|
||||||
|
LOG.info("There are not any neutron routers found")
|
||||||
|
with p_utils.NsxPolicyPluginWrapper() as core_plugin:
|
||||||
|
for router in neutron_routers:
|
||||||
|
router_obj = core_plugin._get_router(ctx, router['id'])
|
||||||
|
router_az = core_plugin._get_router_az_obj(router_obj)
|
||||||
|
if router_obj.gw_port_id and az == router_az.name:
|
||||||
|
old_tier0_path = nsxpolicy.tier1.get(router['id']).\
|
||||||
|
get('tier0_path')
|
||||||
|
if old_tier0_path:
|
||||||
|
old_tier0_edge_cluster_path = nsxpolicy.tier0.\
|
||||||
|
get_edge_cluster_path(old_tier0_path.split('/')[-1])
|
||||||
|
# Update tier1 routers GW to point to the tier0 in the backend
|
||||||
|
try:
|
||||||
|
nsxpolicy.tier1.update(router['id'], tier0=tier0)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error("Failed to update T0 uplink for router %s: %s",
|
||||||
|
router['id'], e)
|
||||||
|
raise SystemExit(e)
|
||||||
|
else:
|
||||||
|
LOG.info("Updated router %s uplink port", router['id'])
|
||||||
|
# Update tier1 routers' edge cluster information to new
|
||||||
|
# tier0's edge cluster only if the tier1 router's old edge
|
||||||
|
# cluster bind to the same edge cluster of old tier0 router
|
||||||
|
old_tier1_edge_cluster_path = nsxpolicy.tier1.\
|
||||||
|
get_edge_cluster_path(router['id'])
|
||||||
|
if old_tier1_edge_cluster_path and \
|
||||||
|
(old_tier1_edge_cluster_path ==
|
||||||
|
old_tier0_edge_cluster_path):
|
||||||
|
try:
|
||||||
|
nsxpolicy.tier1.\
|
||||||
|
set_edge_cluster_path(router['id'],
|
||||||
|
tier0_edge_cluster)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error("Failed to update router %s edge cluster:"
|
||||||
|
" %s", router['id'], e)
|
||||||
|
raise SystemExit(e)
|
||||||
|
else:
|
||||||
|
LOG.info("Updated router %s edge cluster",
|
||||||
|
router['id'])
|
||||||
|
|
||||||
|
# Update Neutron external network's physical network binding
|
||||||
|
nets = core_plugin.get_networks(ctx)
|
||||||
|
for net in nets:
|
||||||
|
network_az = core_plugin.get_network_az_by_net_id(ctx, net['id'])
|
||||||
|
if az == network_az.name and net.get('router:external'):
|
||||||
|
with ctx.session.begin(subtransactions=True):
|
||||||
|
bindings = ctx.session.query(nsx_models.TzNetworkBinding).\
|
||||||
|
filter_by(network_id=net['id']).first()
|
||||||
|
bindings.phy_uuid = tier0
|
||||||
|
LOG.info("Updated neutron external network %s binding "
|
||||||
|
"physical network", net['id'])
|
||||||
|
LOG.info("Successfully updated all the tier0 GW binding information.")
|
||||||
|
|
||||||
|
|
||||||
@admin_utils.output_header
|
@admin_utils.output_header
|
||||||
def update_nat_firewall_match(resource, event, trigger, **kwargs):
|
def update_nat_firewall_match(resource, event, trigger, **kwargs):
|
||||||
"""Update the firewall_match value in neutron nat rules with a new value"""
|
"""Update the firewall_match value in neutron nat rules with a new value"""
|
||||||
|
@ -130,7 +218,7 @@ def update_nat_firewall_match(resource, event, trigger, **kwargs):
|
||||||
properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
|
properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
|
||||||
firewall_match_str = properties.get('firewall-match')
|
firewall_match_str = properties.get('firewall-match')
|
||||||
if (not firewall_match_str or
|
if (not firewall_match_str or
|
||||||
firewall_match_str.lower() not in ('internal', 'external')):
|
firewall_match_str.lower() not in ('internal', 'external')):
|
||||||
LOG.error("%s", errmsg)
|
LOG.error("%s", errmsg)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -184,6 +272,10 @@ registry.subscribe(update_tier0,
|
||||||
constants.ROUTERS,
|
constants.ROUTERS,
|
||||||
shell.Operations.UPDATE_TIER0.value)
|
shell.Operations.UPDATE_TIER0.value)
|
||||||
|
|
||||||
|
registry.subscribe(recover_tier0,
|
||||||
|
constants.ROUTERS,
|
||||||
|
shell.Operations.RECOVER_TIER0.value)
|
||||||
|
|
||||||
registry.subscribe(update_nat_firewall_match,
|
registry.subscribe(update_nat_firewall_match,
|
||||||
constants.ROUTERS,
|
constants.ROUTERS,
|
||||||
shell.Operations.UPDATE_FIREWALL_MATCH.value)
|
shell.Operations.UPDATE_FIREWALL_MATCH.value)
|
||||||
|
|
|
@ -76,6 +76,9 @@ class Operations(enum.Enum):
|
||||||
VALIDATE = 'validate'
|
VALIDATE = 'validate'
|
||||||
REUSE = 'reuse'
|
REUSE = 'reuse'
|
||||||
UPDATE_TIER0 = 'update-tier0'
|
UPDATE_TIER0 = 'update-tier0'
|
||||||
|
RECOVER_TIER0 = 'recover-tier0'
|
||||||
|
UPDATE_METADATA = 'update-metadata'
|
||||||
|
UPDATE_DHCP_EDGE = 'update-dhcp-profile-edge'
|
||||||
UPDATE_FIREWALL_MATCH = 'update-nat-firewall-match'
|
UPDATE_FIREWALL_MATCH = 'update-nat-firewall-match'
|
||||||
SET_STATUS_ERROR = 'set-status-error'
|
SET_STATUS_ERROR = 'set-status-error'
|
||||||
CHECK_COMPUTE_CLUSTERS = 'check-compute-clusters'
|
CHECK_COMPUTE_CLUSTERS = 'check-compute-clusters'
|
||||||
|
@ -122,7 +125,8 @@ nsxv3_resources = {
|
||||||
Operations.NSX_UPDATE_RULES.value,
|
Operations.NSX_UPDATE_RULES.value,
|
||||||
Operations.NSX_UPDATE_DHCP_RELAY.value,
|
Operations.NSX_UPDATE_DHCP_RELAY.value,
|
||||||
Operations.NSX_ENABLE_STANDBY_RELOCATION.value,
|
Operations.NSX_ENABLE_STANDBY_RELOCATION.value,
|
||||||
Operations.UPDATE_TIER0.value]),
|
Operations.UPDATE_TIER0.value,
|
||||||
|
Operations.RECOVER_TIER0.value]),
|
||||||
constants.DHCP_BINDING: Resource(constants.DHCP_BINDING,
|
constants.DHCP_BINDING: Resource(constants.DHCP_BINDING,
|
||||||
[Operations.LIST.value,
|
[Operations.LIST.value,
|
||||||
Operations.NSX_RECREATE.value]),
|
Operations.NSX_RECREATE.value]),
|
||||||
|
@ -282,12 +286,15 @@ nsxp_resources = {
|
||||||
[Operations.LIST.value]),
|
[Operations.LIST.value]),
|
||||||
constants.NETWORKS: Resource(constants.NETWORKS,
|
constants.NETWORKS: Resource(constants.NETWORKS,
|
||||||
[Operations.LIST.value,
|
[Operations.LIST.value,
|
||||||
Operations.NSX_UPDATE_STATE.value]),
|
Operations.NSX_UPDATE_STATE.value,
|
||||||
|
Operations.UPDATE_METADATA.value]),
|
||||||
constants.DHCP_BINDING: Resource(constants.DHCP_BINDING,
|
constants.DHCP_BINDING: Resource(constants.DHCP_BINDING,
|
||||||
[Operations.MIGRATE_TO_POLICY.value]),
|
[Operations.MIGRATE_TO_POLICY.value,
|
||||||
|
Operations.UPDATE_DHCP_EDGE.value]),
|
||||||
constants.ROUTERS: Resource(constants.ROUTERS,
|
constants.ROUTERS: Resource(constants.ROUTERS,
|
||||||
[Operations.LIST.value,
|
[Operations.LIST.value,
|
||||||
Operations.UPDATE_TIER0.value,
|
Operations.UPDATE_TIER0.value,
|
||||||
|
Operations.RECOVER_TIER0.value,
|
||||||
Operations.UPDATE_FIREWALL_MATCH.value]),
|
Operations.UPDATE_FIREWALL_MATCH.value]),
|
||||||
constants.LB_SERVICES: Resource(constants.LB_SERVICES,
|
constants.LB_SERVICES: Resource(constants.LB_SERVICES,
|
||||||
[Operations.NSX_UPDATE_TAGS.value]),
|
[Operations.NSX_UPDATE_TAGS.value]),
|
||||||
|
@ -348,11 +355,11 @@ def _get_choices():
|
||||||
def _get_resources():
|
def _get_resources():
|
||||||
plugin = get_plugin()
|
plugin = get_plugin()
|
||||||
if plugin == 'nsxv3':
|
if plugin == 'nsxv3':
|
||||||
return 'NSX-V3 resources: %s' % (', '.join(nsxv3_resources_names))
|
return f"NSX-V3 resources: {(', '.join(nsxv3_resources_names))}"
|
||||||
if plugin == 'nsxv':
|
if plugin == 'nsxv':
|
||||||
return 'NSX-V resources: %s' % (', '.join(nsxv_resources_names))
|
return f"NSX-V resources: {(', '.join(nsxv_resources_names))}"
|
||||||
if plugin == 'nsxtvd':
|
if plugin == 'nsxtvd':
|
||||||
return 'NSX-TVD resources: %s' % (', '.join(nsxtvd_resources_names))
|
return f"NSX-TVD resources: {(', '.join(nsxtvd_resources_names))}"
|
||||||
|
|
||||||
|
|
||||||
cli_opts = [cfg.StrOpt('fmt',
|
cli_opts = [cfg.StrOpt('fmt',
|
||||||
|
@ -366,8 +373,8 @@ cli_opts = [cfg.StrOpt('fmt',
|
||||||
help=_get_resources()),
|
help=_get_resources()),
|
||||||
cfg.StrOpt('operation',
|
cfg.StrOpt('operation',
|
||||||
short='o',
|
short='o',
|
||||||
help='Supported list of operations: {}'
|
help=f"Supported list of operations:"
|
||||||
.format(', '.join(ops))),
|
f" {(', '.join(ops))}"),
|
||||||
cfg.StrOpt('plugin',
|
cfg.StrOpt('plugin',
|
||||||
help='nsxv or nsxv3 if the tvd plugin is used'),
|
help='nsxv or nsxv3 if the tvd plugin is used'),
|
||||||
cfg.BoolOpt('force',
|
cfg.BoolOpt('force',
|
||||||
|
@ -414,11 +421,11 @@ def init_resource_plugin(plugin_name, plugin_dir):
|
||||||
continue
|
continue
|
||||||
# load the resource
|
# load the resource
|
||||||
importlib.import_module(
|
importlib.import_module(
|
||||||
"vmware_nsx.shell.admin.plugins."
|
f"vmware_nsx.shell.admin.plugins."
|
||||||
"{}.resources.".format(plugin_name) + resource)
|
f"{plugin_name}.resources." + resource)
|
||||||
|
|
||||||
|
|
||||||
def get_plugin_dir(plugin_name):
|
def get_plugin_dir(plugin_name):
|
||||||
plugin_dir = (os.path.dirname(os.path.realpath(__file__)) +
|
plugin_dir = (os.path.dirname(os.path.realpath(__file__)) +
|
||||||
"/admin/plugins")
|
"/admin/plugins")
|
||||||
return '{}/{}/resources'.format(plugin_dir, plugin_name)
|
return f"{plugin_dir}/{plugin_name}/resources"
|
||||||
|
|
|
@ -415,7 +415,11 @@ class TestNsxpAdminUtils(AbstractTestAdminUtils,
|
||||||
"dhcp-config=dumyuuid",
|
"dhcp-config=dumyuuid",
|
||||||
"old-tier0=olduuid",
|
"old-tier0=olduuid",
|
||||||
"new-tier0=newuuid",
|
"new-tier0=newuuid",
|
||||||
"firewall-match=internal"]
|
"firewall-match=internal",
|
||||||
|
"tier0=newuuid",
|
||||||
|
"metadata-proxy=mdproxy",
|
||||||
|
"az=default",
|
||||||
|
"dhcp-profile=openstack_dchp_profile"]
|
||||||
# Create some neutron objects for the utilities to run on
|
# Create some neutron objects for the utilities to run on
|
||||||
self._create_router()
|
self._create_router()
|
||||||
with self._create_l3_ext_network() as network:
|
with self._create_l3_ext_network() as network:
|
||||||
|
|
Loading…
Reference in New Issue