Merge "[Admin-Util] recreate NSX|v router edge"
This commit is contained in:
commit
2b7210313c
@ -83,6 +83,12 @@ DHCP Bindings
|
|||||||
|
|
||||||
nsxadmin -r dhcp-binding -o nsx-recreate --property edge-id=edge-222
|
nsxadmin -r dhcp-binding -o nsx-recreate --property edge-id=edge-222
|
||||||
|
|
||||||
|
Routers
|
||||||
|
~~~~~~~
|
||||||
|
- Recreate a router edge by moving the router/s to other edge/s::
|
||||||
|
|
||||||
|
nsxadmin -r routers -o nsx-recreate --property edge-id=edge-308
|
||||||
|
|
||||||
Networks
|
Networks
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
|
@ -143,6 +143,12 @@ def get_edge_availability_zone(session, edge_id):
|
|||||||
return binding['availability_zone']
|
return binding['availability_zone']
|
||||||
|
|
||||||
|
|
||||||
|
def clean_edge_router_binding(session, edge_id):
|
||||||
|
with session.begin(subtransactions=True):
|
||||||
|
(session.query(nsxv_models.NsxvRouterBinding).
|
||||||
|
filter_by(edge_id=edge_id).delete())
|
||||||
|
|
||||||
|
|
||||||
def get_edge_vnic_binding(session, edge_id, network_id):
|
def get_edge_vnic_binding(session, edge_id, network_id):
|
||||||
return session.query(nsxv_models.NsxvEdgeVnicBinding).filter_by(
|
return session.query(nsxv_models.NsxvEdgeVnicBinding).filter_by(
|
||||||
edge_id=edge_id, network_id=network_id).first()
|
edge_id=edge_id, network_id=network_id).first()
|
||||||
|
@ -1547,16 +1547,14 @@ class EdgeManager(object):
|
|||||||
except Exception:
|
except Exception:
|
||||||
LOG.warning(_LW("Failed to delete virtual wire: %s"), lswitch_id)
|
LOG.warning(_LW("Failed to delete virtual wire: %s"), lswitch_id)
|
||||||
|
|
||||||
def get_routers_on_same_edge(self, context, router_id):
|
def get_routers_on_edge(self, context, edge_id):
|
||||||
edge_binding = nsxv_db.get_nsxv_router_binding(
|
|
||||||
context.session, router_id)
|
|
||||||
router_ids = []
|
router_ids = []
|
||||||
valid_router_ids = []
|
valid_router_ids = []
|
||||||
if edge_binding:
|
if edge_id:
|
||||||
router_ids = [
|
router_ids = [
|
||||||
binding['router_id']
|
binding['router_id']
|
||||||
for binding in nsxv_db.get_nsxv_router_bindings_by_edge(
|
for binding in nsxv_db.get_nsxv_router_bindings_by_edge(
|
||||||
context.session, edge_binding['edge_id'])]
|
context.session, edge_id)]
|
||||||
if router_ids:
|
if router_ids:
|
||||||
valid_router_ids = self.plugin.get_routers(
|
valid_router_ids = self.plugin.get_routers(
|
||||||
context.elevated(),
|
context.elevated(),
|
||||||
@ -1570,6 +1568,13 @@ class EdgeManager(object):
|
|||||||
str(set(router_ids) - set(valid_router_ids)))
|
str(set(router_ids) - set(valid_router_ids)))
|
||||||
return valid_router_ids
|
return valid_router_ids
|
||||||
|
|
||||||
|
def get_routers_on_same_edge(self, context, router_id):
|
||||||
|
edge_binding = nsxv_db.get_nsxv_router_binding(
|
||||||
|
context.session, router_id)
|
||||||
|
if edge_binding:
|
||||||
|
return self.get_routers_on_edge(context, edge_binding['edge_id'])
|
||||||
|
return []
|
||||||
|
|
||||||
def bind_router_on_available_edge(
|
def bind_router_on_available_edge(
|
||||||
self, context, target_router_id,
|
self, context, target_router_id,
|
||||||
optional_router_ids, conflict_router_ids,
|
optional_router_ids, conflict_router_ids,
|
||||||
|
129
vmware_nsx/shell/admin/plugins/nsxv/resources/routers.py
Normal file
129
vmware_nsx/shell/admin/plugins/nsxv/resources/routers.py
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
# Copyright 2016 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.
|
||||||
|
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from vmware_nsx.shell.admin.plugins.common import constants
|
||||||
|
import vmware_nsx.shell.admin.plugins.common.utils as admin_utils
|
||||||
|
import vmware_nsx.shell.admin.plugins.nsxv.resources.utils as utils
|
||||||
|
import vmware_nsx.shell.resources as shell
|
||||||
|
|
||||||
|
from neutron.callbacks import registry
|
||||||
|
from neutron import context as n_context
|
||||||
|
from oslo_config import cfg
|
||||||
|
|
||||||
|
from vmware_nsx._i18n import _LE, _LI, _LW
|
||||||
|
from vmware_nsx.common import locking
|
||||||
|
from vmware_nsx.db import nsxv_db
|
||||||
|
from vmware_nsx.extensions import routersize
|
||||||
|
from vmware_nsx.plugins.nsx_v.vshield import edge_utils
|
||||||
|
from vmware_nsx.plugins.nsx_v.vshield import vcns_driver
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def delete_old_edge(context, old_edge_id):
|
||||||
|
LOG.info(_LI("Deleting the old edge: %s"), old_edge_id)
|
||||||
|
|
||||||
|
# clean it up from the DB
|
||||||
|
nsxv_db.clean_edge_router_binding(context.session, old_edge_id)
|
||||||
|
nsxv_db.clean_edge_vnic_binding(context.session, old_edge_id)
|
||||||
|
nsxv_db.cleanup_nsxv_edge_firewallrule_binding(context.session,
|
||||||
|
old_edge_id)
|
||||||
|
|
||||||
|
with locking.LockManager.get_lock(old_edge_id):
|
||||||
|
# Delete from NSXv backend
|
||||||
|
# Note - If we will not delete the edge, but free it - it will be
|
||||||
|
# immediately used as the new one, So it is better to delete it.
|
||||||
|
try:
|
||||||
|
nsxv = utils.get_nsxv_client()
|
||||||
|
nsxv.delete_edge(old_edge_id)
|
||||||
|
except Exception as e:
|
||||||
|
LOG.warning(_LW("Failed to delete the old edge %(id)s: %(e)s"),
|
||||||
|
{'id': old_edge_id, 'e': e})
|
||||||
|
# Continue the process anyway
|
||||||
|
# The edge may have been already deleted at the backend
|
||||||
|
|
||||||
|
|
||||||
|
@admin_utils.output_header
|
||||||
|
def nsx_recreate_router_edge(resource, event, trigger, **kwargs):
|
||||||
|
"""Recreate a router edge with all the data on a new NSXv edge"""
|
||||||
|
if not kwargs.get('property'):
|
||||||
|
LOG.error(_LE("Need to specify edge-id parameter"))
|
||||||
|
return
|
||||||
|
|
||||||
|
# input validation
|
||||||
|
properties = admin_utils.parse_multi_keyval_opt(kwargs['property'])
|
||||||
|
old_edge_id = properties.get('edge-id')
|
||||||
|
if not old_edge_id:
|
||||||
|
LOG.error(_LE("Need to specify edge-id parameter"))
|
||||||
|
return
|
||||||
|
LOG.info(_LI("ReCreating NSXv Router Edge: %s"), old_edge_id)
|
||||||
|
|
||||||
|
# init the plugin and edge manager
|
||||||
|
cfg.CONF.set_override('core_plugin',
|
||||||
|
'vmware_nsx.shell.admin.plugins.nsxv.resources'
|
||||||
|
'.utils.NsxVPluginWrapper')
|
||||||
|
plugin = utils.NsxVPluginWrapper()
|
||||||
|
nsxv_manager = vcns_driver.VcnsDriver(edge_utils.NsxVCallbacks(plugin))
|
||||||
|
edge_manager = edge_utils.EdgeManager(nsxv_manager, plugin)
|
||||||
|
context = n_context.get_admin_context()
|
||||||
|
|
||||||
|
# verify that this is a Router edge
|
||||||
|
router_ids = edge_manager.get_routers_on_edge(context, old_edge_id)
|
||||||
|
if not router_ids:
|
||||||
|
LOG.error(_LE("Edge %(edge_id)s is not a router edge"),
|
||||||
|
{'edge_id': old_edge_id})
|
||||||
|
return
|
||||||
|
|
||||||
|
# all the routers on the same edge have the same type, so it
|
||||||
|
# is ok to check the type once
|
||||||
|
example_router = plugin.get_router(context, router_ids[0])
|
||||||
|
router_driver = plugin._router_managers.get_tenant_router_driver(
|
||||||
|
context, example_router['router_type'])
|
||||||
|
if router_driver.get_type() == "distributed":
|
||||||
|
LOG.error(_LE("Recreating a distributed driver edge is not "
|
||||||
|
"supported"))
|
||||||
|
return
|
||||||
|
|
||||||
|
# load all the routers before deleting their binding
|
||||||
|
routers = []
|
||||||
|
for router_id in router_ids:
|
||||||
|
routers.append(plugin.get_router(context, router_id))
|
||||||
|
|
||||||
|
# delete the backend edge and all the relevant DB entries
|
||||||
|
delete_old_edge(context, old_edge_id)
|
||||||
|
|
||||||
|
# Go over all the relevant routers
|
||||||
|
for router in routers:
|
||||||
|
router_id = router['id']
|
||||||
|
# clean up other objects related to this router
|
||||||
|
if plugin.metadata_proxy_handler:
|
||||||
|
plugin.metadata_proxy_handler.cleanup_router_edge(router_id)
|
||||||
|
|
||||||
|
# attach the router to a new edge
|
||||||
|
appliance_size = router.get(routersize.ROUTER_SIZE)
|
||||||
|
router_driver.attach_router(context, router_id,
|
||||||
|
{'router': router},
|
||||||
|
appliance_size=appliance_size)
|
||||||
|
# find out who is the new edge to print it
|
||||||
|
new_edge_id = router_driver._get_edge_id_or_raise(context, router_id)
|
||||||
|
LOG.info(_LI("Router %(router)s was attached to edge %(edge)s"),
|
||||||
|
{'router': router_id, 'edge': new_edge_id})
|
||||||
|
|
||||||
|
|
||||||
|
registry.subscribe(nsx_recreate_router_edge,
|
||||||
|
constants.ROUTERS,
|
||||||
|
shell.Operations.NSX_RECREATE.value)
|
@ -127,6 +127,8 @@ nsxv_resources = {
|
|||||||
Operations.STATUS.value]),
|
Operations.STATUS.value]),
|
||||||
constants.LBAAS: Resource(constants.LBAAS,
|
constants.LBAAS: Resource(constants.LBAAS,
|
||||||
[Operations.NSX_MIGRATE_V1_V2.value]),
|
[Operations.NSX_MIGRATE_V1_V2.value]),
|
||||||
|
constants.ROUTERS: Resource(constants.ROUTERS,
|
||||||
|
[Operations.NSX_RECREATE.value]),
|
||||||
}
|
}
|
||||||
|
|
||||||
nsxv3_resources_names = list(nsxv3_resources.keys())
|
nsxv3_resources_names = list(nsxv3_resources.keys())
|
||||||
|
Loading…
Reference in New Issue
Block a user