Merge "Support for router admin-state-up"
This commit is contained in:
commit
b41632c936
@ -1261,9 +1261,6 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
return self.get_router(context, lrouter['id'])
|
||||
|
||||
def update_router(self, context, router_id, router):
|
||||
# TODO(berlin): admin_state_up update
|
||||
if router['router'].get('admin_state_up') is False:
|
||||
LOG.warning(_LW("admin_state_up=False router is not supported."))
|
||||
router_driver = self._find_router_driver(context, router_id)
|
||||
return router_driver.update_router(context, router_id, router)
|
||||
|
||||
@ -1342,6 +1339,14 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
router_driver = self._find_router_driver(context, router_id)
|
||||
router_driver._update_router_gw_info(context, router_id, info)
|
||||
|
||||
def _get_internal_network_ids_by_router(self, context, router_id):
|
||||
ports_qry = context.session.query(models_v2.Port)
|
||||
intf_ports = ports_qry.filter_by(
|
||||
device_id=router_id,
|
||||
device_owner=l3_db.DEVICE_OWNER_ROUTER_INTF).all()
|
||||
intf_net_ids = list(set([port['network_id'] for port in intf_ports]))
|
||||
return intf_net_ids
|
||||
|
||||
def _get_router_interface_ports_by_network(
|
||||
self, context, router_id, network_id):
|
||||
port_filters = {'device_id': [router_id],
|
||||
@ -1443,6 +1448,22 @@ class NsxVPluginV2(agents_db.AgentDbMixin,
|
||||
raise nsx_exc.ServiceOverQuota(overs="router-interface-add",
|
||||
err_msg=err_msg)
|
||||
|
||||
def _update_router_admin_state(self, context,
|
||||
router_id, router_type, admin_state):
|
||||
# Collecting all router interfaces and updating the connection status
|
||||
# for each one to reflect the router admin-state-up status.
|
||||
intf_net_ids = (
|
||||
self._get_internal_network_ids_by_router(context, router_id))
|
||||
for network_id in intf_net_ids:
|
||||
address_groups = (
|
||||
self._get_address_groups(context, router_id, network_id))
|
||||
update_args = (self.nsx_v, context, router_id, network_id,
|
||||
address_groups, admin_state)
|
||||
if router_type == 'distributed':
|
||||
edge_utils.update_vdr_internal_interface(*update_args)
|
||||
else:
|
||||
edge_utils.update_internal_interface(*update_args)
|
||||
|
||||
def add_router_interface(self, context, router_id, interface_info):
|
||||
router_driver = self._find_router_driver(context, router_id)
|
||||
return router_driver.add_router_interface(
|
||||
|
@ -86,6 +86,7 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver):
|
||||
self.edge_manager.create_lrouter(context, lrouter, dist=True)
|
||||
|
||||
def update_router(self, context, router_id, router):
|
||||
r = router['router']
|
||||
gw_info = self.plugin._extract_external_gw(context, router,
|
||||
is_extract=True)
|
||||
super(nsx_v.NsxVPluginV2, self.plugin).update_router(
|
||||
@ -98,6 +99,9 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver):
|
||||
nexthop = self.plugin._get_external_attachment_info(
|
||||
context, router_db)[2]
|
||||
self.update_routes(context, router_id, nexthop)
|
||||
if 'admin_state_up' in r:
|
||||
self.plugin._update_router_admin_state(
|
||||
context, router_id, self.get_type(), r['admin_state_up'])
|
||||
return self.plugin.get_router(context, router_id)
|
||||
|
||||
def delete_router(self, context, router_id):
|
||||
@ -178,9 +182,10 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver):
|
||||
address_groups = self.plugin._get_address_groups(
|
||||
context, router_id, network_id)
|
||||
try:
|
||||
edge_utils.add_vdr_internal_interface(
|
||||
self.nsx_v, context, router_id,
|
||||
network_id, address_groups)
|
||||
edge_utils.add_vdr_internal_interface(self.nsx_v, context,
|
||||
router_id, network_id,
|
||||
address_groups,
|
||||
router_db.admin_state_up)
|
||||
except n_exc.BadRequest:
|
||||
with excutils.save_and_reraise_exception():
|
||||
super(nsx_v.NsxVPluginV2, self.plugin).remove_router_interface(
|
||||
@ -325,20 +330,11 @@ class RouterDistributedDriver(router_driver.RouterBaseDriver):
|
||||
context, router_db)[2]
|
||||
self.update_routes(context, router_id, nexthop)
|
||||
|
||||
ports = self.plugin._get_router_interface_ports_by_network(
|
||||
context, router_id, network_id)
|
||||
self.plugin._update_subnets_and_dnat_firewall(context, router_db)
|
||||
# No subnet on the network connects to the edge vnic
|
||||
if not ports:
|
||||
edge_utils.delete_interface(self.nsx_v, context,
|
||||
router_id, network_id,
|
||||
dist=True)
|
||||
else:
|
||||
address_groups = self.plugin._get_address_groups(
|
||||
context, router_id, network_id)
|
||||
edge_utils.update_vdr_internal_interface(
|
||||
self.nsx_v, context, router_id,
|
||||
network_id, address_groups)
|
||||
# Safly remove interface, VDR can have interface to only one subnet in
|
||||
# a given network.
|
||||
edge_utils.delete_interface(
|
||||
self.nsx_v, context, router_id, network_id, dist=True)
|
||||
|
||||
if self.plugin.metadata_proxy_handler:
|
||||
# Detach network from VDR-dedicated DHCP Edge
|
||||
|
@ -36,6 +36,7 @@ class RouterExclusiveDriver(router_driver.RouterBaseDriver):
|
||||
lrouter['id'])
|
||||
|
||||
def update_router(self, context, router_id, router):
|
||||
r = router['router']
|
||||
gw_info = self.plugin._extract_external_gw(context, router,
|
||||
is_extract=True)
|
||||
super(nsx_v.NsxVPluginV2, self.plugin).update_router(
|
||||
@ -48,6 +49,9 @@ class RouterExclusiveDriver(router_driver.RouterBaseDriver):
|
||||
nexthop = self.plugin._get_external_attachment_info(
|
||||
context, router_db)[2]
|
||||
self.update_routes(context, router_id, nexthop)
|
||||
if 'admin_state_up' in r:
|
||||
self.plugin._update_router_admin_state(
|
||||
context, router_id, self.get_type(), r['admin_state_up'])
|
||||
return self.plugin.get_router(context, router_id)
|
||||
|
||||
def delete_router(self, context, router_id):
|
||||
@ -115,8 +119,9 @@ class RouterExclusiveDriver(router_driver.RouterBaseDriver):
|
||||
network_id = subnet['network_id']
|
||||
address_groups = self.plugin._get_address_groups(
|
||||
context, router_id, network_id)
|
||||
edge_utils.update_internal_interface(
|
||||
self.nsx_v, context, router_id, network_id, address_groups)
|
||||
edge_utils.update_internal_interface(self.nsx_v, context, router_id,
|
||||
network_id, address_groups,
|
||||
router_db['admin_state_up'])
|
||||
# Update edge's firewall rules to accept subnets flows.
|
||||
self.plugin._update_subnets_and_dnat_firewall(context, router_db)
|
||||
|
||||
|
@ -45,6 +45,7 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
pass
|
||||
|
||||
def update_router(self, context, router_id, router):
|
||||
r = router['router']
|
||||
edge_id = edge_utils.get_router_edge_id(context, router_id)
|
||||
if not edge_id:
|
||||
return super(nsx_v.NsxVPluginV2, self.plugin).update_router(
|
||||
@ -61,6 +62,15 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
# here is used to handle routes which tenant updates.
|
||||
if gw_info != attr.ATTR_NOT_SPECIFIED:
|
||||
self._update_router_gw_info(context, router_id, gw_info)
|
||||
if 'admin_state_up' in r:
|
||||
# If router was deployed on a different edge then
|
||||
# admin-state-up is already updated on the new edge.
|
||||
current_edge_id = (
|
||||
edge_utils.get_router_edge_id(context, router_id))
|
||||
if current_edge_id == edge_id:
|
||||
self.plugin._update_router_admin_state(context, router_id,
|
||||
self.get_type(),
|
||||
r['admin_state_up'])
|
||||
return self.plugin.get_router(context, router_id)
|
||||
|
||||
def delete_router(self, context, router_id):
|
||||
@ -184,6 +194,7 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
def update_routes(self, context, router_id, nexthop):
|
||||
edge_id = edge_utils.get_router_edge_id(context, router_id)
|
||||
if edge_id:
|
||||
router_db = self.plugin._get_router(context, router_id)
|
||||
available_router_ids, conflict_router_ids = (
|
||||
self._get_available_and_conflicting_ids(context, router_id))
|
||||
is_conflict = self.edge_manager.is_router_conflict_on_edge(
|
||||
@ -191,7 +202,8 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
if is_conflict:
|
||||
self._remove_router_services_on_edge(context, router_id)
|
||||
self._unbind_router_on_edge(context, router_id)
|
||||
self._bind_router_on_available_edge(context, router_id)
|
||||
self._bind_router_on_available_edge(
|
||||
context, router_id, router_db.admin_state_up)
|
||||
new_edge_id = edge_utils.get_router_edge_id(context,
|
||||
router_id)
|
||||
with lockutils.lock(str(new_edge_id),
|
||||
@ -435,7 +447,7 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
return optional_router_ids, conflict_router_ids
|
||||
|
||||
@lockutils.synchronized("router", "bind-", external=True)
|
||||
def _bind_router_on_available_edge(self, context, router_id):
|
||||
def _bind_router_on_available_edge(self, context, router_id, admin_state):
|
||||
conflict_network_ids, conflict_router_ids, intf_num = (
|
||||
self._get_conflict_network_and_router_ids_by_intf(context,
|
||||
router_id))
|
||||
@ -459,13 +471,15 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
lock_file_prefix=NSXV_ROUTER_RECONFIG,
|
||||
external=True):
|
||||
# add all internal interfaces of the router on edge
|
||||
intf_net_ids = self._get_internal_network_ids_by_router(
|
||||
context, router_id)
|
||||
intf_net_ids = (
|
||||
self.plugin._get_internal_network_ids_by_router(context,
|
||||
router_id))
|
||||
for network_id in intf_net_ids:
|
||||
address_groups = self.plugin._get_address_groups(
|
||||
context, router_id, network_id)
|
||||
edge_utils.update_internal_interface(
|
||||
self.nsx_v, context, router_id, network_id, address_groups)
|
||||
self.nsx_v, context, router_id, network_id,
|
||||
address_groups, admin_state)
|
||||
|
||||
def _unbind_router_on_edge(self, context, router_id):
|
||||
self.edge_manager.unbind_router_on_edge(context, router_id)
|
||||
@ -473,14 +487,6 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
if metadata_proxy_handler:
|
||||
metadata_proxy_handler.cleanup_router_edge(router_id)
|
||||
|
||||
def _get_internal_network_ids_by_router(self, context, router_id):
|
||||
ports_qry = context.session.query(models_v2.Port)
|
||||
intf_ports = ports_qry.filter_by(
|
||||
device_id=router_id,
|
||||
device_owner=l3_db.DEVICE_OWNER_ROUTER_INTF).all()
|
||||
intf_net_ids = list(set([port['network_id'] for port in intf_ports]))
|
||||
return intf_net_ids
|
||||
|
||||
def _add_router_services_on_available_edge(self, context, router_id):
|
||||
router_ids = self.edge_manager.get_routers_on_same_edge(
|
||||
context, router_id)
|
||||
@ -503,8 +509,9 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
self._update_nat_rules_on_routers(context, router_id, router_ids)
|
||||
self._update_external_interface_on_routers(
|
||||
context, router_id, router_ids)
|
||||
intf_net_ids = self._get_internal_network_ids_by_router(
|
||||
context, router_id)
|
||||
intf_net_ids = (
|
||||
self.plugin._get_internal_network_ids_by_router(context,
|
||||
router_id))
|
||||
if intf_net_id:
|
||||
intf_net_ids.remove(intf_net_id)
|
||||
for net_id in intf_net_ids:
|
||||
@ -595,7 +602,8 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
self._update_routes_on_routers(
|
||||
context, router_id, router_ids)
|
||||
if is_migrated:
|
||||
self._bind_router_on_available_edge(context, router_id)
|
||||
self._bind_router_on_available_edge(
|
||||
context, router_id, router.admin_state_up)
|
||||
edge_id = edge_utils.get_router_edge_id(context, router_id)
|
||||
with lockutils.lock(str(edge_id),
|
||||
lock_file_prefix=NSXV_ROUTER_RECONFIG,
|
||||
@ -606,6 +614,7 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
def add_router_interface(self, context, router_id, interface_info):
|
||||
self.plugin._check_intf_number_of_router(context, router_id)
|
||||
edge_id = edge_utils.get_router_edge_id(context, router_id)
|
||||
router_db = self.plugin._get_router(context, router_id)
|
||||
if edge_id:
|
||||
is_migrated = False
|
||||
with lockutils.lock(str(edge_id),
|
||||
@ -616,7 +625,6 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
info = super(nsx_v.NsxVPluginV2,
|
||||
self.plugin).add_router_interface(
|
||||
context, router_id, interface_info)
|
||||
router_db = self.plugin._get_router(context, router_id)
|
||||
subnet = self.plugin.get_subnet(context, info['subnet_id'])
|
||||
network_id = subnet['network_id']
|
||||
# Collect all conflict networks whose cidr are overlapped
|
||||
@ -659,7 +667,7 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
context, router_id, network_id)
|
||||
edge_utils.update_internal_interface(
|
||||
self.nsx_v, context, router_id,
|
||||
network_id, address_groups)
|
||||
network_id, address_groups, router_db.admin_state_up)
|
||||
if router_db.gw_port and router_db.enable_snat:
|
||||
self._update_nat_rules_on_routers(
|
||||
context, router_id, router_ids)
|
||||
@ -667,7 +675,7 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
context, router_id, router_ids, allow_external=True)
|
||||
if is_migrated:
|
||||
self._bind_router_on_available_edge(
|
||||
context, router_id)
|
||||
context, router_id, router_db.admin_state_up)
|
||||
edge_id = edge_utils.get_router_edge_id(context, router_id)
|
||||
with lockutils.lock(str(edge_id),
|
||||
lock_file_prefix=NSXV_ROUTER_RECONFIG,
|
||||
@ -678,7 +686,8 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
info = super(nsx_v.NsxVPluginV2, self.plugin).add_router_interface(
|
||||
context, router_id, interface_info)
|
||||
# bind and configure routing servie on an availab edge
|
||||
self._bind_router_on_available_edge(context, router_id)
|
||||
self._bind_router_on_available_edge(
|
||||
context, router_id, router_db.admin_state_up)
|
||||
edge_id = edge_utils.get_router_edge_id(context, router_id)
|
||||
with lockutils.lock(str(edge_id),
|
||||
lock_file_prefix=NSXV_ROUTER_RECONFIG,
|
||||
@ -708,8 +717,8 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
|
||||
edge_utils.delete_interface(self.nsx_v, context,
|
||||
router_id, network_id)
|
||||
# unbind all services if no interfaces attached to the router
|
||||
if not self._get_internal_network_ids_by_router(
|
||||
context, router_id):
|
||||
if not self.plugin._get_internal_network_ids_by_router(
|
||||
context, router_id):
|
||||
self._remove_router_services_on_edge(context, router_id)
|
||||
self._unbind_router_on_edge(context, router_id)
|
||||
else:
|
||||
|
@ -233,7 +233,7 @@ class EdgeApplianceDriver(object):
|
||||
|
||||
def update_interface(self, router_id, edge_id, index, network,
|
||||
tunnel_index=-1, address=None, netmask=None,
|
||||
secondary=None, jobdata=None,
|
||||
secondary=None, jobdata=None, is_connected=True,
|
||||
address_groups=None):
|
||||
LOG.debug("VCNS: update vnic %(index)d: %(addr)s %(netmask)s", {
|
||||
'index': index, 'addr': address, 'netmask': netmask})
|
||||
@ -250,21 +250,21 @@ class EdgeApplianceDriver(object):
|
||||
config = self._assemble_edge_vnic(
|
||||
name, index, network, tunnel_index,
|
||||
address, netmask, secondary, type=intf_type,
|
||||
address_groups=address_groups)
|
||||
address_groups=address_groups, is_connected=is_connected)
|
||||
|
||||
self.vcns.update_interface(edge_id, config)
|
||||
|
||||
def add_vdr_internal_interface(self, edge_id,
|
||||
network, address=None, netmask=None,
|
||||
secondary=None, address_groups=None,
|
||||
type="internal"):
|
||||
type="internal", is_connected=True):
|
||||
LOG.debug("Add VDR interface on edge: %s", edge_id)
|
||||
if address_groups is None:
|
||||
address_groups = []
|
||||
interface_req = self._assemble_vdr_interface(
|
||||
network, address, netmask, secondary,
|
||||
address_groups=address_groups,
|
||||
type=type)
|
||||
interface_req = (
|
||||
self._assemble_vdr_interface(network, address, netmask, secondary,
|
||||
address_groups=address_groups,
|
||||
is_connected=is_connected, type=type))
|
||||
self.vcns.add_vdr_internal_interface(edge_id, interface_req)
|
||||
header, response = self.vcns.get_edge_interfaces(edge_id)
|
||||
for interface in response['interfaces']:
|
||||
@ -273,13 +273,17 @@ class EdgeApplianceDriver(object):
|
||||
return vnic_index
|
||||
|
||||
def update_vdr_internal_interface(self, edge_id, index, network,
|
||||
address=None, netmask=None,
|
||||
secondary=None, address_groups=None):
|
||||
address_groups=None, is_connected=True):
|
||||
if not address_groups:
|
||||
address_groups = []
|
||||
interface_req = self._assemble_vdr_interface(
|
||||
network, address, netmask, secondary,
|
||||
address_groups=address_groups)
|
||||
interface = {
|
||||
'type': 'internal',
|
||||
'connectedToId': network,
|
||||
'mtu': 1500,
|
||||
'isConnected': is_connected,
|
||||
'addressGroups': {'addressGroup': address_groups}
|
||||
}
|
||||
interface_req = {'interface': interface}
|
||||
try:
|
||||
header, response = self.vcns.update_vdr_internal_interface(
|
||||
edge_id, index, interface_req)
|
||||
|
@ -1392,8 +1392,8 @@ def update_external_interface(
|
||||
secondary=secondary)
|
||||
|
||||
|
||||
def update_internal_interface(
|
||||
nsxv_manager, context, router_id, int_net_id, address_groups):
|
||||
def update_internal_interface(nsxv_manager, context, router_id, int_net_id,
|
||||
address_groups, is_connected=True):
|
||||
# Get the pg/wire id of the network id
|
||||
mappings = nsx_db.get_nsx_switch_ids(context.session, int_net_id)
|
||||
if mappings:
|
||||
@ -1416,11 +1416,12 @@ def update_internal_interface(
|
||||
nsxv_manager.update_interface(router_id, edge_id,
|
||||
edge_vnic_binding.vnic_index,
|
||||
vcns_network_id,
|
||||
is_connected=is_connected,
|
||||
address_groups=address_groups)
|
||||
|
||||
|
||||
def add_vdr_internal_interface(
|
||||
nsxv_manager, context, router_id, int_net_id, address_groups):
|
||||
def add_vdr_internal_interface(nsxv_manager, context, router_id,
|
||||
int_net_id, address_groups, is_connected=True):
|
||||
# Get the pg/wire id of the network id
|
||||
mappings = nsx_db.get_nsx_switch_ids(context.session, int_net_id)
|
||||
if mappings:
|
||||
@ -1435,8 +1436,8 @@ def add_vdr_internal_interface(
|
||||
context.session, edge_id, int_net_id)
|
||||
if not edge_vnic_binding:
|
||||
vnic_index = nsxv_manager.add_vdr_internal_interface(
|
||||
edge_id, vcns_network_id,
|
||||
address_groups=address_groups)
|
||||
edge_id, vcns_network_id, address_groups=address_groups,
|
||||
is_connected=is_connected)
|
||||
nsxv_db.create_edge_vnic_binding(
|
||||
context.session, edge_id, vnic_index, int_net_id)
|
||||
else:
|
||||
@ -1445,8 +1446,8 @@ def add_vdr_internal_interface(
|
||||
raise n_exc.BadRequest(resource='vdr', msg=msg)
|
||||
|
||||
|
||||
def update_vdr_internal_interface(
|
||||
nsxv_manager, context, router_id, int_net_id, address_groups):
|
||||
def update_vdr_internal_interface(nsxv_manager, context, router_id, int_net_id,
|
||||
address_groups, is_connected=True):
|
||||
# Get the pg/wire id of the network id
|
||||
mappings = nsx_db.get_nsx_switch_ids(context.session, int_net_id)
|
||||
if mappings:
|
||||
@ -1459,10 +1460,10 @@ def update_vdr_internal_interface(
|
||||
binding = nsxv_db.get_nsxv_router_binding(context.session, router_id)
|
||||
edge_id = binding['edge_id']
|
||||
edge_vnic_binding = nsxv_db.get_edge_vnic_binding(
|
||||
context.session, edge_id, binding.network_id)
|
||||
context.session, edge_id, int_net_id)
|
||||
nsxv_manager.update_vdr_internal_interface(
|
||||
edge_id, edge_vnic_binding.vnic_index,
|
||||
vcns_network_id, address_groups=address_groups)
|
||||
edge_id, edge_vnic_binding.vnic_index, vcns_network_id,
|
||||
address_groups=address_groups, is_connected=is_connected)
|
||||
|
||||
|
||||
def delete_interface(nsxv_manager, context, router_id, network_id,
|
||||
|
@ -140,11 +140,12 @@ class Vcns(object):
|
||||
edge_id)
|
||||
return self.do_request(HTTP_POST, uri, interface, decode=True)
|
||||
|
||||
def update_vdr_internal_interface(
|
||||
self, edge_id, interface_index, interface):
|
||||
def update_vdr_internal_interface(self, edge_id,
|
||||
interface_index, interface):
|
||||
uri = "%s/%s/interfaces/%s?async=true" % (URI_PREFIX, edge_id,
|
||||
interface_index)
|
||||
return self.do_request(HTTP_PUT, uri, interface, decode=True)
|
||||
return self.do_request(HTTP_PUT, uri, interface,
|
||||
format='xml', decode=True)
|
||||
|
||||
def delete_vdr_internal_interface(self, edge_id, interface_index):
|
||||
uri = "%s/%s/interfaces/%d?async=true" % (URI_PREFIX, edge_id,
|
||||
|
Loading…
Reference in New Issue
Block a user