Merge "Support for router admin-state-up"

This commit is contained in:
Jenkins 2015-06-07 10:40:31 +00:00 committed by Gerrit Code Review
commit b41632c936
7 changed files with 106 additions and 69 deletions

View File

@ -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(

View File

@ -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

View File

@ -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)

View File

@ -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,7 +717,7 @@ 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(
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)

View File

@ -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,
interface_req = (
self._assemble_vdr_interface(network, address, netmask, secondary,
address_groups=address_groups,
type=type)
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)

View File

@ -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,

View File

@ -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,