Merge "Adds support for multiple subnets per external network"
This commit is contained in:
commit
1ba5e69f4d
|
@ -107,8 +107,6 @@ else:
|
|||
|
||||
|
||||
core_opts = base_config.core_opts
|
||||
#extensions = extensions
|
||||
#model_base = model_base
|
||||
|
||||
# Bring in the union of all constants in neutron.common.constants
|
||||
# and neutron_lib.constants. Handle any duplicates by using the
|
||||
|
|
|
@ -524,12 +524,97 @@ def _mock_stuff():
|
|||
pingable_patcher.start()
|
||||
|
||||
|
||||
# NOTE(bobmel): call mock_ncclient() in main() of cfg_agent.py to run config
|
||||
# agent with a fake ncclient. That mocked mode of running the config agent is
|
||||
# useful for end-2-end-like debugging without actual backend hosting devices.
|
||||
def mock_ncclient():
|
||||
import mock
|
||||
from ncclient.transport import errors as ncc_exc
|
||||
from networking_cisco.plugins.cisco.common import (cisco_ios_xe_simulator
|
||||
as cisco_ios_xe)
|
||||
import os
|
||||
|
||||
def _fake_connect(host, port, username, password, device_params, timeout):
|
||||
sim = cisco_ios_xe.CiscoIOSXESimulator(
|
||||
'', host, "255.255.255.0", port, username, password,
|
||||
device_params, "GigabitEthernet0", timeout)
|
||||
connection_mock = mock.MagicMock()
|
||||
connection_mock.edit_config.side_effect = _get_fake_edit_config(sim)
|
||||
connection_mock.get_config.side_effect = (
|
||||
_get_fake_get_config(sim))
|
||||
return connection_mock
|
||||
|
||||
def _get_fake_edit_config(simulator):
|
||||
|
||||
def edit_config(config, format='xml', target='candidate',
|
||||
default_operation=None, test_option=None,
|
||||
error_option=None):
|
||||
if not _fake_is_pingable(rc_emul.host_ip):
|
||||
raise ncc_exc.SSHError('SSH error')
|
||||
rc_emul.edit_config(config)
|
||||
print(rc_emul.get_config())
|
||||
return ok_xml_obj
|
||||
|
||||
ok_xml_obj = mock.MagicMock()
|
||||
ok_xml_obj.xml = "<ok />"
|
||||
rc_emul = simulator
|
||||
return edit_config
|
||||
|
||||
def _get_fake_get_config(simulator):
|
||||
|
||||
def get_running_config(source):
|
||||
if not _fake_is_pingable(rc_emul.host_ip):
|
||||
raise ncc_exc.SSHError('SSH error')
|
||||
head = ('<?xml version="1.0" encoding="UTF-8"?><rpc-reply '
|
||||
'message-id="urn:uuid:ec8bab72-a500-11e5-a92f'
|
||||
'-74a2e6d55908" xmlns="urn:ietf:params:xml:ns:netconf:'
|
||||
'base:1.0"><data><cli-config-data-block>!')
|
||||
tail = '</cli-config-data-block></data></rpc-reply>'
|
||||
raw_rc = rc_emul.get_config()
|
||||
return cisco_ios_xe.FakeRunningConfig(head + raw_rc + tail)
|
||||
|
||||
rc_emul = simulator
|
||||
return get_running_config
|
||||
|
||||
def _fake_is_pingable(ip):
|
||||
# if a file with a certain name (derived from the 'ip' argument):
|
||||
#
|
||||
# /opt/stack/data/neutron/DEAD__10_0_5_8 (ip = 10.0.5.8)
|
||||
#
|
||||
# exists then the (faked) hosting device with that IP address
|
||||
# will appear to NOT respond to pings
|
||||
path = '/opt/stack/data/neutron'
|
||||
indicator_filename = path + '/DEAD_' + str(ip).replace('.', '_')
|
||||
return not os.path.isfile(indicator_filename)
|
||||
|
||||
targets = ['networking_cisco.plugins.cisco.cfg_agent.device_drivers.'
|
||||
'csr1kv.csr1kv_routing_driver.manager',
|
||||
'networking_cisco.plugins.cisco.cfg_agent.device_drivers.'
|
||||
'csr1kv.iosxe_routing_driver.manager']
|
||||
ncc_patchers = []
|
||||
ncclient_mgr_mock = mock.MagicMock()
|
||||
ncclient_mgr_mock.connect.side_effect = _fake_connect
|
||||
|
||||
for target in targets:
|
||||
patcher = mock.patch(target, ncclient_mgr_mock)
|
||||
patcher.start()
|
||||
ncc_patchers.append(patcher)
|
||||
|
||||
is_pingable_mock = mock.MagicMock()
|
||||
is_pingable_mock.side_effect = _fake_is_pingable
|
||||
pingable_patcher = mock.patch(
|
||||
'networking_cisco.plugins.cisco.cfg_agent.device_status._is_pingable',
|
||||
is_pingable_mock)
|
||||
pingable_patcher.start()
|
||||
|
||||
|
||||
def main(manager='networking_cisco.plugins.cisco.cfg_agent.'
|
||||
'cfg_agent.CiscoCfgAgentWithStateReport'):
|
||||
# NOTE(bobmel): call _mock_stuff() to run config agent with fake ncclient
|
||||
# This mocked mode of running the config agent is useful for end-2-end-like
|
||||
# debugging without actual backend hosting devices.
|
||||
#_mock_stuff()
|
||||
#mock_ncclient()
|
||||
conf = cfg.CONF
|
||||
conf.register_opts(OPTS, "cfg_agent")
|
||||
config.register_agent_state_opts_helper(conf)
|
||||
|
|
|
@ -34,6 +34,8 @@ LOG = logging.getLogger(__name__)
|
|||
|
||||
|
||||
ROUTER_ROLE_ATTR = routerrole.ROUTER_ROLE_ATTR
|
||||
ROUTER_ROLE_HA_REDUNDANCY = cisco_constants.ROUTER_ROLE_HA_REDUNDANCY
|
||||
|
||||
|
||||
NROUTER_REGEX = "nrouter-(\w{6,6})"
|
||||
NROUTER_MULTI_REGION_REGEX = "nrouter-(\w{6,6})-(\w{1,7})"
|
||||
|
@ -44,12 +46,12 @@ VRF_REGEX_NEW = "vrf definition " + NROUTER_REGEX
|
|||
VRF_MULTI_REGION_REGEX = "ip vrf " + NROUTER_MULTI_REGION_REGEX
|
||||
VRF_MULTI_REGION_REGEX_NEW = "vrf definition " + NROUTER_MULTI_REGION_REGEX
|
||||
|
||||
#INTF_NAME_REGEX = "(PortChannel\d+|\d+Ethernet\d+\/d+\/d+)"
|
||||
|
||||
INTF_REGEX = "interface \S+\.(\d+)"
|
||||
INTF_DESC_REGEX = "\s*description OPENSTACK_NEUTRON_INTF"
|
||||
INTF_DESC_MULTI_REGION_REGEX = ("\s*description"
|
||||
" OPENSTACK_NEUTRON_(\w{1,7})_INTF")
|
||||
INTF_DESC_REGEX = (
|
||||
"\s*description OPENSTACK_NEUTRON_INTF|OPENSTACK_NEUTRON_EXTERNAL_INTF")
|
||||
INTF_DESC_MULTI_REGION_REGEX = (
|
||||
"\s*description OPENSTACK_NEUTRON_(\w{1,7})_INTF|"
|
||||
"OPENSTACK_NEUTRON_EXTERNAL_(\w{1,7})_INTF")
|
||||
VRF_EXT_INTF_REGEX = "\s*ip vrf forwarding .*"
|
||||
VRF_INTF_REGEX = "\s*ip vrf forwarding " + NROUTER_REGEX
|
||||
VRF_INTF_MULTI_REGION_REGEX = ("\s*ip vrf forwarding " +
|
||||
|
@ -219,9 +221,13 @@ class ConfigSyncer(object):
|
|||
interface_segment_dict[segment_id] = []
|
||||
if segment_id not in segment_nat_dict:
|
||||
segment_nat_dict[segment_id] = False
|
||||
interface['is_external'] = (
|
||||
router[ROUTER_ROLE_ATTR] ==
|
||||
cisco_constants.ROUTER_ROLE_GLOBAL)
|
||||
if (router[ROUTER_ROLE_ATTR] ==
|
||||
cisco_constants.ROUTER_ROLE_GLOBAL):
|
||||
interface['is_external'] = True
|
||||
if (segment_id not in self.segment_gw_dict):
|
||||
self.segment_gw_dict[segment_id] = [interface]
|
||||
else:
|
||||
interface['is_external'] = False
|
||||
interface_segment_dict[segment_id].append(interface)
|
||||
|
||||
# Mark which segments have NAT enabled
|
||||
|
@ -235,16 +241,16 @@ class ConfigSyncer(object):
|
|||
cisco_constants.ROUTER_ROLE_GLOBAL):
|
||||
|
||||
if (gw_segment_id not in self.segment_gw_dict):
|
||||
self.segment_gw_dict[gw_segment_id] = gw_port
|
||||
self.segment_gw_dict[gw_segment_id] = [gw_port]
|
||||
|
||||
if '_interfaces' in router.keys():
|
||||
interfaces = router['_interfaces']
|
||||
for intf in interfaces:
|
||||
if intf['device_owner'] == \
|
||||
bc.constants.DEVICE_OWNER_ROUTER_INTF:
|
||||
if (intf['device_owner'] ==
|
||||
bc.constants.DEVICE_OWNER_ROUTER_INTF):
|
||||
if is_port_v6(intf) is not True:
|
||||
intf_segment_id = \
|
||||
intf['hosting_info']['segmentation_id']
|
||||
intf_segment_id = (
|
||||
intf['hosting_info']['segmentation_id'])
|
||||
segment_nat_dict[gw_segment_id] = True
|
||||
segment_nat_dict[intf_segment_id] = True
|
||||
|
||||
|
@ -261,7 +267,6 @@ class ConfigSyncer(object):
|
|||
LOG.info(_LI("neutron router db records"))
|
||||
|
||||
for router_id, router in six.iteritems(router_id_dict):
|
||||
#LOG.info("ROUTER ID: %s DATA: %s\n\n" % (router_id, router))
|
||||
LOG.info(_LI("ROUTER_ID: %s"), router_id)
|
||||
|
||||
LOG.info(_LI("\n"))
|
||||
|
@ -451,17 +456,18 @@ class ConfigSyncer(object):
|
|||
continue
|
||||
|
||||
# Check IPs and netmask
|
||||
# TODO(sridar) rework this to old model, further
|
||||
# investigation needed and cleanup.
|
||||
# pool_info = router['gw_port']['nat_pool_info']
|
||||
# pool_ip = pool_info['pool_ip']
|
||||
# pool_net = netaddr.IPNetwork(pool_info['pool_cidr'])
|
||||
pool_ip = str(router['gw_port']['fixed_ips'][0]['ip_address'])
|
||||
# pool_net = router['gw_port']['subnets'][0]['cidr']
|
||||
pool_net = netaddr.IPNetwork(
|
||||
router['gw_port']['subnets'][0]['cidr'])
|
||||
if router.get(ROUTER_ROLE_ATTR) == ROUTER_ROLE_HA_REDUNDANCY:
|
||||
the_port = router['gw_port'][ha.HA_INFO]['ha_port']
|
||||
else:
|
||||
the_port = router['gw_port']
|
||||
found = False
|
||||
for i in range(len(the_port['fixed_ips'])):
|
||||
pool_ip = str(the_port['fixed_ips'][i]['ip_address'])
|
||||
if start_ip == pool_ip:
|
||||
found = True
|
||||
break
|
||||
|
||||
if start_ip != pool_ip:
|
||||
if found is False:
|
||||
LOG.info(_LI("start IP %(start_ip)s for "
|
||||
"pool does not match %(pool_ip)s, deleting") %
|
||||
{'start_ip': start_ip, 'pool_ip': pool_ip})
|
||||
|
@ -473,6 +479,7 @@ class ConfigSyncer(object):
|
|||
delete_pool_list.append(pool.text)
|
||||
continue
|
||||
|
||||
pool_net = netaddr.IPNetwork(the_port['subnets'][i]['cidr'])
|
||||
if netmask != str(pool_net.netmask):
|
||||
LOG.info(
|
||||
_LI("netmask for pool does not match, netmask:%(netmask)s,"
|
||||
|
@ -557,8 +564,17 @@ class ConfigSyncer(object):
|
|||
continue
|
||||
|
||||
# Check that nexthop matches gw_ip of external network
|
||||
gw_ip = gw_port['subnets'][0]['gateway_ip']
|
||||
if next_hop.lower() != gw_ip.lower():
|
||||
if router.get(ROUTER_ROLE_ATTR) == ROUTER_ROLE_HA_REDUNDANCY:
|
||||
the_port = router['gw_port'][ha.HA_INFO]['ha_port']
|
||||
else:
|
||||
the_port = router['gw_port']
|
||||
found = False
|
||||
for i in range(len(the_port['subnets'])):
|
||||
gw_ip = the_port['subnets'][i]['gateway_ip']
|
||||
if next_hop.lower() == gw_ip.lower():
|
||||
found = True
|
||||
break
|
||||
if found is False:
|
||||
LOG.info(_LI("route has incorrect next-hop, deleting"))
|
||||
delete_route_list.append(route.text)
|
||||
continue
|
||||
|
@ -644,8 +660,6 @@ class ConfigSyncer(object):
|
|||
|
||||
# Check that hsrp group name is correct
|
||||
gw_port = router['gw_port']
|
||||
#gw_net_id = gw_port['network_id']
|
||||
#gw_hsrp_num = self._get_hsrp_grp_num_from_net_id(gw_net_id)
|
||||
gw_hsrp_num = int(gw_port[ha.HA_INFO]['group'])
|
||||
gw_segment_id = int(gw_port['hosting_info']['segmentation_id'])
|
||||
if segment_id != gw_segment_id:
|
||||
|
@ -889,14 +903,18 @@ class ConfigSyncer(object):
|
|||
checks running-cfg derived ip_addr and netmask against neutron-db
|
||||
gw_port
|
||||
"""
|
||||
if (gw_port is not None):
|
||||
target_ip = gw_port['fixed_ips'][0]['ip_address']
|
||||
target_net = netaddr.IPNetwork(gw_port['subnets'][0]['cidr'])
|
||||
|
||||
if (ip_addr != target_ip):
|
||||
if gw_port is not None:
|
||||
found = False
|
||||
for i in range(len(gw_port['fixed_ips'])):
|
||||
target_ip = gw_port['fixed_ips'][i]['ip_address']
|
||||
if ip_addr == target_ip:
|
||||
found = True
|
||||
break
|
||||
if found is False:
|
||||
LOG.info(_LI("Subintf real IP is incorrect, deleting"))
|
||||
return False
|
||||
if (netmask != str(target_net.netmask)):
|
||||
target_net = netaddr.IPNetwork(gw_port['subnets'][i]['cidr'])
|
||||
if netmask != str(target_net.netmask):
|
||||
LOG.info(_LI("Subintf has incorrect netmask, deleting"))
|
||||
return False
|
||||
|
||||
|
@ -904,7 +922,7 @@ class ConfigSyncer(object):
|
|||
|
||||
return False
|
||||
|
||||
def subintf_real_ip_check(self, intf_list, is_external, ip_addr, netmask):
|
||||
def subintf_real_ip_check(self, intf_list, ip_addr, netmask):
|
||||
|
||||
for target_intf in intf_list:
|
||||
target_ip = target_intf['fixed_ips'][0]['ip_address']
|
||||
|
@ -972,18 +990,16 @@ class ConfigSyncer(object):
|
|||
|
||||
def gw_port_hsrp_ip_check(self, gw_port, ip_addr):
|
||||
|
||||
if (gw_port is not None):
|
||||
if gw_port is not None:
|
||||
ha_port = gw_port[ha.HA_INFO]['ha_port']
|
||||
|
||||
target_ip = ha_port['fixed_ips'][0]['ip_address']
|
||||
LOG.info(_LI("target_ip: %(target_ip)s, actual_ip: %(ip_addr)s") %
|
||||
{'target_ip': target_ip,
|
||||
'ip_addr': ip_addr})
|
||||
if ip_addr != target_ip:
|
||||
LOG.info(_LI("HSRP VIP mismatch on gw_port, deleting"))
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
for fixed_ip in ha_port['fixed_ips']:
|
||||
target_ip = fixed_ip['ip_address']
|
||||
LOG.info(_LI("target_ip: %(target_ip)s, "
|
||||
"actual_ip: %(ip_addr)s") %
|
||||
{'target_ip': target_ip, 'ip_addr': ip_addr})
|
||||
if ip_addr == target_ip:
|
||||
return True
|
||||
LOG.info(_LI("HSRP VIP mismatch on gw_port, deleting"))
|
||||
return False
|
||||
|
||||
def subintf_hsrp_ip_check(self, intf_list, is_external, ip_addr):
|
||||
|
@ -1043,19 +1059,29 @@ class ConfigSyncer(object):
|
|||
def clean_interfaces_ipv4_hsrp_check(self, intf, intf_db_dict):
|
||||
# Check HSRP VIP
|
||||
hsrp_vip_cfg_list = intf.re_search_children(HSRP_V4_VIP_REGEX)
|
||||
if len(hsrp_vip_cfg_list) < 1:
|
||||
num_vips = len(hsrp_vip_cfg_list)
|
||||
num_vips_db = len(intf_db_dict[intf.segment_id][0]['fixed_ips'])
|
||||
if num_vips < 1:
|
||||
LOG.info(_LI("Interface is missing HSRP VIP, deleting"))
|
||||
return False
|
||||
|
||||
hsrp_vip_cfg = hsrp_vip_cfg_list[0]
|
||||
match_obj = re.match(HSRP_V4_VIP_REGEX, hsrp_vip_cfg.text)
|
||||
hsrp_vip_grp_num, hsrp_vip = match_obj.group(1, 2)
|
||||
elif num_vips != num_vips_db:
|
||||
LOG.info(_LI("Subintf has wrong number of HSRP VIP addresses ("
|
||||
"should have %(n_v)d, but has %(n_v_d)d), deleting"),
|
||||
{'n_v': num_vips, 'n_v_d': num_vips_db})
|
||||
return False
|
||||
|
||||
if intf.is_external:
|
||||
return self.gw_port_hsrp_ip_check(
|
||||
intf_db_dict[intf.segment_id],
|
||||
hsrp_vip)
|
||||
for hsrp_vip_cfg in hsrp_vip_cfg_list:
|
||||
match_obj = re.match(HSRP_V4_VIP_REGEX, hsrp_vip_cfg.text)
|
||||
hsrp_vip_grp_num, hsrp_vip = match_obj.group(1, 2)
|
||||
if self.gw_port_hsrp_ip_check(intf_db_dict[intf.segment_id][0],
|
||||
hsrp_vip) is False:
|
||||
return False
|
||||
return True
|
||||
else:
|
||||
hsrp_vip_cfg = hsrp_vip_cfg_list[0]
|
||||
match_obj = re.match(HSRP_V4_VIP_REGEX, hsrp_vip_cfg.text)
|
||||
hsrp_vip_grp_num, hsrp_vip = match_obj.group(1, 2)
|
||||
return self.subintf_hsrp_ip_check(
|
||||
intf_db_dict[intf.segment_id],
|
||||
intf.is_external,
|
||||
|
@ -1065,23 +1091,32 @@ class ConfigSyncer(object):
|
|||
|
||||
# Check that real IP address is correct
|
||||
ipv4_addr = intf.re_search_children(INTF_V4_ADDR_REGEX)
|
||||
if len(ipv4_addr) < 1:
|
||||
num_addrs = len(ipv4_addr)
|
||||
num_addrs_db = len(intf_db_dict[intf.segment_id][0]['fixed_ips'])
|
||||
if num_addrs < 1:
|
||||
LOG.info(_LI("Subintf has no IP address, deleting"))
|
||||
return False
|
||||
|
||||
ipv4_addr_cfg = ipv4_addr[0]
|
||||
match_obj = re.match(INTF_V4_ADDR_REGEX, ipv4_addr_cfg.text)
|
||||
ip_addr, netmask = match_obj.group(1, 2)
|
||||
elif num_addrs != num_addrs_db:
|
||||
LOG.info(_LI("Subintf has wrong number of addresses (should have "
|
||||
"%(n_a)d, but has %(n_a_d)d), deleting"), num_addrs,
|
||||
num_addrs_db)
|
||||
return False
|
||||
|
||||
if intf.is_external:
|
||||
return self.subintf_real_ip_check_gw_port(
|
||||
intf_db_dict[intf.segment_id],
|
||||
ip_addr, netmask)
|
||||
for ipv4_addr_cfg in ipv4_addr:
|
||||
match_obj = re.match(INTF_V4_ADDR_REGEX, ipv4_addr_cfg.text)
|
||||
ip_addr, netmask = match_obj.group(1, 2)
|
||||
if (self.subintf_real_ip_check_gw_port(
|
||||
intf_db_dict[intf.segment_id][0], ip_addr, netmask) is
|
||||
False):
|
||||
return False
|
||||
return True
|
||||
else:
|
||||
ipv4_addr_cfg = ipv4_addr[0]
|
||||
match_obj = re.match(INTF_V4_ADDR_REGEX, ipv4_addr_cfg.text)
|
||||
ip_addr, netmask = match_obj.group(1, 2)
|
||||
return self.subintf_real_ip_check(
|
||||
intf_db_dict[intf.segment_id],
|
||||
intf.is_external,
|
||||
ip_addr, netmask)
|
||||
intf_db_dict[intf.segment_id], ip_addr, netmask)
|
||||
|
||||
def clean_interfaces_ipv6_check(self, intf, intf_segment_dict):
|
||||
# Check that real IP address is correct
|
||||
|
@ -1188,11 +1223,10 @@ class ConfigSyncer(object):
|
|||
|
||||
# Is this an "external network" segment_id?
|
||||
if intf.is_external:
|
||||
db_intf = self.segment_gw_dict[intf.segment_id]
|
||||
db_intf = self.segment_gw_dict[intf.segment_id][0]
|
||||
else:
|
||||
db_intf = intf_segment_dict[intf.segment_id][0]
|
||||
|
||||
# intf.is_external = db_intf['is_external']
|
||||
intf.has_ipv6 = is_port_v6(db_intf)
|
||||
|
||||
# Check VRF config
|
||||
|
@ -1251,8 +1285,6 @@ class ConfigSyncer(object):
|
|||
pending_delete_list.append(intf)
|
||||
continue
|
||||
|
||||
# self.existing_cfg_dict['interfaces'][intf.segment_id] = intf
|
||||
|
||||
correct_grp_num = int(db_intf[ha.HA_INFO]['group'])
|
||||
|
||||
if intf.is_external:
|
||||
|
@ -1262,43 +1294,33 @@ class ConfigSyncer(object):
|
|||
|
||||
if intf.has_ipv6 is False:
|
||||
if self.clean_interfaces_nat_check(intf,
|
||||
segment_nat_dict) \
|
||||
is False:
|
||||
segment_nat_dict) is False:
|
||||
pending_delete_list.append(intf)
|
||||
continue
|
||||
if self.clean_interfaces_ipv4_check(intf,
|
||||
intf_db) \
|
||||
is False:
|
||||
if self.clean_interfaces_ipv4_check(intf, intf_db) is False:
|
||||
pending_delete_list.append(intf)
|
||||
continue
|
||||
if self.clean_interfaces_ipv4_hsrp_check(intf,
|
||||
intf_db) \
|
||||
is False:
|
||||
intf_db) is False:
|
||||
pending_delete_list.append(intf)
|
||||
continue
|
||||
else:
|
||||
if self.clean_interfaces_ipv6_check(intf, intf_db) \
|
||||
is False:
|
||||
if self.clean_interfaces_ipv6_check(intf, intf_db) is False:
|
||||
pending_delete_list.append(intf)
|
||||
continue
|
||||
|
||||
# Delete if there's any hsrp config with wrong group number
|
||||
#del_hsrp_cmd = XML_CMD_TAG % (intf.text)
|
||||
hsrp_cfg_list = intf.re_search_children(HSRP_REGEX)
|
||||
needs_hsrp_delete = False
|
||||
for hsrp_cfg in hsrp_cfg_list:
|
||||
hsrp_num = int(hsrp_cfg.re_match(HSRP_REGEX, group=1))
|
||||
if hsrp_num != correct_grp_num:
|
||||
needs_hsrp_delete = True
|
||||
#del_hsrp_cmd += XML_CMD_TAG % ("no %s" % (hsrp_cfg.text))
|
||||
|
||||
if needs_hsrp_delete:
|
||||
LOG.info(_LI("Bad HSRP config for interface, deleting"))
|
||||
pending_delete_list.append(intf)
|
||||
continue
|
||||
#confstr = XML_FREEFORM_SNIPPET % (del_hsrp_cmd)
|
||||
#LOG.info("Deleting bad HSRP config: %s" % (confstr))
|
||||
#rpc_obj = conn.edit_config(target='running', config=confstr)
|
||||
|
||||
self.existing_cfg_dict['interfaces'][intf.segment_id] = intf.text
|
||||
|
||||
|
@ -1307,7 +1329,6 @@ class ConfigSyncer(object):
|
|||
del_cmd = XML_CMD_TAG % ("no %s" % (intf.text))
|
||||
confstr = XML_FREEFORM_SNIPPET % (del_cmd)
|
||||
LOG.info(_LI("Deleting %s"), (intf.text))
|
||||
#LOG.info(confstr)
|
||||
conn.edit_config(target='running', config=confstr)
|
||||
|
||||
LOG.debug("pending_delete_list (interfaces) = %s" %
|
||||
|
|
|
@ -74,7 +74,8 @@ class ASR1kRoutingDriver(iosxe_driver.IosXeRoutingDriver):
|
|||
self._edit_running_config(conf_str, 'EMPTY_SNIPPET')
|
||||
|
||||
def internal_network_added(self, ri, port):
|
||||
gw_ip = port['subnets'][0]['gateway_ip']
|
||||
gw_ip = self._get_item(
|
||||
port['subnets'], port['ip_info']['subnet_id'], 'id')['gateway_ip']
|
||||
if self._is_port_v6(port):
|
||||
LOG.debug("Adding IPv6 internal network port: %(port)s for router "
|
||||
"%(r_id)s", {'port': port, 'r_id': ri.id})
|
||||
|
@ -107,7 +108,9 @@ class ASR1kRoutingDriver(iosxe_driver.IosXeRoutingDriver):
|
|||
if self._is_global_router(ri):
|
||||
self._remove_sub_interface(ext_gw_port)
|
||||
else:
|
||||
ex_gw_ip = ext_gw_port['subnets'][0]['gateway_ip']
|
||||
ex_gw_ip = self._get_item(
|
||||
ext_gw_port['subnets'],
|
||||
ext_gw_port['ip_info']['subnet_id'], 'id')['gateway_ip']
|
||||
if (ex_gw_ip and
|
||||
ext_gw_port['device_owner'] == DEVICE_OWNER_ROUTER_GW):
|
||||
# Remove default route via this network's gateway ip
|
||||
|
@ -216,26 +219,32 @@ class ASR1kRoutingDriver(iosxe_driver.IosXeRoutingDriver):
|
|||
|
||||
def _handle_external_gateway_added_global_router(self, ri, ext_gw_port):
|
||||
# TODO(bobmel): Get the HA virtual IP correctly
|
||||
# TODO(sridar):
|
||||
# This seems to work fine. Keeping this todo until more testing.
|
||||
# NOTE(sridar): This seems to work fine. Keeping this todo until
|
||||
# more testing.
|
||||
virtual_gw_port = ext_gw_port[ha.HA_INFO]['ha_port']
|
||||
sub_itfc_ip = virtual_gw_port['fixed_ips'][0]['ip_address']
|
||||
subnet_id = ext_gw_port['ip_info']['subnet_id']
|
||||
sub_itfc_ip = self._get_item(virtual_gw_port['fixed_ips'],
|
||||
subnet_id)['ip_address']
|
||||
if self._is_port_v6(ext_gw_port):
|
||||
LOG.debug("Adding IPv6 external network port: %(port)s for global "
|
||||
"router %(r_id)s", {'port': ext_gw_port['id'],
|
||||
'r_id': ri.id})
|
||||
self._create_sub_interface_v6(ri, ext_gw_port, True, sub_itfc_ip)
|
||||
else:
|
||||
LOG.debug("Adding IPv4 external network port: %(port)s for global "
|
||||
"router %(r_id)s", {'port': ext_gw_port['id'],
|
||||
'r_id': ri.id})
|
||||
LOG.debug("Adding IPv4 external network port: %(port)s on "
|
||||
"subnet: (subnet)s for global router %(r_id)s",
|
||||
{'port': ext_gw_port['id'], 'subnet': subnet_id,
|
||||
'r_id': ri.id})
|
||||
self._create_sub_interface(ri, ext_gw_port, True, sub_itfc_ip)
|
||||
|
||||
def _handle_external_gateway_added_normal_router(self, ri, ext_gw_port):
|
||||
# Default routes are mapped to tenant router VRFs . Global Router
|
||||
# is not aware of tenant routers with ext network assigned. Thus,
|
||||
# default route must be handled per tenant router.
|
||||
ex_gw_ip = ext_gw_port['subnets'][0]['gateway_ip']
|
||||
ex_gw_ip = self._get_item(
|
||||
ext_gw_port['subnets'],
|
||||
ext_gw_port['ip_info']['subnet_id'], 'id')['gateway_ip']
|
||||
|
||||
sub_interface = self._get_interface_name_from_hosting_port(ext_gw_port)
|
||||
vlan_id = self._get_interface_vlan_from_hosting_port(ext_gw_port)
|
||||
if (self._fullsync and
|
||||
|
@ -266,11 +275,17 @@ class ASR1kRoutingDriver(iosxe_driver.IosXeRoutingDriver):
|
|||
LOG.info(_LI("Sub-interface already exists, skipping"))
|
||||
return
|
||||
vrf_name = self._get_vrf_name(ri)
|
||||
net_mask = netaddr.IPNetwork(port['ip_cidr']).netmask
|
||||
hsrp_ip = port['fixed_ips'][0]['ip_address']
|
||||
net_mask = netaddr.IPNetwork(port['ip_info']['ip_cidr']).netmask
|
||||
# get port's ip address for the subnet we're processing
|
||||
hsrp_ip = self._get_item(port['fixed_ips'],
|
||||
port['ip_info']['subnet_id'])['ip_address']
|
||||
sub_interface = self._get_interface_name_from_hosting_port(port)
|
||||
self._do_create_sub_interface(sub_interface, vlan, vrf_name, hsrp_ip,
|
||||
net_mask, is_external)
|
||||
if port['ip_info']['is_primary'] is True:
|
||||
self._do_create_sub_interface(
|
||||
sub_interface, vlan, vrf_name, hsrp_ip, net_mask, is_external)
|
||||
else:
|
||||
# this will only happen for global routers
|
||||
self._do_set_secondary(sub_interface, hsrp_ip, net_mask)
|
||||
# Always do HSRP
|
||||
if ri.router.get(ha.ENABLED, False):
|
||||
if port.get(ha.HA_INFO) is not None:
|
||||
|
@ -281,6 +296,12 @@ class ASR1kRoutingDriver(iosxe_driver.IosXeRoutingDriver):
|
|||
'port': port}
|
||||
raise cfg_exc.HAParamsMissingException(**params)
|
||||
|
||||
def _do_set_secondary(self, sub_interface, ip, mask):
|
||||
conf_str = (
|
||||
asr1k_snippets.SET_SUBINTERFACE_SECONDARY_IP % (
|
||||
sub_interface, ip, mask))
|
||||
self._edit_running_config(conf_str, 'SET_SUBINTERFACE_SECONDARY_IP')
|
||||
|
||||
def _do_create_sub_interface(self, sub_interface, vlan_id, vrf_name, ip,
|
||||
mask, is_external=False):
|
||||
is_multi_region_enabled = cfg.CONF.multi_region.enable_multi_region
|
||||
|
@ -329,41 +350,31 @@ class ASR1kRoutingDriver(iosxe_driver.IosXeRoutingDriver):
|
|||
def _set_nat_pool(self, ri, gw_port, is_delete):
|
||||
vrf_name = self._get_vrf_name(ri)
|
||||
if ri.router.get(ROUTER_ROLE_ATTR) == ROUTER_ROLE_HA_REDUNDANCY:
|
||||
pool_ip = gw_port[ha.HA_INFO]['ha_port']['fixed_ips'][0][
|
||||
'ip_address']
|
||||
pool_ip_prefix_len = gw_port['fixed_ips'][0]['prefixlen']
|
||||
the_port = gw_port[ha.HA_INFO]['ha_port']
|
||||
else:
|
||||
pool_ip = gw_port['fixed_ips'][0]['ip_address']
|
||||
pool_ip_prefix_len = gw_port['fixed_ips'][0]['prefixlen']
|
||||
# TODO(sridar) reverting to old model, needs more investigation
|
||||
# and cleanup
|
||||
# pool_info = gw_port['nat_pool_info']
|
||||
# pool_ip = pool_info['pool_ip']
|
||||
the_port = gw_port
|
||||
subnet_id = gw_port['ip_info']['subnet_id']
|
||||
fixed_ip = self._get_item(the_port['fixed_ips'], subnet_id)
|
||||
pool_ip = fixed_ip['ip_address']
|
||||
pool_ip_prefix_len = fixed_ip['prefixlen']
|
||||
#TODO(ebobmel) We need to modify the pool name generation if we
|
||||
# will have multiple NAT pools per VRF
|
||||
pool_name = "%s_nat_pool" % (vrf_name)
|
||||
#pool_net = netaddr.IPNetwork(pool_info['pool_cidr'])
|
||||
#pool_net = netaddr.IPNetwork(gw_port['ip_cidr'])
|
||||
pool_net = "%s/%s" % (pool_ip, pool_ip_prefix_len)
|
||||
pool_net = netaddr.IPNetwork(pool_net)
|
||||
if self._fullsync and pool_ip in self._existing_cfg_dict['pools']:
|
||||
LOG.info(_LI("Pool already exists, skipping"))
|
||||
return
|
||||
|
||||
#LOG.debug("SET_NAT_POOL pool netmask: %s, gw_port %s" % (
|
||||
# pool_net.netmask, gw_port))
|
||||
try:
|
||||
if is_delete:
|
||||
conf_str = asr1k_snippets.DELETE_NAT_POOL % (
|
||||
pool_name, pool_ip, pool_ip, pool_net.netmask)
|
||||
#self._edit_running_config(conf_str, '%s DELETE_NAT_POOL' %
|
||||
# self.target_asr['name'])
|
||||
# TODO(update so that hosting device name is passed down)
|
||||
self._edit_running_config(conf_str, 'DELETE_NAT_POOL')
|
||||
|
||||
else:
|
||||
conf_str = asr1k_snippets.CREATE_NAT_POOL % (
|
||||
pool_name, pool_ip, pool_ip, pool_net.netmask)
|
||||
#self._edit_running_config(conf_str, '%s CREATE_NAT_POOL' %
|
||||
# self.target_asr['name'])
|
||||
# TODO(update so that hosting device name is passed down)
|
||||
self._edit_running_config(conf_str, 'CREATE_NAT_POOL')
|
||||
#except cfg_exc.CSR1kvConfigException as cse:
|
||||
|
@ -376,7 +387,9 @@ class ASR1kRoutingDriver(iosxe_driver.IosXeRoutingDriver):
|
|||
self._existing_cfg_dict['routes']):
|
||||
LOG.debug("Default route already exists, skipping")
|
||||
return
|
||||
ext_gw_ip = ext_gw_port['subnets'][0]['gateway_ip']
|
||||
ext_gw_ip = self._get_item(
|
||||
ext_gw_port['subnets'],
|
||||
ext_gw_port['ip_info']['subnet_id'], 'id')['gateway_ip']
|
||||
if ext_gw_ip:
|
||||
vrf_name = self._get_vrf_name(ri)
|
||||
out_itfc = self._get_interface_name_from_hosting_port(ext_gw_port)
|
||||
|
@ -385,7 +398,9 @@ class ASR1kRoutingDriver(iosxe_driver.IosXeRoutingDriver):
|
|||
self._edit_running_config(conf_str, 'SET_DEFAULT_ROUTE_WITH_INTF')
|
||||
|
||||
def _remove_default_route(self, ri, ext_gw_port):
|
||||
ext_gw_ip = ext_gw_port['subnets'][0]['gateway_ip']
|
||||
ext_gw_ip = self._get_item(
|
||||
ext_gw_port['subnets'],
|
||||
ext_gw_port['ip_info']['subnet_id'], 'id')['gateway_ip']
|
||||
if ext_gw_ip:
|
||||
vrf_name = self._get_vrf_name(ri)
|
||||
out_itfc = self._get_interface_name_from_hosting_port(ext_gw_port)
|
||||
|
@ -405,29 +420,40 @@ class ASR1kRoutingDriver(iosxe_driver.IosXeRoutingDriver):
|
|||
priority = ri.router[ha.DETAILS][ha.PRIORITY]
|
||||
port_ha_info = port[ha.HA_INFO]
|
||||
group = port_ha_info['group']
|
||||
ip = port_ha_info['ha_port']['fixed_ips'][0]['ip_address']
|
||||
subnet_id = port['ip_info']['subnet_id']
|
||||
ip = self._get_item(port_ha_info['ha_port']['fixed_ips'],
|
||||
subnet_id)['ip_address']
|
||||
vlan = port['hosting_info']['segmentation_id']
|
||||
if ip and group and priority:
|
||||
vrf_name = self._get_vrf_name(ri)
|
||||
is_primary = port['ip_info']['is_primary']
|
||||
sub_interface = self._get_interface_name_from_hosting_port(port)
|
||||
self._do_set_ha_hsrp(sub_interface, vrf_name,
|
||||
priority, group, ip, vlan)
|
||||
self._do_set_ha_hsrp(sub_interface, vrf_name, priority, group, ip,
|
||||
vlan, is_primary)
|
||||
|
||||
def _do_set_ha_hsrp(self, sub_interface, vrf_name, priority, group,
|
||||
ip, vlan):
|
||||
conf_str = asr1k_snippets.SET_INTC_ASR_HSRP_EXTERNAL % (sub_interface,
|
||||
group,
|
||||
priority,
|
||||
group, ip,
|
||||
group, group,
|
||||
group, vlan)
|
||||
self._edit_running_config(conf_str, 'SET_INTC_ASR_HSRP_EXTERNAL')
|
||||
ip, vlan, is_primary=True):
|
||||
if is_primary is True:
|
||||
conf_str = asr1k_snippets.SET_INTC_ASR_HSRP_EXTERNAL % (
|
||||
sub_interface,
|
||||
group,
|
||||
priority,
|
||||
group, ip,
|
||||
group, group,
|
||||
group, vlan)
|
||||
self._edit_running_config(conf_str, 'SET_INTC_ASR_HSRP_EXTERNAL')
|
||||
else:
|
||||
conf_str = asr1k_snippets.SET_INTC_ASR_SECONDARY_HSRP_EXTERNAL % (
|
||||
sub_interface,
|
||||
group, ip)
|
||||
self._edit_running_config(conf_str,
|
||||
'SET_INTC_ASR_SECONDARY_HSRP_EXTERNAL')
|
||||
|
||||
def _create_sub_interface_v6(self, ri, port, is_external=False, gw_ip=""):
|
||||
if self._v6_port_needs_config(port) is not True:
|
||||
return
|
||||
vrf_name = self._get_vrf_name(ri)
|
||||
ip_cidr = port['ip_cidr']
|
||||
ip_cidr = port['ip_info']['ip_cidr']
|
||||
vlan = self._get_interface_vlan_from_hosting_port(port)
|
||||
sub_interface = self._get_interface_name_from_hosting_port(port)
|
||||
self._do_create_sub_interface_v6(sub_interface, vlan, vrf_name,
|
||||
|
@ -486,6 +512,20 @@ class ASR1kRoutingDriver(iosxe_driver.IosXeRoutingDriver):
|
|||
return False
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def _get_item(list_containing_dicts_entries, attribute_value,
|
||||
attribute_name='subnet_id'):
|
||||
"""Searches a list of dicts and returns the first matching entry
|
||||
|
||||
The dict entry returned contains the attribute 'attribute_name' whose
|
||||
value equals 'attribute_value'. If no such dict is found in the list
|
||||
an empty dict is returned.
|
||||
"""
|
||||
for item in list_containing_dicts_entries:
|
||||
if item.get(attribute_name) == attribute_value:
|
||||
return item
|
||||
return {}
|
||||
|
||||
@staticmethod
|
||||
def _port_is_hsrp(port):
|
||||
hsrp_types = [bc.constants.DEVICE_OWNER_ROUTER_HA_INTF]
|
||||
|
@ -496,9 +536,11 @@ class ASR1kRoutingDriver(iosxe_driver.IosXeRoutingDriver):
|
|||
return (ri.router.get(ROUTER_ROLE_ATTR) ==
|
||||
cisco_constants.ROUTER_ROLE_GLOBAL)
|
||||
|
||||
@staticmethod
|
||||
def _is_port_v6(port):
|
||||
return netaddr.IPNetwork(port['subnets'][0]['cidr']).version == 6
|
||||
@classmethod
|
||||
def _is_port_v6(cls, port):
|
||||
cidr = cls._get_item(port['subnets'],
|
||||
port['ip_info']['subnet_id'], 'id')['cidr']
|
||||
return netaddr.IPNetwork(cidr).version == 6
|
||||
|
||||
@staticmethod
|
||||
def _get_hsrp_grp_num_from_ri(ri):
|
||||
|
@ -507,7 +549,7 @@ class ASR1kRoutingDriver(iosxe_driver.IosXeRoutingDriver):
|
|||
def _add_internal_nw_nat_rules(self, ri, port, ext_port):
|
||||
vrf_name = self._get_vrf_name(ri)
|
||||
acl_no = self._generate_acl_num_from_port(port)
|
||||
internal_cidr = port['ip_cidr']
|
||||
internal_cidr = port['ip_info']['ip_cidr']
|
||||
internal_net = netaddr.IPNetwork(internal_cidr).network
|
||||
net_mask = netaddr.IPNetwork(internal_cidr).hostmask
|
||||
inner_itfc = self._get_interface_name_from_hosting_port(port)
|
||||
|
|
|
@ -81,6 +81,20 @@ CREATE_SUBINTERFACE_EXT_REGION_ID_WITH_ID = """
|
|||
</config>
|
||||
"""
|
||||
|
||||
# ===================================================
|
||||
# Add secondary ip for additional subnets
|
||||
# $(config)interface GigabitEthernet 2.500
|
||||
# $(config)ip address 192.168.0.1 255.255.255.0 secondary
|
||||
# ===================================================
|
||||
SET_SUBINTERFACE_SECONDARY_IP = """
|
||||
<config>
|
||||
<cli-config-data>
|
||||
<cmd>interface %s</cmd>
|
||||
<cmd>ip address %s %s secondary</cmd>
|
||||
</cli-config-data>
|
||||
</config>
|
||||
"""
|
||||
|
||||
# ===================================================
|
||||
# Enable HSRP on a Subinterface
|
||||
# $(config)interface GigabitEthernet0/0/0.314
|
||||
|
@ -129,6 +143,20 @@ SET_INTC_ASR_HSRP_EXTERNAL = """
|
|||
</config>
|
||||
"""
|
||||
|
||||
# ===================================================
|
||||
# Enable HSRP on a External Network Subinterface secondary IP
|
||||
# $(config)interface GigabitEthernet0/0/0.314
|
||||
# $(config)standby 1621 ip 10.0.3.1 secondary
|
||||
# ===================================================
|
||||
SET_INTC_ASR_SECONDARY_HSRP_EXTERNAL = """
|
||||
<config>
|
||||
<cli-config-data>
|
||||
<cmd>interface %s</cmd>
|
||||
<cmd>standby %s ip %s secondary</cmd>
|
||||
</cli-config-data>
|
||||
</config>
|
||||
"""
|
||||
|
||||
# ===========================================================================
|
||||
# Set Static source translation on an interface
|
||||
# Syntax: ip nat inside source static <fixed_ip> <floating_ip>
|
||||
|
|
|
@ -17,6 +17,7 @@ import eventlet
|
|||
import netaddr
|
||||
import pprint as pp
|
||||
|
||||
from operator import itemgetter
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
import oslo_messaging
|
||||
|
@ -30,6 +31,8 @@ from neutron.common import topics
|
|||
from neutron.common import utils as common_utils
|
||||
from neutron import context as n_context
|
||||
|
||||
from neutron_lib import exceptions as n_lib_exc
|
||||
|
||||
from networking_cisco._i18n import _, _LE, _LI, _LW
|
||||
from networking_cisco import backwards_compatibility as bc
|
||||
from networking_cisco.plugins.cisco.cfg_agent import cfg_exceptions
|
||||
|
@ -54,6 +57,16 @@ SYNC_ROUTERS_MAX_CHUNK_SIZE = 64
|
|||
SYNC_ROUTERS_MIN_CHUNK_SIZE = 8
|
||||
|
||||
|
||||
class IPAddressMissingException(n_lib_exc.NeutronException):
|
||||
message = _("Router port %(port_id)s has no IP address on subnet "
|
||||
"%(subnet_id)s.")
|
||||
|
||||
|
||||
class MultipleIPv4SubnetsException(n_lib_exc.NeutronException):
|
||||
message = _("There should not be multiple IPv4 subnets %(subnets)s on "
|
||||
"router port %(port_id)s")
|
||||
|
||||
|
||||
class RouterInfo(object):
|
||||
"""Wrapper class around the (neutron) router dictionary.
|
||||
|
||||
|
@ -726,9 +739,41 @@ class RoutingServiceHelper(object):
|
|||
self._enable_router_interface(ri, port)
|
||||
|
||||
def _process_new_ports(self, ri, new_ports, ex_gw_port, list_port_ids_up):
|
||||
#TODO(bmelande): 1. We need to handle the case where an external
|
||||
# network, to which a global router is connected,
|
||||
# is given another subnet. The global router must
|
||||
# then attached to that subnet. That attachment
|
||||
# does NOT result in a new router port. Instead, it
|
||||
# is done as an update to an EXISTING router port
|
||||
# which gets another ip address (from the newly
|
||||
# added subnet.
|
||||
for p in new_ports:
|
||||
self._set_subnet_info(p)
|
||||
# We sort the port's subnets on subnet_id so we can be sure that
|
||||
# the same ip address is used as primary on the HA master router
|
||||
# as well as on all HA backup routers.
|
||||
port_subnets = sorted(p['subnets'], key=itemgetter('id'))
|
||||
|
||||
num_subnets_on_port = len(port_subnets)
|
||||
LOG.debug("Number of subnets associated with router port = %d" %
|
||||
num_subnets_on_port)
|
||||
if (ri.router[ROUTER_ROLE_ATTR] is None and
|
||||
num_subnets_on_port > 1):
|
||||
LOG.error(_LE("Ignoring router port with multiple IPv4 "
|
||||
"subnets associated"))
|
||||
raise MultipleIPv4SubnetsException(
|
||||
port_id=p['id'], subnets=pp.pformat(port_subnets))
|
||||
|
||||
# Configure the primary IP address
|
||||
self._set_subnet_info(p, port_subnets[0]['id'])
|
||||
self._internal_network_added(ri, p, ex_gw_port)
|
||||
|
||||
# Process the secondary subnets. Only router ports of global
|
||||
# routers can have multiple ipv4 subnets since we connect such
|
||||
# routers to external networks using regular router ports.
|
||||
for p_sn in port_subnets[1:]:
|
||||
self._set_subnet_info(p, p_sn['id'], is_primary=False)
|
||||
self._internal_network_added(ri, p, ex_gw_port)
|
||||
|
||||
ri.internal_ports.append(p)
|
||||
list_port_ids_up.append(p['id'])
|
||||
|
||||
|
@ -738,13 +783,37 @@ class RoutingServiceHelper(object):
|
|||
ri.internal_ports.remove(p)
|
||||
|
||||
def _process_gateway_set(self, ri, ex_gw_port, list_port_ids_up):
|
||||
self._set_subnet_info(ex_gw_port)
|
||||
# We sort the port's subnets on subnet_id so we can be sure that
|
||||
# the same ip address is used as primary on the HA master router
|
||||
# as well as on all HA backup routers.
|
||||
gw_port_subnets = sorted(ex_gw_port['subnets'], key=itemgetter('id'))
|
||||
|
||||
# Configure the primary IP address
|
||||
self._set_subnet_info(ex_gw_port, gw_port_subnets[0]['id'])
|
||||
self._external_gateway_added(ri, ex_gw_port)
|
||||
|
||||
# Process the secondary subnets
|
||||
for gw_p_sn in gw_port_subnets[1:]:
|
||||
self._set_subnet_info(ex_gw_port, gw_p_sn['id'], is_primary=False)
|
||||
self._external_gateway_added(ri, ex_gw_port)
|
||||
|
||||
list_port_ids_up.append(ex_gw_port['id'])
|
||||
|
||||
def _process_gateway_cleared(self, ri, ex_gw_port):
|
||||
# We sort the port's subnets on subnet_id so we can be sure that
|
||||
# the same ip address is used as primary on the HA master router
|
||||
# as well as on all HA backup routers.
|
||||
gw_port_subnets = sorted(ex_gw_port['subnets'], key=itemgetter('id'))
|
||||
|
||||
# Deconfigure the primary IP address
|
||||
self._set_subnet_info(ex_gw_port, gw_port_subnets[0]['id'])
|
||||
self._external_gateway_removed(ri, ex_gw_port)
|
||||
|
||||
# Process the secondary subnets
|
||||
for gw_p_sn in gw_port_subnets[1:]:
|
||||
self._set_subnet_info(ex_gw_port, gw_p_sn['id'], is_primary=False)
|
||||
self._external_gateway_removed(ri, ex_gw_port)
|
||||
|
||||
def _add_rid_to_vrf_list(self, ri):
|
||||
# not needed in base service helper
|
||||
pass
|
||||
|
@ -1074,26 +1143,14 @@ class RoutingServiceHelper(object):
|
|||
ri.routes = new_routes
|
||||
|
||||
@staticmethod
|
||||
def _set_subnet_info(port):
|
||||
ips = port['fixed_ips']
|
||||
def _set_subnet_info(port, subnet_id, is_primary=True):
|
||||
|
||||
ips = [i['ip_address'] for i in port['fixed_ips']
|
||||
if i['subnet_id'] == subnet_id]
|
||||
if not ips:
|
||||
raise Exception(_("Router port %s has no IP address") % port['id'])
|
||||
if len(ips) > 1:
|
||||
LOG.error(_LE("Ignoring multiple IPs on router port %s"),
|
||||
port['id'])
|
||||
|
||||
port_subnets = port['subnets']
|
||||
|
||||
num_subnets_on_port = len(port_subnets)
|
||||
LOG.debug("number of subnets associated with port = %d" %
|
||||
num_subnets_on_port)
|
||||
# TODO(What should we do if multiple subnets are somehow associated)
|
||||
# TODO(with a port?)
|
||||
if (num_subnets_on_port > 1):
|
||||
LOG.error(_LE("Ignoring port with multiple subnets associated"))
|
||||
raise Exception(("Multiple subnets configured on port. %s") %
|
||||
pp.pformat(port_subnets))
|
||||
else:
|
||||
subnet = port_subnets[0]
|
||||
prefixlen = netaddr.IPNetwork(subnet['cidr']).prefixlen
|
||||
port['ip_cidr'] = "%s/%s" % (ips[0]['ip_address'], prefixlen)
|
||||
raise IPAddressMissingException(port_id=port['id'],
|
||||
subnet_id=subnet_id)
|
||||
subnet = port['subnets'][0]
|
||||
prefixlen = netaddr.IPNetwork(subnet['cidr']).prefixlen
|
||||
port['ip_info'] = {'subnet_id': subnet_id, 'is_primary': is_primary,
|
||||
'ip_cidr': "%s/%s" % (ips[0], prefixlen)}
|
||||
|
|
|
@ -19,8 +19,11 @@ from oslo_log import log as logging
|
|||
from networking_cisco import backwards_compatibility as bc
|
||||
from networking_cisco.plugins.cisco.cfg_agent.service_helpers import (
|
||||
routing_svc_helper as helper)
|
||||
from networking_cisco.plugins.cisco.common import (cisco_constants as
|
||||
c_constants)
|
||||
from networking_cisco.plugins.cisco.extensions import routerrole
|
||||
|
||||
|
||||
ROUTER_ROLE_ATTR = routerrole.ROUTER_ROLE_ATTR
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -33,11 +36,15 @@ class RoutingServiceHelperAci(helper.RoutingServiceHelper):
|
|||
self._router_ids_by_vrf = {}
|
||||
self._router_ids_by_vrf_and_ext_net = {}
|
||||
|
||||
def _is_global_router(self, ri):
|
||||
return (ri.router.get(ROUTER_ROLE_ATTR) ==
|
||||
c_constants.ROUTER_ROLE_GLOBAL)
|
||||
|
||||
def _process_new_ports(self, ri, new_ports, ex_gw_port, list_port_ids_up):
|
||||
# Only add internal networks if we have an
|
||||
# external gateway -- otherwise we have no parameters
|
||||
# to use to configure the interface (e.g. VRF, IP, etc.)
|
||||
if ex_gw_port:
|
||||
if ex_gw_port or self._is_global_router(ri):
|
||||
super(RoutingServiceHelperAci,
|
||||
self)._process_new_ports(
|
||||
ri, new_ports, ex_gw_port, list_port_ids_up)
|
||||
|
@ -51,7 +58,7 @@ class RoutingServiceHelperAci(helper.RoutingServiceHelper):
|
|||
# the relevant information (VRF and external network
|
||||
# parameters), which come from the GW port. Go ahead
|
||||
# and remove the interface from our internal state
|
||||
if gw_port:
|
||||
if gw_port or self._is_global_router(ri):
|
||||
self._internal_network_removed(ri, p, gw_port)
|
||||
ri.internal_ports.remove(p)
|
||||
|
||||
|
|
|
@ -0,0 +1,239 @@
|
|||
# Copyright 2016 Cisco Systems, 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.
|
||||
|
||||
# A tiny and simple Cisco IOS XE running config simulator.
|
||||
# The intended use is to allow a developer to observe how the running config
|
||||
# of an IOS XE device evolves as CLI commands are issued.
|
||||
#
|
||||
# Simple implies here that no CLI syntax or semantical checks are made so it
|
||||
# is entirely up to the command issuer to ensure the correctness of the
|
||||
# commands and their arguments.
|
||||
#
|
||||
# Bob Melander (bob.melander@gmail.com)
|
||||
|
||||
import re
|
||||
import six
|
||||
|
||||
from oslo_utils import timeutils
|
||||
|
||||
|
||||
class CiscoIOSXESimulator(object):
|
||||
|
||||
# set of commands to be logged only
|
||||
log_only_commands = set()
|
||||
# set of commands bound to immediately preceding line
|
||||
parent_bound_commands = {'exit-address-family'}
|
||||
exclamation = {'vrf definition', ' exit-address-family'}
|
||||
|
||||
def __init__(self, path, host_ip, netmask, port, username, password,
|
||||
device_params, mgmt_interface, timeout):
|
||||
self.host_ip = host_ip
|
||||
self.netmask = netmask
|
||||
self.port = port
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.device_params = device_params
|
||||
self.mgmt_interface = mgmt_interface
|
||||
self.timeout = timeout
|
||||
self.last_update = timeutils.utcnow()
|
||||
self.rc = self._get_dict()
|
||||
self._set_default_config()
|
||||
|
||||
def get_config(self):
|
||||
change_date = timeutils.strtime(self.last_update, '%a %b %d %Y')
|
||||
change_time = timeutils.strtime(self.last_update, '%H:%M:%S')
|
||||
intro_lines = ("! Last configuration change at " + change_time + " " +
|
||||
"UTC " + change_date + " by " + self.username + "\n!\n")
|
||||
intro_lines += ("hostname ASR-1002X-" +
|
||||
self.host_ip.replace('.', '_') + "\n!\n")
|
||||
intro_lines += ("boot-start-marker\nboot system flash "
|
||||
"bootflash:/asr1002x-simulated.03.16.00.S-ext."
|
||||
"SPA.bin\nboot-end-marker\n!\n")
|
||||
rc_data = {'rc_str': intro_lines}
|
||||
cmds = sorted(self.rc.keys())
|
||||
if 'vrf' in cmds:
|
||||
cmds.remove('vrf')
|
||||
cmds.insert(0, 'vrf')
|
||||
#for cmd, args in sorted(six.iteritems(self.rc)):
|
||||
for cmd in cmds:
|
||||
args = self.rc[cmd]
|
||||
line = cmd
|
||||
self._build_line(rc_data, args, line, 0)
|
||||
print(rc_data['rc_str'])
|
||||
return rc_data['rc_str']
|
||||
|
||||
def edit_config(self, snippet):
|
||||
command_lines = self._get_command_lines(snippet)
|
||||
if not command_lines:
|
||||
return
|
||||
self._process_next_level(self.rc, self.rc, command_lines, None, True)
|
||||
self.last_update = timeutils.utcnow()
|
||||
return True
|
||||
|
||||
def _set_default_config(self):
|
||||
mgmt_gw_ip = '.'.join((self.host_ip.split('.')[:-1]) + ['1'])
|
||||
command_chunks = [
|
||||
["vrf definition Mgmt-intf",
|
||||
"address-family ipv4",
|
||||
"exit-address-family",
|
||||
"address-family ipv6",
|
||||
"exit-address-family"],
|
||||
["interface " + self.mgmt_interface,
|
||||
"vrf forwarding Mgmt-intf",
|
||||
"ip address " + self.host_ip + " " + self.netmask,
|
||||
"negotiation auto"],
|
||||
["ip tftp source - interface " + self.mgmt_interface],
|
||||
["ip route vrf Mgmt - intf 0.0.0.0 0.0.0.0 " + mgmt_gw_ip],
|
||||
["ip ssh source - interface " + self.mgmt_interface],
|
||||
["ip ssh version 2"]
|
||||
]
|
||||
for commands in command_chunks:
|
||||
self._process_next_level(self.rc, self.rc, commands, None, True)
|
||||
|
||||
def _build_line(self, rc_data, current, baseline, level):
|
||||
for string, the_rest in sorted(six.iteritems(current)):
|
||||
if string == 'EOL':
|
||||
continue
|
||||
#line = baseline
|
||||
line = " " if baseline == "" and level >= 1 else baseline
|
||||
#line += ' ' + string if line != "" else string
|
||||
line += ' ' + string if line != "" and line != " " else string
|
||||
if 'EOL' in the_rest:
|
||||
#termination = "\n!\n" if self._to_exclamate(line) else "\n"
|
||||
if self._to_exclamate(line):
|
||||
termination = "\n !\n" if level >= 1 else "\n!\n"
|
||||
else:
|
||||
#termination = " \n" if level == 1 else "\n"
|
||||
termination = "\n"
|
||||
rc_data['rc_str'] += line + termination
|
||||
line = ""
|
||||
self._build_line(rc_data, the_rest, line, level + 1)
|
||||
if level == 0:
|
||||
rc_data['rc_str'] += "!\n"
|
||||
|
||||
def _to_exclamate(self, line):
|
||||
for statement in self.exclamation:
|
||||
if line.startswith(statement):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _process_next_level(self, parent, current, remaining_lines,
|
||||
last_processed, is_root=False):
|
||||
if not remaining_lines:
|
||||
return
|
||||
pre, cmd_line = self._get_command_prepending(remaining_lines[0])
|
||||
if pre is None:
|
||||
self._process_set(cmd_line, parent, current,
|
||||
remaining_lines, last_processed, is_root)
|
||||
elif pre.lower() == "no":
|
||||
self._process_unset(cmd_line.split(" "), current)
|
||||
|
||||
def _process_set(self, cmd_line, parent, current, remaining_lines,
|
||||
last_processed, is_root):
|
||||
cmd, args = self._get_command_and_args(cmd_line)
|
||||
if cmd in self.log_only_commands:
|
||||
self._process_next_level(parent, current,
|
||||
remaining_lines[1:], last_processed)
|
||||
return
|
||||
if cmd in self.parent_bound_commands:
|
||||
this_one = last_processed.get(cmd)
|
||||
start = last_processed
|
||||
else:
|
||||
this_one = parent.get(cmd)
|
||||
start = current
|
||||
if this_one is None:
|
||||
this_one, current_parent = self._get_successor_and_its_parent(
|
||||
parent, cmd, start, is_root)
|
||||
else:
|
||||
current_parent = start
|
||||
for arg in args:
|
||||
next_one, current_parent = self._get_successor_and_its_parent(
|
||||
current_parent, arg, this_one, is_root)
|
||||
this_one = next_one
|
||||
this_one['EOL'] = True
|
||||
if is_root is True:
|
||||
current = this_one
|
||||
self._process_next_level(current_parent, current, remaining_lines[1:],
|
||||
this_one)
|
||||
|
||||
def _process_unset(self, remaining, current):
|
||||
if not remaining:
|
||||
return
|
||||
arg = remaining[0]
|
||||
rest = remaining[1:]
|
||||
if arg in current:
|
||||
if not rest:
|
||||
del current[arg]
|
||||
else:
|
||||
self._process_unset(rest, current[arg])
|
||||
num_items = len(current[arg])
|
||||
if num_items == 0:
|
||||
del current[arg]
|
||||
|
||||
def _get_successor_and_its_parent(self, parent, string, current, is_root):
|
||||
successor = current.get(string)
|
||||
if successor is None:
|
||||
successor = self._get_dict()
|
||||
current[string] = successor
|
||||
current_parent = parent if is_root is False else successor
|
||||
else:
|
||||
current_parent = current
|
||||
return successor, current_parent
|
||||
|
||||
def _get_command_lines(self, snippet):
|
||||
if not snippet:
|
||||
return []
|
||||
lines = snippet.split('\n')
|
||||
commands = []
|
||||
for line in lines:
|
||||
if self._should_skip_line(line):
|
||||
continue
|
||||
cmd = self._get_embedded_command_string(line)
|
||||
if cmd is not None:
|
||||
commands.append(cmd)
|
||||
return commands
|
||||
|
||||
def _should_skip_line(self, line):
|
||||
if line == "":
|
||||
return True
|
||||
if line.find("config>") != -1:
|
||||
return True
|
||||
elif line.find("cli-config-data>") != -1:
|
||||
return True
|
||||
return False
|
||||
|
||||
def _get_embedded_command_string(self, line):
|
||||
match_obj = re.match(r'\s*<cmd>(.*)</cmd>\s*', line)
|
||||
if match_obj:
|
||||
return match_obj.group(1)
|
||||
return None
|
||||
|
||||
def _get_command_prepending(self, cmd):
|
||||
match_obj = re.match(r'\s*(no|do) (.*)\s*', cmd)
|
||||
if match_obj:
|
||||
return match_obj.group(1), match_obj.group(2)
|
||||
return None, cmd
|
||||
|
||||
def _get_command_and_args(self, cmd_line):
|
||||
str_list = cmd_line.split(" ")
|
||||
return str_list[0], str_list[1:]
|
||||
|
||||
def _get_dict(self):
|
||||
return {}
|
||||
|
||||
|
||||
# A simple Cisco IOS XE CLI simulator
|
||||
class FakeRunningConfig(object):
|
||||
def __init__(self, rc):
|
||||
self._raw = rc
|
|
@ -429,8 +429,13 @@ class HA_db_mixin(object):
|
|||
# Now add gw to redundancy routers
|
||||
rr_ids = []
|
||||
for r_b_db in router_db.redundancy_bindings:
|
||||
spec = {EXTERNAL_GW_INFO: copy.copy(router[EXTERNAL_GW_INFO])}
|
||||
spec[EXTERNAL_GW_INFO].pop('external_fixed_ips', None)
|
||||
spec = {EXTERNAL_GW_INFO: copy.deepcopy(router[EXTERNAL_GW_INFO])}
|
||||
if spec[EXTERNAL_GW_INFO]['external_fixed_ips']:
|
||||
# Ensure ip addresses are not specified as they cannot be
|
||||
# same as visible router's ip addresses.
|
||||
for e_fixed_ip in spec[EXTERNAL_GW_INFO]['external_fixed_ips']:
|
||||
e_fixed_ip.pop('ip_address', None)
|
||||
#spec[EXTERNAL_GW_INFO].pop('external_fixed_ips', None)
|
||||
spec[ha.ENABLED] = False
|
||||
self._update_router_no_notify(
|
||||
context, r_b_db.redundancy_router_id, {'router': spec})
|
||||
|
@ -681,7 +686,7 @@ class HA_db_mixin(object):
|
|||
return r_ha_g
|
||||
|
||||
def _get_fixed_ips_subnets(self, fixed_ips):
|
||||
subnets = copy.copy(fixed_ips)
|
||||
subnets = copy.deepcopy(fixed_ips)
|
||||
for s in subnets:
|
||||
s.pop('ip_address', None)
|
||||
return subnets
|
||||
|
|
|
@ -44,7 +44,7 @@ from neutron.extensions import providernet as pr_net
|
|||
from neutron_lib import exceptions as n_exc
|
||||
|
||||
from networking_cisco import backwards_compatibility as bc
|
||||
from networking_cisco._i18n import _, _LE, _LI, _LW
|
||||
from networking_cisco._i18n import _, _LE, _LI
|
||||
from networking_cisco.plugins.cisco.common import cisco_constants
|
||||
from networking_cisco.plugins.cisco.db.device_manager import hd_models
|
||||
from networking_cisco.plugins.cisco.db.l3 import l3_models
|
||||
|
@ -67,6 +67,7 @@ VM_CATEGORY = ciscohostingdevicemanager.VM_CATEGORY
|
|||
L3_ROUTER_NAT = bc.constants.L3
|
||||
HOSTING_DEVICE_ATTR = routerhostingdevice.HOSTING_DEVICE_ATTR
|
||||
ROUTER_ROLE_GLOBAL = cisco_constants.ROUTER_ROLE_GLOBAL
|
||||
ROUTER_ROLE_LOGICAL_GLOBAL = cisco_constants.ROUTER_ROLE_LOGICAL_GLOBAL
|
||||
ROUTER_ROLE_HA_REDUNDANCY = cisco_constants.ROUTER_ROLE_HA_REDUNDANCY
|
||||
|
||||
DICT_EXTEND_FUNCTIONS = ['_extend_router_dict_routertype',
|
||||
|
@ -1064,13 +1065,17 @@ class L3RouterApplianceDBMixin(extraroute_db.ExtraRoute_dbonly_mixin):
|
|||
|
||||
@lockutils.synchronized('routerbacklog', 'neutron-')
|
||||
def _process_backlogged_routers(self):
|
||||
self.ensure_global_router_cleanup()
|
||||
e_context = n_context.get_admin_context()
|
||||
for r_type, drv in self._router_drivers.items():
|
||||
if drv is not None:
|
||||
LOG.debug('Calling pre_backlog_processing for router type %s',
|
||||
r_type)
|
||||
drv.pre_backlog_processing(e_context)
|
||||
if self._refresh_router_backlog:
|
||||
self._sync_router_backlog()
|
||||
if not self._backlogged_routers:
|
||||
LOG.debug('No routers in backlog %s' % self._backlogged_routers)
|
||||
return
|
||||
e_context = n_context.get_admin_context()
|
||||
scheduled_routers = []
|
||||
LOG.info(_LI('Processing router (scheduling) backlog'))
|
||||
# try to reschedule
|
||||
|
@ -1111,50 +1116,11 @@ class L3RouterApplianceDBMixin(extraroute_db.ExtraRoute_dbonly_mixin):
|
|||
for ni in self.get_notifiers(e_context, scheduled_routers):
|
||||
if ni['notifier']:
|
||||
ni['notifier'].routers_updated(e_context, ni['routers'])
|
||||
|
||||
def ensure_global_router_cleanup(self):
|
||||
"""TODO: Function to be moved into router type driver.
|
||||
|
||||
This function should be moved into the router type driver.
|
||||
This will be done when the router type driver api is revised.
|
||||
"""
|
||||
e_context = n_context.get_admin_context()
|
||||
l3plugin = bc.get_plugin(L3_ROUTER_NAT)
|
||||
filters = {routerrole.ROUTER_ROLE_ATTR: [ROUTER_ROLE_GLOBAL]}
|
||||
global_routers = l3plugin.get_routers(e_context, filters=filters)
|
||||
if not global_routers:
|
||||
LOG.debug("There are no global routers")
|
||||
return
|
||||
for gr in global_routers:
|
||||
filters = {
|
||||
HOSTING_DEVICE_ATTR: [gr[HOSTING_DEVICE_ATTR]],
|
||||
routerrole.ROUTER_ROLE_ATTR: [ROUTER_ROLE_HA_REDUNDANCY, None]
|
||||
}
|
||||
invert_filters = {'gw_port_id': [None]}
|
||||
num_rtrs = l3plugin.get_routers_count_extended(
|
||||
e_context, filters=filters, invert_filters=invert_filters)
|
||||
LOG.debug("Global router %(name)s[%(id)s] with hosting_device "
|
||||
"%(hd)s has %(num)d routers with gw_port set on that "
|
||||
"device",
|
||||
{'name': gr['name'], 'id': gr['id'],
|
||||
'hd': gr[HOSTING_DEVICE_ATTR], 'num': num_rtrs, })
|
||||
if num_rtrs == 0:
|
||||
LOG.warning(_LW("Global router:%(name)s[id:%(id)s] is present "
|
||||
"for hosting device:%(hd)s but there are no "
|
||||
"tenant or redundancy routers with gateway set "
|
||||
"on that hosting device. Proceeding to delete "
|
||||
"global router."),
|
||||
{'name': gr['name'], 'id': gr['id'],
|
||||
'hd': gr[HOSTING_DEVICE_ATTR]})
|
||||
try:
|
||||
l3plugin.delete_router(
|
||||
e_context, gr['id'], unschedule=False)
|
||||
except (exc.ObjectDeletedError, l3.RouterNotFound) as e:
|
||||
LOG.warning(e)
|
||||
driver = self._get_router_type_driver(
|
||||
e_context, gr[routertype.TYPE_ATTR])
|
||||
driver._conditionally_remove_logical_global_router(
|
||||
e_context, gr)
|
||||
for r_type, drv in self._router_drivers.items():
|
||||
if drv is not None:
|
||||
LOG.debug('Calling post_backlog_processing for router type %s',
|
||||
r_type)
|
||||
drv.post_backlog_processing(e_context)
|
||||
|
||||
def _setup_backlog_handling(self):
|
||||
LOG.debug('Activating periodic backlog processor')
|
||||
|
|
|
@ -18,12 +18,15 @@ from oslo_utils import excutils
|
|||
|
||||
from networking_cisco._i18n import _LE
|
||||
from networking_cisco import backwards_compatibility as bc
|
||||
from networking_cisco.plugins.cisco.common import cisco_constants
|
||||
from networking_cisco.plugins.cisco.device_manager import config
|
||||
import networking_cisco.plugins.cisco.device_manager.plugging_drivers as plug
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
DEVICE_OWNER_ROUTER_GW = bc.constants.DEVICE_OWNER_ROUTER_GW
|
||||
GLOBAL_ROUTER_ROLES = [cisco_constants.ROUTER_ROLE_GLOBAL,
|
||||
cisco_constants.ROUTER_ROLE_LOGICAL_GLOBAL]
|
||||
|
||||
|
||||
class HwVLANTrunkingPlugDriver(plug.PluginSidePluggingDriver):
|
||||
|
@ -66,7 +69,7 @@ class HwVLANTrunkingPlugDriver(plug.PluginSidePluggingDriver):
|
|||
def extend_hosting_port_info(self, context, port_db, hosting_device,
|
||||
hosting_info):
|
||||
hosting_info['segmentation_id'] = port_db.hosting_info.segmentation_id
|
||||
is_external = (port_db.device_owner == DEVICE_OWNER_ROUTER_GW)
|
||||
is_external = (port_db.networks.external is not None)
|
||||
hosting_info['physical_interface'] = self._get_interface_info(
|
||||
hosting_device['id'], port_db.network_id, is_external)
|
||||
|
||||
|
|
|
@ -400,3 +400,27 @@ class L3RouterBaseDriver(object):
|
|||
config agent drivers corresponding to this router type driver.
|
||||
"""
|
||||
return ""
|
||||
|
||||
def pre_backlog_processing(self, context):
|
||||
"""Perform driver specific processing before backlog is processed.
|
||||
|
||||
:param context: admin neutron context
|
||||
|
||||
This function is invoked before the router plugin is processing the
|
||||
backlog of unscheduled routers. It allows the router type driver to
|
||||
perform any tasks that should be performed before the backlog is
|
||||
processed.
|
||||
"""
|
||||
pass
|
||||
|
||||
def post_backlog_processing(self, context):
|
||||
"""Perform driver specific processing after backlog is processed.
|
||||
|
||||
:param context: admin neutron context
|
||||
|
||||
This function is invoked after the router plugin has processed the
|
||||
backlog of unscheduled routers. It allows the router type driver to
|
||||
perform any tasks that should be performed after the backlog has been
|
||||
processed.
|
||||
"""
|
||||
pass
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import uuidutils
|
||||
|
@ -26,7 +24,7 @@ from neutron.extensions import l3
|
|||
from neutron_lib import constants as l3_constants
|
||||
from neutron_lib import exceptions as n_exc
|
||||
|
||||
from networking_cisco._i18n import _
|
||||
from networking_cisco._i18n import _, _LW
|
||||
from networking_cisco import backwards_compatibility as bc
|
||||
from networking_cisco.plugins.cisco.common import cisco_constants
|
||||
from networking_cisco.plugins.cisco.db.l3 import ha_db
|
||||
|
@ -196,6 +194,48 @@ class ASR1kL3RouterDriver(drivers.L3RouterBaseDriver):
|
|||
group_id += EXT_HSRP_GRP_OFFSET
|
||||
return group_id
|
||||
|
||||
def pre_backlog_processing(self, context):
|
||||
filters = {routerrole.ROUTER_ROLE_ATTR: [ROUTER_ROLE_GLOBAL]}
|
||||
global_routers = self._l3_plugin.get_routers(context, filters=filters)
|
||||
if not global_routers:
|
||||
LOG.debug("There are no global routers")
|
||||
return
|
||||
for gr in global_routers:
|
||||
filters = {
|
||||
HOSTING_DEVICE_ATTR: [gr[HOSTING_DEVICE_ATTR]],
|
||||
routerrole.ROUTER_ROLE_ATTR: [ROUTER_ROLE_HA_REDUNDANCY, None]
|
||||
}
|
||||
invert_filters = {'gw_port_id': [None]}
|
||||
num_rtrs = self._l3_plugin.get_routers_count_extended(
|
||||
context, filters=filters, invert_filters=invert_filters)
|
||||
LOG.debug("Global router %(name)s[%(id)s] with hosting_device "
|
||||
"%(hd)s has %(num)d routers with gw_port set on that "
|
||||
"device",
|
||||
{'name': gr['name'], 'id': gr['id'],
|
||||
'hd': gr[HOSTING_DEVICE_ATTR], 'num': num_rtrs, })
|
||||
if num_rtrs == 0:
|
||||
LOG.warning(
|
||||
_LW("Global router:%(name)s[id:%(id)s] is present for "
|
||||
"hosting device:%(hd)s but there are no tenant or "
|
||||
"redundancy routers with gateway set on that hosting "
|
||||
"device. Proceeding to delete global router."),
|
||||
{'name': gr['name'], 'id': gr['id'],
|
||||
'hd': gr[HOSTING_DEVICE_ATTR]})
|
||||
self._delete_global_router(context, gr['id'])
|
||||
filters = {
|
||||
#TODO(bmelande): Filter on routertype of global router
|
||||
#routertype.TYPE_ATTR: [routertype_id],
|
||||
routerrole.ROUTER_ROLE_ATTR: [ROUTER_ROLE_LOGICAL_GLOBAL]}
|
||||
log_global_routers = self._l3_plugin.get_routers(
|
||||
context, filters=filters)
|
||||
if log_global_routers:
|
||||
log_global_router_id = log_global_routers[0]['id']
|
||||
self._delete_global_router(context, log_global_router_id,
|
||||
logical=True)
|
||||
|
||||
def post_backlog_processing(self, context):
|
||||
pass
|
||||
|
||||
# ---------------- Create workflow functions -----------------
|
||||
|
||||
def _conditionally_add_global_router(self, context, tenant_router):
|
||||
|
@ -237,7 +277,7 @@ class ASR1kL3RouterDriver(drivers.L3RouterBaseDriver):
|
|||
'device_id': [global_router['id']],
|
||||
'device_owner': [port_type]}
|
||||
connected_nets = {
|
||||
p['network_id'] for p in
|
||||
p['network_id']: p['fixed_ips'] for p in
|
||||
self._core_plugin.get_ports(context, filters=filters)}
|
||||
if ext_net_id in connected_nets:
|
||||
# already connected to the external network so we're done
|
||||
|
@ -254,7 +294,8 @@ class ASR1kL3RouterDriver(drivers.L3RouterBaseDriver):
|
|||
port_type=DEVICE_OWNER_GLOBAL_ROUTER_GW):
|
||||
# When a global router is connected to an external network then a
|
||||
# special type of gateway port is created on that network. Such a
|
||||
# port is called auxiliary gateway ports. A (logical) global router
|
||||
# port is called auxiliary gateway ports. It has an ip address on
|
||||
# each subnet of the external network. A (logical) global router
|
||||
# never has a traditional Neutron gateway port.
|
||||
filters = {
|
||||
'device_id': [tenant_router['id']],
|
||||
|
@ -263,7 +304,7 @@ class ASR1kL3RouterDriver(drivers.L3RouterBaseDriver):
|
|||
# the CIDR of that port's subnet
|
||||
gw_port = self._core_plugin.get_ports(context,
|
||||
filters=filters)[0]
|
||||
fixed_ips = self._get_fixed_ips_subnets(gw_port['fixed_ips'])
|
||||
fixed_ips = self._get_fixed_ips_subnets(context, gw_port)
|
||||
global_router_id = global_router['id']
|
||||
with context.session.begin(subtransactions=True):
|
||||
aux_gw_port = self._core_plugin.create_port(context, {
|
||||
|
@ -351,10 +392,9 @@ class ASR1kL3RouterDriver(drivers.L3RouterBaseDriver):
|
|||
context.session.add(r_ha_s_db)
|
||||
return logical_global_router
|
||||
|
||||
def _get_fixed_ips_subnets(self, fixed_ips):
|
||||
subnets = copy.copy(fixed_ips)
|
||||
for s in subnets:
|
||||
s.pop('ip_address', None)
|
||||
def _get_fixed_ips_subnets(self, context, gw_port):
|
||||
nw = self._core_plugin.get_network(context, gw_port['network_id'])
|
||||
subnets = [{'subnet_id': s} for s in nw['subnets']]
|
||||
return subnets
|
||||
|
||||
def _provision_port_ha(self, context, ha_port, router, ha_binding_db=None):
|
||||
|
@ -400,6 +440,10 @@ class ASR1kL3RouterDriver(drivers.L3RouterBaseDriver):
|
|||
hd_to_gr_dict = {r[HOSTING_DEVICE_ATTR]: r for r in global_routers}
|
||||
if global_routers:
|
||||
global_router_id = global_routers[0]['id']
|
||||
if not tenant_router or not tenant_router[l3.EXTERNAL_GW_INFO]:
|
||||
# let l3 plugin's periodic backlog processing take care of the
|
||||
# clean up of the global router
|
||||
return
|
||||
ext_net_id = tenant_router[l3.EXTERNAL_GW_INFO]['network_id']
|
||||
routertype_id = tenant_router[routertype.TYPE_ATTR]
|
||||
hd_id = tenant_router[HOSTING_DEVICE_ATTR]
|
||||
|
@ -443,7 +487,8 @@ class ASR1kL3RouterDriver(drivers.L3RouterBaseDriver):
|
|||
(num_rtrs == 0 and update_operation is True)):
|
||||
# there are no tenant routers *on ext_net_id* that are serviced by
|
||||
# this global router so it's aux gw port can be deleted
|
||||
self._delete_auxiliary_gateway_port(context, router_id, ext_net_id)
|
||||
self._delete_auxiliary_gateway_ports(context, router_id,
|
||||
ext_net_id)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -462,8 +507,8 @@ class ASR1kL3RouterDriver(drivers.L3RouterBaseDriver):
|
|||
if num_global_rtrs == 0:
|
||||
# there are no global routers *on ext_net_id* that are serviced by
|
||||
# this logical global router so it's aux gw VIP port can be deleted
|
||||
self._delete_auxiliary_gateway_port(context, log_global_router_id,
|
||||
ext_net_id)
|
||||
self._delete_auxiliary_gateway_ports(context, log_global_router_id,
|
||||
ext_net_id)
|
||||
filters[routerrole.ROUTER_ROLE_ATTR] = [ROUTER_ROLE_GLOBAL]
|
||||
total_num_global_rtrs = self._l3_plugin.get_routers_count(
|
||||
context, filters=filters)
|
||||
|
@ -473,7 +518,7 @@ class ASR1kL3RouterDriver(drivers.L3RouterBaseDriver):
|
|||
self._delete_global_router(context, log_global_router_id, True)
|
||||
return False
|
||||
|
||||
def _delete_auxiliary_gateway_port(
|
||||
def _delete_auxiliary_gateway_ports(
|
||||
self, context, router_id, net_id=None,
|
||||
port_type=DEVICE_OWNER_GLOBAL_ROUTER_GW):
|
||||
filters = {
|
||||
|
@ -490,7 +535,7 @@ class ASR1kL3RouterDriver(drivers.L3RouterBaseDriver):
|
|||
|
||||
def _delete_global_router(self, context, global_router_id, logical=False):
|
||||
# ensure we clean up any stale auxiliary gateway ports
|
||||
self._delete_auxiliary_gateway_port(context, global_router_id)
|
||||
self._delete_auxiliary_gateway_ports(context, global_router_id)
|
||||
try:
|
||||
if logical is True:
|
||||
# We use parent class method as no special operations beyond
|
||||
|
|
|
@ -76,3 +76,9 @@ class NoopL3RouterDriver(drivers.L3RouterBaseDriver):
|
|||
|
||||
def delete_floatingip_postcommit(self, context, fip_context):
|
||||
pass
|
||||
|
||||
def pre_backlog_processing(self, context):
|
||||
pass
|
||||
|
||||
def post_backlog_processing(self, context):
|
||||
pass
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
(neutron) net-list
|
||||
+--------------------------------------+---------+-----------------------------------------------------+
|
||||
| id | name | subnets |
|
||||
+--------------------------------------+---------+-----------------------------------------------------+
|
||||
| 9d81f2da-eb8b-4c61-b247-ca3fe85a7838 | public | 7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41 172.16.6.32/27 |
|
||||
| | | 05509041-00e0-45c3-bf38-c603911c1ea4 172.17.7.32/27 |
|
||||
| 02232008-c78c-46b2-b712-678d85def46a | private | 54074049-aaf1-44d2-9843-99cdb10e3212 10.0.3.0/24 |
|
||||
+--------------------------------------+---------+-----------------------------------------------------+
|
||||
(neutron) subnet-list
|
||||
+--------------------------------------+-----------------+----------------+------------------------------------------------+
|
||||
| id | name | cidr | allocation_pools |
|
||||
+--------------------------------------+-----------------+----------------+------------------------------------------------+
|
||||
| 7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41 | public-subnet | 172.16.6.32/27 | {"start": "172.16.6.34", "end": "172.16.6.62"} |
|
||||
| 54074049-aaf1-44d2-9843-99cdb10e3212 | private-subnet | 10.0.3.0/24 | {"start": "10.0.3.2", "end": "10.0.3.254"} |
|
||||
| 05509041-00e0-45c3-bf38-c603911c1ea4 | public-subnet-2 | 172.17.7.32/27 | {"start": "172.17.7.34", "end": "172.17.7.62"} |
|
||||
+--------------------------------------+-----------------+----------------+------------------------------------------------+
|
||||
(neutron) router-list
|
||||
+--------------------------------------+---------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| id | name | external_gateway_info |
|
||||
+--------------------------------------+---------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| 085eba49-7ec9-470a-ac37-e89606eba108 | router1_HA_backup_1 | {"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838", "external_fixed_ips": [{"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": |
|
||||
| | | "172.16.6.45"}, {"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.35"}]} |
|
||||
| 25ecf24d-a3eb-426f-8871-22d7e78c5944 | Global-router-0000-000000000005 | null |
|
||||
| 5dd41cc4-7cbd-444f-894b-589531d3686c | router1 | {"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838", "external_fixed_ips": [{"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": |
|
||||
| | | "172.16.6.44"}, {"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.34"}]} |
|
||||
| 945d631c-0b37-4322-8dbe-c3759a3cac45 | Logical-Global-router | null |
|
||||
| c5c5eb9e-4451-4936-9125-9a9634cb5d2e | Global-router-0000-000000000004 | null |
|
||||
+--------------------------------------+---------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
(neutron) router-port-list router1
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| id | name | mac_address | fixed_ips |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| 780a2d1a-6cae-4b2e-919e-bb5fb0ee0395 | | fa:16:3e:37:e3:d7 | {"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": "172.16.6.44"} |
|
||||
| | | | {"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.34"} |
|
||||
| 9747b0d0-9380-4674-8cd9-9bc0db62355c | | fa:16:3e:ae:75:c5 | {"subnet_id": "54074049-aaf1-44d2-9843-99cdb10e3212", "ip_address": "10.0.3.1"} |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
(neutron) router-show router1
|
||||
+-------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Field | Value |
|
||||
+-------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| admin_state_up | True |
|
||||
| cisco_ha:details | {"redundancy_routers": [{"priority": 97, "state": "STANDBY", "id": "085eba49-7ec9-470a-ac37-e89606eba108"}], "probe_connectivity": false, "priority": 100, "state": "ACTIVE", |
|
||||
| | "redundancy_level": 1, "type": "HSRP"} |
|
||||
| cisco_ha:enabled | True |
|
||||
| description | |
|
||||
| external_gateway_info | {"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838", "external_fixed_ips": [{"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": "172.16.6.44"}, {"subnet_id": |
|
||||
| | "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.34"}]} |
|
||||
| id | 5dd41cc4-7cbd-444f-894b-589531d3686c |
|
||||
| name | router1 |
|
||||
| routerhost:hosting_device | 00000000-0000-0000-0000-000000000005 |
|
||||
| routerrole:role | |
|
||||
| routertype-aware-scheduler:auto_schedule | True |
|
||||
| routertype-aware-scheduler:share_hosting_device | True |
|
||||
| routertype:id | 00000000-0000-0000-0000-000000000003 |
|
||||
| routes | |
|
||||
| status | ACTIVE |
|
||||
| tenant_id | 840995fdaaf44ad4ab972f06fd6fbc13 |
|
||||
+-------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
(neutron) router-port-list Global-router-0000-000000000005
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| id | name | mac_address | fixed_ips |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| e678299a-0fbb-43f1-915c-a1c48c676bc6 | | fa:16:3e:04:d1:66 | {"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": "172.16.6.48"} |
|
||||
| | | | {"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.38"} |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
(neutron) router-show Global-router-0000-000000000005
|
||||
+-------------------------------------------------+--------------------------------------+
|
||||
| Field | Value |
|
||||
+-------------------------------------------------+--------------------------------------+
|
||||
| admin_state_up | True |
|
||||
| cisco_ha:enabled | False |
|
||||
| description | |
|
||||
| external_gateway_info | |
|
||||
| id | 25ecf24d-a3eb-426f-8871-22d7e78c5944 |
|
||||
| name | Global-router-0000-000000000005 |
|
||||
| routerhost:hosting_device | 00000000-0000-0000-0000-000000000005 |
|
||||
| routerrole:role | Global |
|
||||
| routertype-aware-scheduler:auto_schedule | False |
|
||||
| routertype-aware-scheduler:share_hosting_device | True |
|
||||
| routertype:id | 00000000-0000-0000-0000-000000000003 |
|
||||
| routes | |
|
||||
| status | ACTIVE |
|
||||
| tenant_id | |
|
||||
+-------------------------------------------------+--------------------------------------+
|
||||
(neutron) router-show router1_HA_backup_1
|
||||
+-------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Field | Value |
|
||||
+-------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| admin_state_up | True |
|
||||
| cisco_ha:enabled | False |
|
||||
| description | |
|
||||
| external_gateway_info | {"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838", "external_fixed_ips": [{"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": "172.16.6.45"}, {"subnet_id": |
|
||||
| | "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.35"}]} |
|
||||
| id | 085eba49-7ec9-470a-ac37-e89606eba108 |
|
||||
| name | router1_HA_backup_1 |
|
||||
| routerhost:hosting_device | 00000000-0000-0000-0000-000000000004 |
|
||||
| routerrole:role | HA-Redundancy |
|
||||
| routertype-aware-scheduler:auto_schedule | True |
|
||||
| routertype-aware-scheduler:share_hosting_device | True |
|
||||
| routertype:id | 00000000-0000-0000-0000-000000000003 |
|
||||
| routes | |
|
||||
| status | ACTIVE |
|
||||
| tenant_id | |
|
||||
+-------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
(neutron) router-port-list router1_HA_backup_1
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| id | name | mac_address | fixed_ips |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| 121bf217-7224-435a-bb23-fdb9c79b35c1 | | fa:16:3e:33:26:8e | {"subnet_id": "54074049-aaf1-44d2-9843-99cdb10e3212", "ip_address": "10.0.3.3"} |
|
||||
| 53e1c49f-8bad-4dc3-8e19-2202ab08fe53 | | fa:16:3e:fe:b7:79 | {"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": "172.16.6.45"} |
|
||||
| | | | {"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.35"} |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
(neutron) router-show router1_HA_backup_1
|
||||
+-------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Field | Value |
|
||||
+-------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| admin_state_up | True |
|
||||
| cisco_ha:enabled | False |
|
||||
| description | |
|
||||
| external_gateway_info | {"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838", "external_fixed_ips": [{"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": "172.16.6.45"}, {"subnet_id": |
|
||||
| | "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.35"}]} |
|
||||
| id | 085eba49-7ec9-470a-ac37-e89606eba108 |
|
||||
| name | router1_HA_backup_1 |
|
||||
| routerhost:hosting_device | 00000000-0000-0000-0000-000000000004 |
|
||||
| routerrole:role | HA-Redundancy |
|
||||
| routertype-aware-scheduler:auto_schedule | True |
|
||||
| routertype-aware-scheduler:share_hosting_device | True |
|
||||
| routertype:id | 00000000-0000-0000-0000-000000000003 |
|
||||
| routes | |
|
||||
| status | ACTIVE |
|
||||
| tenant_id | |
|
||||
+-------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
(neutron) router-port-list Global-router-0000-000000000004
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| id | name | mac_address | fixed_ips |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| 5931d51b-7806-4dd9-a024-2ed1c674782a | | fa:16:3e:40:96:dd | {"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": "172.16.6.47"} |
|
||||
| | | | {"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.37"} |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
(neutron) router-show Global-router-0000-000000000004
|
||||
+-------------------------------------------------+--------------------------------------+
|
||||
| Field | Value |
|
||||
+-------------------------------------------------+--------------------------------------+
|
||||
| admin_state_up | True |
|
||||
| cisco_ha:enabled | False |
|
||||
| description | |
|
||||
| external_gateway_info | |
|
||||
| id | c5c5eb9e-4451-4936-9125-9a9634cb5d2e |
|
||||
| name | Global-router-0000-000000000004 |
|
||||
| routerhost:hosting_device | 00000000-0000-0000-0000-000000000004 |
|
||||
| routerrole:role | Global |
|
||||
| routertype-aware-scheduler:auto_schedule | False |
|
||||
| routertype-aware-scheduler:share_hosting_device | True |
|
||||
| routertype:id | 00000000-0000-0000-0000-000000000003 |
|
||||
| routes | |
|
||||
| status | ACTIVE |
|
||||
| tenant_id | |
|
||||
+-------------------------------------------------+--------------------------------------+
|
||||
(mysql) select id,device_owner,device_id,network_id from ports;
|
||||
+--------------------------------------+--------------------------+--------------------------------------+--------------------------------------+
|
||||
| port_id | device_owner | device_id | network_id |
|
||||
+--------------------------------------+--------------------------+--------------------------------------+--------------------------------------+
|
||||
| 0b9c4564-9e42-4dfd-ab96-2cabee626aec | network:router_interface | 312cc5db-8749-46fe-82d9-d8492267902d | 02232008-c78c-46b2-b712-678d85def46a |
|
||||
| 121bf217-7224-435a-bb23-fdb9c79b35c1 | network:router_interface | 085eba49-7ec9-470a-ac37-e89606eba108 | 02232008-c78c-46b2-b712-678d85def46a |
|
||||
| 3fdf36c5-34a7-4aa3-8508-66b258377a68 | network:router_interface | 945d631c-0b37-4322-8dbe-c3759a3cac45 | 9d81f2da-eb8b-4c61-b247-ca3fe85a7838 |
|
||||
| 53e1c49f-8bad-4dc3-8e19-2202ab08fe53 | network:router_gateway | 085eba49-7ec9-470a-ac37-e89606eba108 | 9d81f2da-eb8b-4c61-b247-ca3fe85a7838 |
|
||||
| 5931d51b-7806-4dd9-a024-2ed1c674782a | network:router_interface | c5c5eb9e-4451-4936-9125-9a9634cb5d2e | 9d81f2da-eb8b-4c61-b247-ca3fe85a7838 |
|
||||
| 780a2d1a-6cae-4b2e-919e-bb5fb0ee0395 | network:router_gateway | 5dd41cc4-7cbd-444f-894b-589531d3686c | 9d81f2da-eb8b-4c61-b247-ca3fe85a7838 |
|
||||
| 9747b0d0-9380-4674-8cd9-9bc0db62355c | network:router_interface | 5dd41cc4-7cbd-444f-894b-589531d3686c | 02232008-c78c-46b2-b712-678d85def46a |
|
||||
| e678299a-0fbb-43f1-915c-a1c48c676bc6 | network:router_interface | 25ecf24d-a3eb-426f-8871-22d7e78c5944 | 9d81f2da-eb8b-4c61-b247-ca3fe85a7838 |
|
||||
+--------------------------------------+--------------------------+--------------------------------------+--------------------------------------+
|
||||
|
|
@ -0,0 +1,728 @@
|
|||
[{"_interfaces": [{"address_scopes": {"4": null, "6": null},
|
||||
"admin_state_up": true,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {},
|
||||
"binding:vif_type": "unbound",
|
||||
"binding:vnic_type": "normal",
|
||||
"created_at": "2017-02-28T11:27:27",
|
||||
"description": null,
|
||||
"device_id": "312cc5db-8749-46fe-82d9-d8492267902d",
|
||||
"device_owner": "network:router_interface",
|
||||
"dns_name": null,
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [{"ip_address": "10.0.3.2",
|
||||
"prefixlen": 24,
|
||||
"subnet_id": "54074049-aaf1-44d2-9843-99cdb10e3212"}],
|
||||
"ha_info": {"group": "1064",
|
||||
"ha_port": {"address_scopes": {"4": null,
|
||||
"6": null},
|
||||
"admin_state_up": true,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {},
|
||||
"binding:vif_type": "unbound",
|
||||
"binding:vnic_type": "normal",
|
||||
"created_at": "2017-02-28T11:27:26",
|
||||
"description": "",
|
||||
"device_id": "5dd41cc4-7cbd-444f-894b-589531d3686c",
|
||||
"device_owner": "network:router_interface",
|
||||
"dns_name": null,
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [{"ip_address": "10.0.3.1",
|
||||
"prefixlen": 24,
|
||||
"subnet_id": "54074049-aaf1-44d2-9843-99cdb10e3212"}],
|
||||
"id": "9747b0d0-9380-4674-8cd9-9bc0db62355c",
|
||||
"mac_address": "fa:16:3e:ae:75:c5",
|
||||
"mt": 1450,
|
||||
"name": "",
|
||||
"network_id": "02232008-c78c-46b2-b712-678d85def46a",
|
||||
"port_security_enabled": false,
|
||||
"security_groups": [],
|
||||
"status": "DOWN",
|
||||
"subnets": [{"cidr": "10.0.3.0/24",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "10.0.3.1",
|
||||
"id": "54074049-aaf1-44d2-9843-99cdb10e3212",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null}],
|
||||
"tenant_id": "840995fdaaf44ad4ab972f06fd6fbc13",
|
||||
"updated_at": "2017-02-28T11:27:26"},
|
||||
"other_config": "",
|
||||
"timers_config": "",
|
||||
"tracking_config": "",
|
||||
"type": "HSRP"},
|
||||
"hosting_info": {"hosting_mac": "fa:16:3e:82:59:fb",
|
||||
"hosting_port_id": "0b9c4564-9e42-4dfd-ab96-2cabee626aec",
|
||||
"hosting_port_name": "",
|
||||
"physical_interface": "GigabitEthernet/1/0/4",
|
||||
"segmentation_id": 1086},
|
||||
"id": "0b9c4564-9e42-4dfd-ab96-2cabee626aec",
|
||||
"mac_address": "fa:16:3e:82:59:fb",
|
||||
"mt": 1450,
|
||||
"name": "",
|
||||
"network_id": "02232008-c78c-46b2-b712-678d85def46a",
|
||||
"port_security_enabled": false,
|
||||
"security_groups": [],
|
||||
"status": "ACTIVE",
|
||||
"subnets": [{"cidr": "10.0.3.0/24",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "10.0.3.1",
|
||||
"id": "54074049-aaf1-44d2-9843-99cdb10e3212",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null}],
|
||||
"tenant_id": "",
|
||||
"updated_at": "2017-02-28T12:25:56"}],
|
||||
"admin_state_up": true,
|
||||
"cisco_ha:details": {"priority": 100,
|
||||
"probe_connectivity": false,
|
||||
"redundancy_level": 1,
|
||||
"redundancy_routers": [{"id": "085eba49-7ec9-470a-ac37-e89606eba108",
|
||||
"priority": 97,
|
||||
"state": "STANDBY"}],
|
||||
"state": "ACTIVE",
|
||||
"type": "HSRP"},
|
||||
"cisco_ha:enabled": true,
|
||||
"description": "",
|
||||
"external_gateway_info": {"external_fixed_ips": [{"ip_address": "172.16.6.44",
|
||||
"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41"},
|
||||
{"ip_address": "172.17.7.34",
|
||||
"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4"}],
|
||||
"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838"},
|
||||
"gw_port": {"address_scopes": {"4": null, "6": null},
|
||||
"admin_state_up": true,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {},
|
||||
"binding:vif_type": "unbound",
|
||||
"binding:vnic_type": "normal",
|
||||
"created_at": "2017-02-28T12:52:15",
|
||||
"description": "",
|
||||
"device_id": "5dd41cc4-7cbd-444f-894b-589531d3686c",
|
||||
"device_owner": "network:router_gateway",
|
||||
"dns_name": null,
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [{"ip_address": "172.16.6.44",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41"},
|
||||
{"ip_address": "172.17.7.34",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4"}],
|
||||
"ha_info": {"group": "1064",
|
||||
"ha_port": {"address_scopes": {"4": null,
|
||||
"6": null},
|
||||
"admin_state_up": true,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {},
|
||||
"binding:vif_type": "unbound",
|
||||
"binding:vnic_type": "normal",
|
||||
"created_at": "2017-02-28T12:52:15",
|
||||
"description": "",
|
||||
"device_id": "5dd41cc4-7cbd-444f-894b-589531d3686c",
|
||||
"device_owner": "network:router_gateway",
|
||||
"dns_name": null,
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [{"ip_address": "172.16.6.44",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41"},
|
||||
{"ip_address": "172.17.7.34",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4"}],
|
||||
"id": "780a2d1a-6cae-4b2e-919e-bb5fb0ee0395",
|
||||
"mac_address": "fa:16:3e:37:e3:d7",
|
||||
"mt": 1450,
|
||||
"name": "",
|
||||
"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838",
|
||||
"port_security_enabled": false,
|
||||
"security_groups": [],
|
||||
"status": "DOWN",
|
||||
"subnets": [{"cidr": "172.16.6.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.16.6.33",
|
||||
"id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null},
|
||||
{"cidr": "172.17.7.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.17.7.33",
|
||||
"id": "05509041-00e0-45c3-bf38-c603911c1ea4",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null}],
|
||||
"tenant_id": "",
|
||||
"updated_at": "2017-02-28T12:52:15"},
|
||||
"other_config": "",
|
||||
"timers_config": "",
|
||||
"tracking_config": "",
|
||||
"type": "HSRP"},
|
||||
"hosting_info": {"hosting_mac": "fa:16:3e:37:e3:d7",
|
||||
"hosting_port_id": "780a2d1a-6cae-4b2e-919e-bb5fb0ee0395",
|
||||
"hosting_port_name": "",
|
||||
"physical_interface": "GigabitEthernet/1/0/5",
|
||||
"segmentation_id": 1056},
|
||||
"id": "780a2d1a-6cae-4b2e-919e-bb5fb0ee0395",
|
||||
"mac_address": "fa:16:3e:37:e3:d7",
|
||||
"mt": 1450,
|
||||
"name": "",
|
||||
"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838",
|
||||
"port_security_enabled": false,
|
||||
"security_groups": [],
|
||||
"status": "DOWN",
|
||||
"subnets": [{"cidr": "172.16.6.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.16.6.33",
|
||||
"id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null},
|
||||
{"cidr": "172.17.7.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.17.7.33",
|
||||
"id": "05509041-00e0-45c3-bf38-c603911c1ea4",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null}],
|
||||
"tenant_id": "",
|
||||
"updated_at": "2017-02-28T12:52:15"},
|
||||
"gw_port_id": "780a2d1a-6cae-4b2e-919e-bb5fb0ee0395",
|
||||
"hosting_device": {"admin_state_up": true,
|
||||
"booting_time": 360,
|
||||
"created_at": "2017-02-28 11:27:21",
|
||||
"credentials": {"password": "cisco",
|
||||
"user_name": "stack"},
|
||||
"host_category": "Hardware",
|
||||
"id": "00000000-0000-0000-0000-000000000005",
|
||||
"management_ip_address": "10.0.100.7",
|
||||
"name": "ASR1k template",
|
||||
"protocol_port": 22,
|
||||
"service_types": "router",
|
||||
"status": "ACTIVE",
|
||||
"template_id": "00000000-0000-0000-0000-000000000003",
|
||||
"timeout": null},
|
||||
"id": "5dd41cc4-7cbd-444f-894b-589531d3686c",
|
||||
"name": "router1",
|
||||
"router_type": {"cfg_agent_driver": "networking_cisco.plugins.cisco.cfg_agent.device_drivers.asr1k.asr1k_routing_driver.ASR1kRoutingDriver",
|
||||
"cfg_agent_service_helper": "networking_cisco.plugins.cisco.cfg_agent.service_helpers.routing_svc_helper.RoutingServiceHelper",
|
||||
"id": "00000000-0000-0000-0000-000000000003",
|
||||
"name": "ASR1k_router"},
|
||||
"routerhost:hosting_device": "00000000-0000-0000-0000-000000000005",
|
||||
"routerrole:role": null,
|
||||
"routertype-aware-scheduler:auto_schedule": true,
|
||||
"routertype-aware-scheduler:share_hosting_device": true,
|
||||
"routertype:id": "00000000-0000-0000-0000-000000000003",
|
||||
"routes": [],
|
||||
"share_host": true,
|
||||
"status": "ACTIVE",
|
||||
"tenant_id": "840995fdaaf44ad4ab972f06fd6fbc13"},
|
||||
{"_interfaces": [{"address_scopes": {"4": null, "6": null},
|
||||
"admin_state_up": true,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {},
|
||||
"binding:vif_type": "unbound",
|
||||
"binding:vnic_type": "normal",
|
||||
"created_at": "2017-02-28T12:52:18",
|
||||
"description": null,
|
||||
"device_id": "c5c5eb9e-4451-4936-9125-9a9634cb5d2e",
|
||||
"device_owner": "network:router_interface",
|
||||
"dns_name": null,
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [{"ip_address": "172.16.6.47",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41"},
|
||||
{"ip_address": "172.17.7.37",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4"}],
|
||||
"ha_info": {"group": "1064",
|
||||
"ha_port": {"address_scopes": {"4": null,
|
||||
"6": null},
|
||||
"admin_state_up": true,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {},
|
||||
"binding:vif_type": "unbound",
|
||||
"binding:vnic_type": "normal",
|
||||
"created_at": "2017-02-28T12:52:18",
|
||||
"description": null,
|
||||
"device_id": "945d631c-0b37-4322-8dbe-c3759a3cac45",
|
||||
"device_owner": "network:router_interface",
|
||||
"dns_name": null,
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [{"ip_address": "172.16.6.46",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41"},
|
||||
{"ip_address": "172.17.7.36",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4"}],
|
||||
"id": "3fdf36c5-34a7-4aa3-8508-66b258377a68",
|
||||
"mac_address": "fa:16:3e:00:d7:f2",
|
||||
"mt": 1450,
|
||||
"name": "",
|
||||
"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838",
|
||||
"port_security_enabled": false,
|
||||
"security_groups": [],
|
||||
"status": "DOWN",
|
||||
"subnets": [{"cidr": "172.17.7.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.17.7.33",
|
||||
"id": "05509041-00e0-45c3-bf38-c603911c1ea4",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null},
|
||||
{"cidr": "172.16.6.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.16.6.33",
|
||||
"id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null}],
|
||||
"tenant_id": "",
|
||||
"updated_at": "2017-02-28T12:52:18"},
|
||||
"other_config": "",
|
||||
"timers_config": "",
|
||||
"tracking_config": "",
|
||||
"type": "HSRP"},
|
||||
"hosting_info": {"hosting_mac": "fa:16:3e:40:96:dd",
|
||||
"hosting_port_id": "5931d51b-7806-4dd9-a024-2ed1c674782a",
|
||||
"hosting_port_name": "",
|
||||
"physical_interface": "GigabitEthernet/1/0/2",
|
||||
"segmentation_id": 1056},
|
||||
"id": "5931d51b-7806-4dd9-a024-2ed1c674782a",
|
||||
"mac_address": "fa:16:3e:40:96:dd",
|
||||
"mt": 1450,
|
||||
"name": "",
|
||||
"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838",
|
||||
"port_security_enabled": false,
|
||||
"security_groups": [],
|
||||
"status": "DOWN",
|
||||
"subnets": [{"cidr": "172.16.6.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.16.6.33",
|
||||
"id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null},
|
||||
{"cidr": "172.17.7.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.17.7.33",
|
||||
"id": "05509041-00e0-45c3-bf38-c603911c1ea4",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null}],
|
||||
"tenant_id": "",
|
||||
"updated_at": "2017-02-28T12:52:18"}],
|
||||
"admin_state_up": true,
|
||||
"cisco_ha:details": {"priority": 100,
|
||||
"probe_connectivity": false,
|
||||
"redundancy_level": 2,
|
||||
"redundancy_routers": [{"id": "c5c5eb9e-4451-4936-9125-9a9634cb5d2e",
|
||||
"priority": 100,
|
||||
"state": "STANDBY"},
|
||||
{"id": "25ecf24d-a3eb-426f-8871-22d7e78c5944",
|
||||
"priority": 103,
|
||||
"state": "STANDBY"}],
|
||||
"state": "ACTIVE",
|
||||
"type": "HSRP"},
|
||||
"cisco_ha:enabled": true,
|
||||
"description": null,
|
||||
"external_gateway_info": null,
|
||||
"gw_port_id": null,
|
||||
"hosting_device": {"admin_state_up": true,
|
||||
"booting_time": 360,
|
||||
"created_at": "2017-02-28 11:27:21",
|
||||
"credentials": {"password": "cisco",
|
||||
"user_name": "stack"},
|
||||
"host_category": "Hardware",
|
||||
"id": "00000000-0000-0000-0000-000000000004",
|
||||
"management_ip_address": "10.0.100.6",
|
||||
"name": "ASR1k template",
|
||||
"protocol_port": 22,
|
||||
"service_types": "router",
|
||||
"status": "ACTIVE",
|
||||
"template_id": "00000000-0000-0000-0000-000000000003",
|
||||
"timeout": null},
|
||||
"id": "c5c5eb9e-4451-4936-9125-9a9634cb5d2e",
|
||||
"name": "Global-router-0000-000000000004",
|
||||
"router_type": {"cfg_agent_driver": "networking_cisco.plugins.cisco.cfg_agent.device_drivers.asr1k.asr1k_routing_driver.ASR1kRoutingDriver",
|
||||
"cfg_agent_service_helper": "networking_cisco.plugins.cisco.cfg_agent.service_helpers.routing_svc_helper.RoutingServiceHelper",
|
||||
"id": "00000000-0000-0000-0000-000000000003",
|
||||
"name": "ASR1k_router"},
|
||||
"routerhost:hosting_device": "00000000-0000-0000-0000-000000000004",
|
||||
"routerrole:role": "Global",
|
||||
"routertype-aware-scheduler:auto_schedule": false,
|
||||
"routertype-aware-scheduler:share_hosting_device": true,
|
||||
"routertype:id": "00000000-0000-0000-0000-000000000003",
|
||||
"routes": [],
|
||||
"share_host": true,
|
||||
"status": "ACTIVE",
|
||||
"tenant_id": ""},
|
||||
{"_interfaces": [{"address_scopes": {"4": null, "6": null},
|
||||
"admin_state_up": true,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {},
|
||||
"binding:vif_type": "unbound",
|
||||
"binding:vnic_type": "normal",
|
||||
"created_at": "2017-02-28T11:27:27",
|
||||
"description": null,
|
||||
"device_id": "085eba49-7ec9-470a-ac37-e89606eba108",
|
||||
"device_owner": "network:router_interface",
|
||||
"dns_name": null,
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [{"ip_address": "10.0.3.3",
|
||||
"prefixlen": 24,
|
||||
"subnet_id": "54074049-aaf1-44d2-9843-99cdb10e3212"}],
|
||||
"ha_info": {"group": "1064",
|
||||
"ha_port": {"address_scopes": {"4": null,
|
||||
"6": null},
|
||||
"admin_state_up": true,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {},
|
||||
"binding:vif_type": "unbound",
|
||||
"binding:vnic_type": "normal",
|
||||
"created_at": "2017-02-28T11:27:26",
|
||||
"description": "",
|
||||
"device_id": "5dd41cc4-7cbd-444f-894b-589531d3686c",
|
||||
"device_owner": "network:router_interface",
|
||||
"dns_name": null,
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [{"ip_address": "10.0.3.1",
|
||||
"prefixlen": 24,
|
||||
"subnet_id": "54074049-aaf1-44d2-9843-99cdb10e3212"}],
|
||||
"id": "9747b0d0-9380-4674-8cd9-9bc0db62355c",
|
||||
"mac_address": "fa:16:3e:ae:75:c5",
|
||||
"mt": 1450,
|
||||
"name": "",
|
||||
"network_id": "02232008-c78c-46b2-b712-678d85def46a",
|
||||
"port_security_enabled": false,
|
||||
"security_groups": [],
|
||||
"status": "DOWN",
|
||||
"subnets": [{"cidr": "10.0.3.0/24",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "10.0.3.1",
|
||||
"id": "54074049-aaf1-44d2-9843-99cdb10e3212",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null}],
|
||||
"tenant_id": "840995fdaaf44ad4ab972f06fd6fbc13",
|
||||
"updated_at": "2017-02-28T11:27:26"},
|
||||
"other_config": "",
|
||||
"timers_config": "",
|
||||
"tracking_config": "",
|
||||
"type": "HSRP"},
|
||||
"hosting_info": {"hosting_mac": "fa:16:3e:33:26:8e",
|
||||
"hosting_port_id": "121bf217-7224-435a-bb23-fdb9c79b35c1",
|
||||
"hosting_port_name": "",
|
||||
"physical_interface": "GigabitEthernet/1/0/2",
|
||||
"segmentation_id": 1086},
|
||||
"id": "121bf217-7224-435a-bb23-fdb9c79b35c1",
|
||||
"mac_address": "fa:16:3e:33:26:8e",
|
||||
"mt": 1450,
|
||||
"name": "",
|
||||
"network_id": "02232008-c78c-46b2-b712-678d85def46a",
|
||||
"port_security_enabled": false,
|
||||
"security_groups": [],
|
||||
"status": "ACTIVE",
|
||||
"subnets": [{"cidr": "10.0.3.0/24",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "10.0.3.1",
|
||||
"id": "54074049-aaf1-44d2-9843-99cdb10e3212",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null}],
|
||||
"tenant_id": "",
|
||||
"updated_at": "2017-02-28T12:26:04"}],
|
||||
"admin_state_up": true,
|
||||
"cisco_ha:details": {"priority": 100,
|
||||
"probe_connectivity": false,
|
||||
"redundancy_level": 1,
|
||||
"redundancy_routers": [{"id": "085eba49-7ec9-470a-ac37-e89606eba108",
|
||||
"priority": 97,
|
||||
"state": "STANDBY"}],
|
||||
"state": "ACTIVE",
|
||||
"type": "HSRP"},
|
||||
"cisco_ha:enabled": true,
|
||||
"description": "",
|
||||
"external_gateway_info": {"external_fixed_ips": [{"ip_address": "172.16.6.45",
|
||||
"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41"},
|
||||
{"ip_address": "172.17.7.35",
|
||||
"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4"}],
|
||||
"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838"},
|
||||
"gw_port": {"address_scopes": {"4": null, "6": null},
|
||||
"admin_state_up": true,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {},
|
||||
"binding:vif_type": "unbound",
|
||||
"binding:vnic_type": "normal",
|
||||
"created_at": "2017-02-28T12:52:16",
|
||||
"description": "",
|
||||
"device_id": "085eba49-7ec9-470a-ac37-e89606eba108",
|
||||
"device_owner": "network:router_gateway",
|
||||
"dns_name": null,
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [{"ip_address": "172.16.6.45",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41"},
|
||||
{"ip_address": "172.17.7.35",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4"}],
|
||||
"ha_info": {"group": "1064",
|
||||
"ha_port": {"address_scopes": {"4": null,
|
||||
"6": null},
|
||||
"admin_state_up": true,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {},
|
||||
"binding:vif_type": "unbound",
|
||||
"binding:vnic_type": "normal",
|
||||
"created_at": "2017-02-28T12:52:15",
|
||||
"description": "",
|
||||
"device_id": "5dd41cc4-7cbd-444f-894b-589531d3686c",
|
||||
"device_owner": "network:router_gateway",
|
||||
"dns_name": null,
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [{"ip_address": "172.16.6.44",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41"},
|
||||
{"ip_address": "172.17.7.34",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4"}],
|
||||
"id": "780a2d1a-6cae-4b2e-919e-bb5fb0ee0395",
|
||||
"mac_address": "fa:16:3e:37:e3:d7",
|
||||
"mt": 1450,
|
||||
"name": "",
|
||||
"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838",
|
||||
"port_security_enabled": false,
|
||||
"security_groups": [],
|
||||
"status": "DOWN",
|
||||
"subnets": [{"cidr": "172.16.6.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.16.6.33",
|
||||
"id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null},
|
||||
{"cidr": "172.17.7.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.17.7.33",
|
||||
"id": "05509041-00e0-45c3-bf38-c603911c1ea4",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null}],
|
||||
"tenant_id": "",
|
||||
"updated_at": "2017-02-28T12:52:15"},
|
||||
"other_config": "",
|
||||
"timers_config": "",
|
||||
"tracking_config": "",
|
||||
"type": "HSRP"},
|
||||
"hosting_info": {"hosting_mac": "fa:16:3e:fe:b7:79",
|
||||
"hosting_port_id": "53e1c49f-8bad-4dc3-8e19-2202ab08fe53",
|
||||
"hosting_port_name": "",
|
||||
"physical_interface": "GigabitEthernet/2/0/3",
|
||||
"segmentation_id": 1056},
|
||||
"id": "53e1c49f-8bad-4dc3-8e19-2202ab08fe53",
|
||||
"mac_address": "fa:16:3e:fe:b7:79",
|
||||
"mt": 1450,
|
||||
"name": "",
|
||||
"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838",
|
||||
"port_security_enabled": false,
|
||||
"security_groups": [],
|
||||
"status": "DOWN",
|
||||
"subnets": [{"cidr": "172.16.6.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.16.6.33",
|
||||
"id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null},
|
||||
{"cidr": "172.17.7.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.17.7.33",
|
||||
"id": "05509041-00e0-45c3-bf38-c603911c1ea4",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null}],
|
||||
"tenant_id": "",
|
||||
"updated_at": "2017-02-28T12:52:16"},
|
||||
"gw_port_id": "53e1c49f-8bad-4dc3-8e19-2202ab08fe53",
|
||||
"hosting_device": {"admin_state_up": true,
|
||||
"booting_time": 360,
|
||||
"created_at": "2017-02-28 11:27:21",
|
||||
"credentials": {"password": "cisco",
|
||||
"user_name": "stack"},
|
||||
"host_category": "Hardware",
|
||||
"id": "00000000-0000-0000-0000-000000000004",
|
||||
"management_ip_address": "10.0.100.6",
|
||||
"name": "ASR1k template",
|
||||
"protocol_port": 22,
|
||||
"service_types": "router",
|
||||
"status": "ACTIVE",
|
||||
"template_id": "00000000-0000-0000-0000-000000000003",
|
||||
"timeout": null},
|
||||
"id": "085eba49-7ec9-470a-ac37-e89606eba108",
|
||||
"name": "router1_HA_backup_1",
|
||||
"router_type": {"cfg_agent_driver": "networking_cisco.plugins.cisco.cfg_agent.device_drivers.asr1k.asr1k_routing_driver.ASR1kRoutingDriver",
|
||||
"cfg_agent_service_helper": "networking_cisco.plugins.cisco.cfg_agent.service_helpers.routing_svc_helper.RoutingServiceHelper",
|
||||
"id": "00000000-0000-0000-0000-000000000003",
|
||||
"name": "ASR1k_router"},
|
||||
"routerhost:hosting_device": "00000000-0000-0000-0000-000000000004",
|
||||
"routerrole:role": "HA-Redundancy",
|
||||
"routertype-aware-scheduler:auto_schedule": true,
|
||||
"routertype-aware-scheduler:share_hosting_device": true,
|
||||
"routertype:id": "00000000-0000-0000-0000-000000000003",
|
||||
"routes": [],
|
||||
"share_host": true,
|
||||
"status": "ACTIVE",
|
||||
"tenant_id": ""},
|
||||
{"_interfaces": [{"address_scopes": {"4": null, "6": null},
|
||||
"admin_state_up": true,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {},
|
||||
"binding:vif_type": "unbound",
|
||||
"binding:vnic_type": "normal",
|
||||
"created_at": "2017-02-28T12:52:20",
|
||||
"description": null,
|
||||
"device_id": "25ecf24d-a3eb-426f-8871-22d7e78c5944",
|
||||
"device_owner": "network:router_interface",
|
||||
"dns_name": null,
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [{"ip_address": "172.16.6.48",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41"},
|
||||
{"ip_address": "172.17.7.38",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4"}],
|
||||
"ha_info": {"group": "1064",
|
||||
"ha_port": {"address_scopes": {"4": null,
|
||||
"6": null},
|
||||
"admin_state_up": true,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {},
|
||||
"binding:vif_type": "unbound",
|
||||
"binding:vnic_type": "normal",
|
||||
"created_at": "2017-02-28T12:52:18",
|
||||
"description": null,
|
||||
"device_id": "945d631c-0b37-4322-8dbe-c3759a3cac45",
|
||||
"device_owner": "network:router_interface",
|
||||
"dns_name": null,
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [{"ip_address": "172.16.6.46",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41"},
|
||||
{"ip_address": "172.17.7.36",
|
||||
"prefixlen": 27,
|
||||
"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4"}],
|
||||
"id": "3fdf36c5-34a7-4aa3-8508-66b258377a68",
|
||||
"mac_address": "fa:16:3e:00:d7:f2",
|
||||
"mt": 1450,
|
||||
"name": "",
|
||||
"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838",
|
||||
"port_security_enabled": false,
|
||||
"security_groups": [],
|
||||
"status": "DOWN",
|
||||
"subnets": [{"cidr": "172.16.6.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.16.6.33",
|
||||
"id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null},
|
||||
{"cidr": "172.17.7.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.17.7.33",
|
||||
"id": "05509041-00e0-45c3-bf38-c603911c1ea4",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null}],
|
||||
"tenant_id": "",
|
||||
"updated_at": "2017-02-28T12:52:18"},
|
||||
"other_config": "",
|
||||
"timers_config": "",
|
||||
"tracking_config": "",
|
||||
"type": "HSRP"},
|
||||
"hosting_info": {"hosting_mac": "fa:16:3e:04:d1:66",
|
||||
"hosting_port_id": "e678299a-0fbb-43f1-915c-a1c48c676bc6",
|
||||
"hosting_port_name": "",
|
||||
"physical_interface": "GigabitEthernet/1/0/4",
|
||||
"segmentation_id": 1056},
|
||||
"id": "e678299a-0fbb-43f1-915c-a1c48c676bc6",
|
||||
"mac_address": "fa:16:3e:04:d1:66",
|
||||
"mt": 1450,
|
||||
"name": "",
|
||||
"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838",
|
||||
"port_security_enabled": false,
|
||||
"security_groups": [],
|
||||
"status": "DOWN",
|
||||
"subnets": [{"cidr": "172.16.6.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.16.6.33",
|
||||
"id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null},
|
||||
{"cidr": "172.17.7.32/27",
|
||||
"dns_nameservers": [],
|
||||
"gateway_ip": "172.17.7.33",
|
||||
"id": "05509041-00e0-45c3-bf38-c603911c1ea4",
|
||||
"ipv6_ra_mode": null,
|
||||
"subnetpool_id": null}],
|
||||
"tenant_id": "",
|
||||
"updated_at": "2017-02-28T12:52:20"}],
|
||||
"admin_state_up": true,
|
||||
"cisco_ha:details": {"priority": 100,
|
||||
"probe_connectivity": false,
|
||||
"redundancy_level": 2,
|
||||
"redundancy_routers": [{"id": "c5c5eb9e-4451-4936-9125-9a9634cb5d2e",
|
||||
"priority": 100,
|
||||
"state": "STANDBY"},
|
||||
{"id": "25ecf24d-a3eb-426f-8871-22d7e78c5944",
|
||||
"priority": 103,
|
||||
"state": "STANDBY"}],
|
||||
"state": "ACTIVE",
|
||||
"type": "HSRP"},
|
||||
"cisco_ha:enabled": true,
|
||||
"description": null,
|
||||
"external_gateway_info": null,
|
||||
"gw_port_id": null,
|
||||
"hosting_device": {"admin_state_up": true,
|
||||
"booting_time": 360,
|
||||
"created_at": "2017-02-28 11:27:21",
|
||||
"credentials": {"password": "cisco",
|
||||
"user_name": "stack"},
|
||||
"host_category": "Hardware",
|
||||
"id": "00000000-0000-0000-0000-000000000005",
|
||||
"management_ip_address": "10.0.100.7",
|
||||
"name": "ASR1k template",
|
||||
"protocol_port": 22,
|
||||
"service_types": "router",
|
||||
"status": "ACTIVE",
|
||||
"template_id": "00000000-0000-0000-0000-000000000003",
|
||||
"timeout": null},
|
||||
"id": "25ecf24d-a3eb-426f-8871-22d7e78c5944",
|
||||
"name": "Global-router-0000-000000000005",
|
||||
"router_type": {"cfg_agent_driver": "networking_cisco.plugins.cisco.cfg_agent.device_drivers.asr1k.asr1k_routing_driver.ASR1kRoutingDriver",
|
||||
"cfg_agent_service_helper": "networking_cisco.plugins.cisco.cfg_agent.service_helpers.routing_svc_helper.RoutingServiceHelper",
|
||||
"id": "00000000-0000-0000-0000-000000000003",
|
||||
"name": "ASR1k_router"},
|
||||
"routerhost:hosting_device": "00000000-0000-0000-0000-000000000005",
|
||||
"routerrole:role": "Global",
|
||||
"routertype-aware-scheduler:auto_schedule": false,
|
||||
"routertype-aware-scheduler:share_hosting_device": true,
|
||||
"routertype:id": "00000000-0000-0000-0000-000000000003",
|
||||
"routes": [],
|
||||
"share_host": true,
|
||||
"status": "ACTIVE",
|
||||
"tenant_id": ""}]
|
|
@ -0,0 +1,61 @@
|
|||
! Last configuration change at 08:58:07 UTC Fri Mar 03 2017 by stack
|
||||
!
|
||||
vrf definition Mgmt-intf
|
||||
!
|
||||
address-family ipv4
|
||||
exit-address-family
|
||||
!
|
||||
address-family ipv6
|
||||
exit-address-family
|
||||
!
|
||||
vrf definition nrouter-085eba
|
||||
!
|
||||
address-family ipv4
|
||||
exit-address-family
|
||||
!
|
||||
address-family ipv6
|
||||
exit-address-family
|
||||
!
|
||||
!
|
||||
interface GigabitEthernet/1/0/2.1086
|
||||
description OPENSTACK_NEUTRON_INTF
|
||||
encapsulation dot1Q 1086
|
||||
ip address 10.0.3.3 255.255.255.0
|
||||
ip nat inside
|
||||
standby 1064 ip 10.0.3.1
|
||||
standby 1064 name neutron-hsrp-1064-1086
|
||||
standby 1064 priority 97
|
||||
standby 1064 timers 1 3
|
||||
standby delay minimum 30 reload 60
|
||||
standby version 2
|
||||
vrf forwarding nrouter-085eba
|
||||
!
|
||||
interface GigabitEthernet/2/0/3.1056
|
||||
description OPENSTACK_NEUTRON_EXTERNAL_INTF
|
||||
encapsulation dot1Q 1056
|
||||
ip address 172.16.6.47 255.255.255.224 secondary
|
||||
ip address 172.17.7.37 255.255.255.224
|
||||
ip nat outside
|
||||
standby 1064 ip 172.16.6.46 secondary
|
||||
standby 1064 ip 172.17.7.36
|
||||
standby 1064 name neutron-hsrp-1064-1056
|
||||
standby 1064 priority 100
|
||||
standby 1064 timers 1 3
|
||||
standby delay minimum 30 reload 60
|
||||
standby version 2
|
||||
!
|
||||
interface GigabitEthernet0
|
||||
ip address 10.0.100.6 255.255.255.0
|
||||
negotiation auto
|
||||
vrf forwarding Mgmt-intf
|
||||
!
|
||||
ip access-list standard neutron_acl_1086_121bf217
|
||||
permit 10.0.3.0 0.0.0.255
|
||||
!
|
||||
ip nat inside source list neutron_acl_1086_121bf217 pool nrouter-085eba_nat_pool vrf nrouter-085eba overload
|
||||
ip nat pool nrouter-085eba_nat_pool 172.16.6.44 172.16.6.44 netmask 255.255.255.224
|
||||
ip nat pool nrouter-085eba_nat_pool 172.17.7.34 172.17.7.34 netmask 255.255.255.224
|
||||
!
|
||||
ip route vrf nrouter-085eba 0.0.0.0 0.0.0.0 GigabitEthernet/2/0/3.1056 172.16.6.33
|
||||
ip route vrf nrouter-085eba 0.0.0.0 0.0.0.0 GigabitEthernet/2/0/3.1056 172.17.7.33
|
||||
!
|
|
@ -0,0 +1,61 @@
|
|||
! Last configuration change at 08:58:07 UTC Fri Mar 03 2017 by stack
|
||||
!
|
||||
vrf definition Mgmt-intf
|
||||
!
|
||||
address-family ipv4
|
||||
exit-address-family
|
||||
!
|
||||
address-family ipv6
|
||||
exit-address-family
|
||||
!
|
||||
vrf definition nrouter-5dd41c
|
||||
!
|
||||
address-family ipv4
|
||||
exit-address-family
|
||||
!
|
||||
address-family ipv6
|
||||
exit-address-family
|
||||
!
|
||||
!
|
||||
interface GigabitEthernet/1/0/4.1086
|
||||
description OPENSTACK_NEUTRON_INTF
|
||||
encapsulation dot1Q 1086
|
||||
ip address 10.0.3.2 255.255.255.0
|
||||
ip nat inside
|
||||
standby 1064 ip 10.0.3.1
|
||||
standby 1064 name neutron-hsrp-1064-1086
|
||||
standby 1064 priority 100
|
||||
standby 1064 timers 1 3
|
||||
standby delay minimum 30 reload 60
|
||||
standby version 2
|
||||
vrf forwarding nrouter-5dd41c
|
||||
!
|
||||
interface GigabitEthernet/1/0/5.1056
|
||||
description OPENSTACK_NEUTRON_EXTERNAL_INTF
|
||||
encapsulation dot1Q 1056
|
||||
ip address 172.16.6.48 255.255.255.224 secondary
|
||||
ip address 172.17.7.38 255.255.255.224
|
||||
ip nat outside
|
||||
standby 1064 ip 172.16.6.46 secondary
|
||||
standby 1064 ip 172.17.7.36
|
||||
standby 1064 name neutron-hsrp-1064-1056
|
||||
standby 1064 priority 103
|
||||
standby 1064 timers 1 3
|
||||
standby delay minimum 30 reload 60
|
||||
standby version 2
|
||||
!
|
||||
interface GigabitEthernet0
|
||||
ip address 10.0.100.7 255.255.255.0
|
||||
negotiation auto
|
||||
vrf forwarding Mgmt-intf
|
||||
!
|
||||
ip access-list standard neutron_acl_1086_0b9c4564
|
||||
permit 10.0.3.0 0.0.0.255
|
||||
!
|
||||
ip nat inside source list neutron_acl_1086_0b9c4564 pool nrouter-5dd41c_nat_pool vrf nrouter-5dd41c overload
|
||||
ip nat pool nrouter-5dd41c_nat_pool 172.16.6.44 172.16.6.44 netmask 255.255.255.224
|
||||
ip nat pool nrouter-5dd41c_nat_pool 172.17.7.34 172.17.7.34 netmask 255.255.255.224
|
||||
!
|
||||
ip route vrf nrouter-5dd41c 0.0.0.0 0.0.0.0 GigabitEthernet/1/0/5.1056 172.16.6.33
|
||||
ip route vrf nrouter-5dd41c 0.0.0.0 0.0.0.0 GigabitEthernet/1/0/5.1056 172.17.7.33
|
||||
!
|
|
@ -0,0 +1,254 @@
|
|||
(neutron) net-list
|
||||
+--------------------------------------+-----------+-----------------------------------------------------+
|
||||
| id | name | subnets |
|
||||
+--------------------------------------+-----------+-----------------------------------------------------+
|
||||
| 02232008-c78c-46b2-b712-678d85def46a | private | 54074049-aaf1-44d2-9843-99cdb10e3212 10.0.3.0/24 |
|
||||
| 7a382985-4c58-4912-beb3-84fcf7d7af77 | public-2 | 7459de26-e9e2-491a-b174-db9f4d7313b8 172.17.8.32/27 |
|
||||
| 9d81f2da-eb8b-4c61-b247-ca3fe85a7838 | public | 7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41 172.16.6.32/27 |
|
||||
| | | 05509041-00e0-45c3-bf38-c603911c1ea4 172.17.7.32/27 |
|
||||
| cd04cc62-1799-4727-8f54-a2b4ec1a8bd2 | private-2 | 1af47d42-149e-423f-883f-5369ab11a9a0 10.0.4.0/24 |
|
||||
+--------------------------------------+-----------+-----------------------------------------------------+
|
||||
(neutron) subnet-list
|
||||
+--------------------------------------+------------------+----------------+------------------------------------------------+
|
||||
| id | name | cidr | allocation_pools |
|
||||
+--------------------------------------+------------------+----------------+------------------------------------------------+
|
||||
| 7459de26-e9e2-491a-b174-db9f4d7313b8 | public-2-subnet | 172.17.8.32/27 | {"start": "172.17.8.34", "end": "172.17.8.62"} |
|
||||
| 1af47d42-149e-423f-883f-5369ab11a9a0 | private-2-subnet | 10.0.4.0/24 | {"start": "10.0.4.2", "end": "10.0.4.254"} |
|
||||
| 54074049-aaf1-44d2-9843-99cdb10e3212 | private-subnet | 10.0.3.0/24 | {"start": "10.0.3.2", "end": "10.0.3.254"} |
|
||||
| 05509041-00e0-45c3-bf38-c603911c1ea4 | public-subnet-2 | 172.17.7.32/27 | {"start": "172.17.7.34", "end": "172.17.7.62"} |
|
||||
| 7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41 | public-subnet | 172.16.6.32/27 | {"start": "172.16.6.34", "end": "172.16.6.62"} |
|
||||
+--------------------------------------+------------------+----------------+------------------------------------------------+
|
||||
(neutron) router-list
|
||||
+--------------------------------------+---------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| id | name | external_gateway_info |
|
||||
+--------------------------------------+---------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| 085eba49-7ec9-470a-ac37-e89606eba108 | router1_HA_backup_1 | {"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838", "external_fixed_ips": [{"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": |
|
||||
| | | "172.16.6.45"}, {"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.35"}]} |
|
||||
| 25ecf24d-a3eb-426f-8871-22d7e78c5944 | Global-router-0000-000000000005 | null |
|
||||
| 5dd41cc4-7cbd-444f-894b-589531d3686c | routerOne | {"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838", "external_fixed_ips": [{"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": |
|
||||
| | | "172.16.6.44"}, {"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.34"}]} |
|
||||
| 71810702-bcc0-4718-9f62-1f16609084d0 | router2_HA_backup_1 | {"network_id": "7a382985-4c58-4912-beb3-84fcf7d7af77", "external_fixed_ips": [{"subnet_id": "7459de26-e9e2-491a-b174-db9f4d7313b8", "ip_address": |
|
||||
| | | "172.17.8.37"}]} |
|
||||
| 945d631c-0b37-4322-8dbe-c3759a3cac45 | Logical-Global-router | null |
|
||||
| b1e18b85-75ef-49e2-9eda-a5ddce09d777 | router2 | {"network_id": "7a382985-4c58-4912-beb3-84fcf7d7af77", "external_fixed_ips": [{"subnet_id": "7459de26-e9e2-491a-b174-db9f4d7313b8", "ip_address": |
|
||||
| | | "172.17.8.36"}]} |
|
||||
| c5c5eb9e-4451-4936-9125-9a9634cb5d2e | Global-router-0000-000000000004 | null |
|
||||
+--------------------------------------+---------------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
(neutron) router-port-list router1
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| id | name | mac_address | fixed_ips |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| 780a2d1a-6cae-4b2e-919e-bb5fb0ee0395 | | fa:16:3e:37:e3:d7 | {"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": "172.16.6.44"} |
|
||||
| | | | {"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.34"} |
|
||||
| 9747b0d0-9380-4674-8cd9-9bc0db62355c | | fa:16:3e:ae:75:c5 | {"subnet_id": "54074049-aaf1-44d2-9843-99cdb10e3212", "ip_address": "10.0.3.1"} |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
(neutron) router-show router1
|
||||
+-------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Field | Value |
|
||||
+-------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| admin_state_up | True |
|
||||
| cisco_ha:details | {"redundancy_routers": [{"priority": 97, "state": "STANDBY", "id": "085eba49-7ec9-470a-ac37-e89606eba108"}], "probe_connectivity": false, "priority": 100, "state": "ACTIVE", |
|
||||
| | "redundancy_level": 1, "type": "HSRP"} |
|
||||
| cisco_ha:enabled | True |
|
||||
| description | |
|
||||
| external_gateway_info | {"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838", "external_fixed_ips": [{"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": "172.16.6.44"}, {"subnet_id": |
|
||||
| | "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.34"}]} |
|
||||
| id | 5dd41cc4-7cbd-444f-894b-589531d3686c |
|
||||
| name | router1 |
|
||||
| routerhost:hosting_device | 00000000-0000-0000-0000-000000000005 |
|
||||
| routerrole:role | |
|
||||
| routertype-aware-scheduler:auto_schedule | True |
|
||||
| routertype-aware-scheduler:share_hosting_device | True |
|
||||
| routertype:id | 00000000-0000-0000-0000-000000000003 |
|
||||
| routes | |
|
||||
| status | ACTIVE |
|
||||
| tenant_id | 840995fdaaf44ad4ab972f06fd6fbc13 |
|
||||
+-------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
(neutron) router-port-list router2_HA_backup_1
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| id | name | mac_address | fixed_ips |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| 050aee56-f6a8-496a-a1af-2c7a57ca93d1 | | fa:16:3e:58:cb:03 | {"subnet_id": "7459de26-e9e2-491a-b174-db9f4d7313b8", "ip_address": "172.17.8.37"} |
|
||||
| e626fe6a-ee02-4453-8b81-59ba5efe92f8 | | fa:16:3e:0e:51:cc | {"subnet_id": "1af47d42-149e-423f-883f-5369ab11a9a0", "ip_address": "10.0.4.3"} |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
(neutron) router-show router2_HA_backup_1
|
||||
+-------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Field | Value |
|
||||
+-------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| admin_state_up | True |
|
||||
| cisco_ha:enabled | False |
|
||||
| description | |
|
||||
| external_gateway_info | {"network_id": "7a382985-4c58-4912-beb3-84fcf7d7af77", "external_fixed_ips": [{"subnet_id": "7459de26-e9e2-491a-b174-db9f4d7313b8", "ip_address": "172.17.8.37"}]} |
|
||||
| id | 71810702-bcc0-4718-9f62-1f16609084d0 |
|
||||
| name | router2_HA_backup_1 |
|
||||
| routerhost:hosting_device | 00000000-0000-0000-0000-000000000005 |
|
||||
| routerrole:role | HA-Redundancy |
|
||||
| routertype-aware-scheduler:auto_schedule | True |
|
||||
| routertype-aware-scheduler:share_hosting_device | True |
|
||||
| routertype:id | 00000000-0000-0000-0000-000000000003 |
|
||||
| routes | |
|
||||
| status | ACTIVE |
|
||||
| tenant_id | |
|
||||
+-------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
(neutron) router-port-list Global-router-0000-000000000005
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| id | name | mac_address | fixed_ips |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| 2a66a97a-3b53-4847-88b5-4fdeba6d42c7 | | fa:16:3e:c0:28:2b | {"subnet_id": "7459de26-e9e2-491a-b174-db9f4d7313b8", "ip_address": "172.17.8.39"} |
|
||||
| e678299a-0fbb-43f1-915c-a1c48c676bc6 | | fa:16:3e:04:d1:66 | {"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": "172.16.6.48"} |
|
||||
| | | | {"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.38"} |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
(neutron) router-show Global-router-0000-000000000005
|
||||
+-------------------------------------------------+--------------------------------------+
|
||||
| Field | Value |
|
||||
+-------------------------------------------------+--------------------------------------+
|
||||
| admin_state_up | True |
|
||||
| cisco_ha:enabled | False |
|
||||
| description | |
|
||||
| external_gateway_info | |
|
||||
| id | 25ecf24d-a3eb-426f-8871-22d7e78c5944 |
|
||||
| name | Global-router-0000-000000000005 |
|
||||
| routerhost:hosting_device | 00000000-0000-0000-0000-000000000005 |
|
||||
| routerrole:role | Global |
|
||||
| routertype-aware-scheduler:auto_schedule | False |
|
||||
| routertype-aware-scheduler:share_hosting_device | True |
|
||||
| routertype:id | 00000000-0000-0000-0000-000000000003 |
|
||||
| routes | |
|
||||
| status | ACTIVE |
|
||||
| tenant_id | |
|
||||
+-------------------------------------------------+--------------------------------------+
|
||||
(neutron) router-port-list router1_HA_backup_1
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| id | name | mac_address | fixed_ips |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| 121bf217-7224-435a-bb23-fdb9c79b35c1 | | fa:16:3e:33:26:8e | {"subnet_id": "54074049-aaf1-44d2-9843-99cdb10e3212", "ip_address": "10.0.3.3"} |
|
||||
| 53e1c49f-8bad-4dc3-8e19-2202ab08fe53 | | fa:16:3e:fe:b7:79 | {"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": "172.16.6.45"} |
|
||||
| | | | {"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.35"} |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
(neutron) router-show router1_HA_backup_1
|
||||
+-------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Field | Value |
|
||||
+-------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| admin_state_up | True |
|
||||
| cisco_ha:enabled | False |
|
||||
| description | |
|
||||
| external_gateway_info | {"network_id": "9d81f2da-eb8b-4c61-b247-ca3fe85a7838", "external_fixed_ips": [{"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": "172.16.6.45"}, {"subnet_id": |
|
||||
| | "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.35"}]} |
|
||||
| id | 085eba49-7ec9-470a-ac37-e89606eba108 |
|
||||
| name | router1_HA_backup_1 |
|
||||
| routerhost:hosting_device | 00000000-0000-0000-0000-000000000004 |
|
||||
| routerrole:role | HA-Redundancy |
|
||||
| routertype-aware-scheduler:auto_schedule | True |
|
||||
| routertype-aware-scheduler:share_hosting_device | True |
|
||||
| routertype:id | 00000000-0000-0000-0000-000000000003 |
|
||||
| routes | |
|
||||
| status | ACTIVE |
|
||||
| tenant_id | |
|
||||
+-------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
(neutron) router-port-list router2
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| id | name | mac_address | fixed_ips |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| 3582f930-df68-421d-b62e-e7dbcc424deb | | fa:16:3e:ee:95:e4 | {"subnet_id": "7459de26-e9e2-491a-b174-db9f4d7313b8", "ip_address": "172.17.8.36"} |
|
||||
| 8f6ec549-a879-4893-8cac-fab3911c8e45 | | fa:16:3e:07:76:1c | {"subnet_id": "1af47d42-149e-423f-883f-5369ab11a9a0", "ip_address": "10.0.4.1"} |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
(neutron) router-show router2
|
||||
+-------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| Field | Value |
|
||||
+-------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| admin_state_up | True |
|
||||
| cisco_ha:details | {"redundancy_routers": [{"priority": 97, "state": "STANDBY", "id": "71810702-bcc0-4718-9f62-1f16609084d0"}], "probe_connectivity": false, "priority": 100, "state": "ACTIVE", |
|
||||
| | "redundancy_level": 1, "type": "HSRP"} |
|
||||
| cisco_ha:enabled | True |
|
||||
| description | |
|
||||
| external_gateway_info | {"network_id": "7a382985-4c58-4912-beb3-84fcf7d7af77", "external_fixed_ips": [{"subnet_id": "7459de26-e9e2-491a-b174-db9f4d7313b8", "ip_address": "172.17.8.36"}]} |
|
||||
| id | b1e18b85-75ef-49e2-9eda-a5ddce09d777 |
|
||||
| name | router2 |
|
||||
| routerhost:hosting_device | 00000000-0000-0000-0000-000000000004 |
|
||||
| routerrole:role | |
|
||||
| routertype-aware-scheduler:auto_schedule | True |
|
||||
| routertype-aware-scheduler:share_hosting_device | True |
|
||||
| routertype:id | 00000000-0000-0000-0000-000000000003 |
|
||||
| routes | |
|
||||
| status | ACTIVE |
|
||||
| tenant_id | 840995fdaaf44ad4ab972f06fd6fbc13 |
|
||||
+-------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
(neutron) router-port-list Global-router-0000-000000000004
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| id | name | mac_address | fixed_ips |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
| 5931d51b-7806-4dd9-a024-2ed1c674782a | | fa:16:3e:40:96:dd | {"subnet_id": "7b3f7882-867e-4e6c-a9b3-a8f6ce3abd41", "ip_address": "172.16.6.47"} |
|
||||
| | | | {"subnet_id": "05509041-00e0-45c3-bf38-c603911c1ea4", "ip_address": "172.17.7.37"} |
|
||||
+--------------------------------------+------+-------------------+------------------------------------------------------------------------------------+
|
||||
(neutron) router-show Global-router-0000-000000000004
|
||||
+-------------------------------------------------+--------------------------------------+
|
||||
| Field | Value |
|
||||
+-------------------------------------------------+--------------------------------------+
|
||||
| admin_state_up | True |
|
||||
| cisco_ha:enabled | False |
|
||||
| description | |
|
||||
| external_gateway_info | |
|
||||
| id | c5c5eb9e-4451-4936-9125-9a9634cb5d2e |
|
||||
| name | Global-router-0000-000000000004 |
|
||||
| routerhost:hosting_device | 00000000-0000-0000-0000-000000000004 |
|
||||
| routerrole:role | Global |
|
||||
| routertype-aware-scheduler:auto_schedule | False |
|
||||
| routertype-aware-scheduler:share_hosting_device | True |
|
||||
| routertype:id | 00000000-0000-0000-0000-000000000003 |
|
||||
| routes | |
|
||||
| status | ACTIVE |
|
||||
| tenant_id | |
|
||||
+-------------------------------------------------+--------------------------------------+
|
||||
mysql> select id,device_owner,device_id,network_id from ports;
|
||||
+--------------------------------------+--------------------------+--------------------------------------+--------------------------------------+
|
||||
| id | device_owner | device_id | network_id |
|
||||
+--------------------------------------+--------------------------+--------------------------------------+--------------------------------------+
|
||||
| 050aee56-f6a8-496a-a1af-2c7a57ca93d1 | network:router_gateway | 71810702-bcc0-4718-9f62-1f16609084d0 | 7a382985-4c58-4912-beb3-84fcf7d7af77 |
|
||||
| 0b9c4564-9e42-4dfd-ab96-2cabee626aec | network:router_interface | 312cc5db-8749-46fe-82d9-d8492267902d | 02232008-c78c-46b2-b712-678d85def46a |
|
||||
| 121bf217-7224-435a-bb23-fdb9c79b35c1 | network:router_interface | 085eba49-7ec9-470a-ac37-e89606eba108 | 02232008-c78c-46b2-b712-678d85def46a |
|
||||
| 2a66a97a-3b53-4847-88b5-4fdeba6d42c7 | network:router_interface | 25ecf24d-a3eb-426f-8871-22d7e78c5944 | 7a382985-4c58-4912-beb3-84fcf7d7af77 |
|
||||
| 3582f930-df68-421d-b62e-e7dbcc424deb | network:router_gateway | b1e18b85-75ef-49e2-9eda-a5ddce09d777 | 7a382985-4c58-4912-beb3-84fcf7d7af77 |
|
||||
| 3ad3a3d6-1533-4572-8e13-c655f8f7a701 | network:router_interface | 945d631c-0b37-4322-8dbe-c3759a3cac45 | 7a382985-4c58-4912-beb3-84fcf7d7af77 |
|
||||
| 3fdf36c5-34a7-4aa3-8508-66b258377a68 | network:router_interface | 945d631c-0b37-4322-8dbe-c3759a3cac45 | 9d81f2da-eb8b-4c61-b247-ca3fe85a7838 |
|
||||
| 53e1c49f-8bad-4dc3-8e19-2202ab08fe53 | network:router_gateway | 085eba49-7ec9-470a-ac37-e89606eba108 | 9d81f2da-eb8b-4c61-b247-ca3fe85a7838 |
|
||||
| 5931d51b-7806-4dd9-a024-2ed1c674782a | network:router_interface | c5c5eb9e-4451-4936-9125-9a9634cb5d2e | 9d81f2da-eb8b-4c61-b247-ca3fe85a7838 |
|
||||
| 780a2d1a-6cae-4b2e-919e-bb5fb0ee0395 | network:router_gateway | 5dd41cc4-7cbd-444f-894b-589531d3686c | 9d81f2da-eb8b-4c61-b247-ca3fe85a7838 |
|
||||
| 8850d162-03ee-4b63-8d5a-632ef2e538d9 | network:router_interface | 125973e6-42dd-4e9a-8eed-38cb21b8b30f | cd04cc62-1799-4727-8f54-a2b4ec1a8bd2 |
|
||||
| 8f6ec549-a879-4893-8cac-fab3911c8e45 | network:router_interface | b1e18b85-75ef-49e2-9eda-a5ddce09d777 | cd04cc62-1799-4727-8f54-a2b4ec1a8bd2 |
|
||||
| 9747b0d0-9380-4674-8cd9-9bc0db62355c | network:router_interface | 5dd41cc4-7cbd-444f-894b-589531d3686c | 02232008-c78c-46b2-b712-678d85def46a |
|
||||
| e626fe6a-ee02-4453-8b81-59ba5efe92f8 | network:router_interface | 71810702-bcc0-4718-9f62-1f16609084d0 | cd04cc62-1799-4727-8f54-a2b4ec1a8bd2 |
|
||||
| e678299a-0fbb-43f1-915c-a1c48c676bc6 | network:router_interface | 25ecf24d-a3eb-426f-8871-22d7e78c5944 | 9d81f2da-eb8b-4c61-b247-ca3fe85a7838 |
|
||||
| f06164a0-8d91-4a7e-bcde-ab9a7887c978 | | | 02232008-c78c-46b2-b712-678d85def46a |
|
||||
| fe89f2e3-a07a-4ae9-ad9b-b5090ddac1d1 | network:router_interface | c5c5eb9e-4451-4936-9125-9a9634cb5d2e | 7a382985-4c58-4912-beb3-84fcf7d7af77 |
|
||||
+--------------------------------------+--------------------------+--------------------------------------+--------------------------------------+
|
||||
17 rows in set (0.00 sec)
|
||||
(neutron) port-show private-port-1
|
||||
+-----------------------+---------------------------------------------------------------------------------+
|
||||
| Field | Value |
|
||||
+-----------------------+---------------------------------------------------------------------------------+
|
||||
| admin_state_up | True |
|
||||
| allowed_address_pairs | |
|
||||
| binding:host_id | |
|
||||
| binding:profile | {} |
|
||||
| binding:vif_details | {} |
|
||||
| binding:vif_type | unbound |
|
||||
| binding:vnic_type | normal |
|
||||
| created_at | 2017-03-07T12:08:30 |
|
||||
| description | |
|
||||
| device_id | |
|
||||
| device_owner | |
|
||||
| extra_dhcp_opts | |
|
||||
| fixed_ips | {"subnet_id": "54074049-aaf1-44d2-9843-99cdb10e3212", "ip_address": "10.0.3.4"} |
|
||||
| id | f06164a0-8d91-4a7e-bcde-ab9a7887c978 |
|
||||
| mac_address | fa:16:3e:7b:45:2b |
|
||||
| name | private-port-1 |
|
||||
| network_id | 02232008-c78c-46b2-b712-678d85def46a |
|
||||
| port_security_enabled | True |
|
||||
| security_groups | f52fa760-8849-4612-a592-3714166c20c3 |
|
||||
| status | DOWN |
|
||||
| tenant_id | 840995fdaaf44ad4ab972f06fd6fbc13 |
|
||||
| updated_at | 2017-03-07T13:01:55 |
|
||||
+-----------------------+---------------------------------------------------------------------------------+
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,111 @@
|
|||
! Last configuration change at 13:03:29 UTC Tue Mar 07 2017 by stack
|
||||
!
|
||||
hostname ASR-1002X-10_0_100_6
|
||||
!
|
||||
boot-start-marker
|
||||
boot system flash bootflash:/asr1002x-simulated.03.16.00.S-ext.SPA.bin
|
||||
boot-end-marker
|
||||
!
|
||||
vrf definition Mgmt-intf
|
||||
!
|
||||
address-family ipv4
|
||||
exit-address-family
|
||||
!
|
||||
address-family ipv6
|
||||
exit-address-family
|
||||
!
|
||||
vrf definition nrouter-085eba
|
||||
!
|
||||
address-family ipv4
|
||||
exit-address-family
|
||||
!
|
||||
address-family ipv6
|
||||
exit-address-family
|
||||
!
|
||||
vrf definition nrouter-b1e18b
|
||||
!
|
||||
address-family ipv4
|
||||
exit-address-family
|
||||
!
|
||||
address-family ipv6
|
||||
exit-address-family
|
||||
!
|
||||
!
|
||||
interface GigabitEthernet/1/0/2.1050
|
||||
description OPENSTACK_NEUTRON_INTF
|
||||
encapsulation dot1Q 1050
|
||||
ip address 10.0.4.2 255.255.255.0
|
||||
ip nat inside
|
||||
standby 1064 ip 10.0.4.1
|
||||
standby 1064 name neutron-hsrp-1064-1050
|
||||
standby 1064 priority 100
|
||||
standby 1064 timers 1 3
|
||||
standby delay minimum 30 reload 60
|
||||
standby version 2
|
||||
vrf forwarding nrouter-b1e18b
|
||||
!
|
||||
interface GigabitEthernet/1/0/2.1086
|
||||
description OPENSTACK_NEUTRON_INTF
|
||||
encapsulation dot1Q 1086
|
||||
ip address 10.0.3.3 255.255.255.0
|
||||
ip nat inside
|
||||
standby 1064 ip 10.0.3.1
|
||||
standby 1064 name neutron-hsrp-1064-1086
|
||||
standby 1064 priority 97
|
||||
standby 1064 timers 1 3
|
||||
standby delay minimum 30 reload 60
|
||||
standby version 2
|
||||
vrf forwarding nrouter-085eba
|
||||
!
|
||||
interface GigabitEthernet/2/0/3.1018
|
||||
description OPENSTACK_NEUTRON_EXTERNAL_INTF
|
||||
encapsulation dot1Q 1018
|
||||
ip address 172.17.8.40 255.255.255.224
|
||||
ip nat outside
|
||||
standby 1064 ip 172.17.8.38
|
||||
standby 1064 name neutron-hsrp-1064-1018
|
||||
standby 1064 priority 100
|
||||
standby 1064 timers 1 3
|
||||
standby delay minimum 30 reload 60
|
||||
standby version 2
|
||||
!
|
||||
interface GigabitEthernet/2/0/3.1056
|
||||
description OPENSTACK_NEUTRON_EXTERNAL_INTF
|
||||
encapsulation dot1Q 1056
|
||||
ip address 172.16.6.47 255.255.255.224 secondary
|
||||
ip address 172.17.7.37 255.255.255.224
|
||||
ip nat outside
|
||||
standby 1064 ip 172.16.6.46 secondary
|
||||
standby 1064 ip 172.17.7.36
|
||||
standby 1064 name neutron-hsrp-1064-1056
|
||||
standby 1064 priority 100
|
||||
standby 1064 timers 1 3
|
||||
standby delay minimum 30 reload 60
|
||||
standby version 2
|
||||
!
|
||||
interface GigabitEthernet0
|
||||
ip address 10.0.100.6 255.255.255.0
|
||||
negotiation auto
|
||||
vrf forwarding Mgmt-intf
|
||||
!
|
||||
ip access-list standard neutron_acl_1050_8850d162
|
||||
permit 10.0.4.0 0.0.0.255
|
||||
ip access-list standard neutron_acl_1086_121bf217
|
||||
permit 10.0.3.0 0.0.0.255
|
||||
!
|
||||
ip nat inside source list neutron_acl_1050_8850d162 pool nrouter-b1e18b_nat_pool vrf nrouter-b1e18b overload
|
||||
ip nat inside source list neutron_acl_1086_121bf217 pool nrouter-085eba_nat_pool vrf nrouter-085eba overload
|
||||
ip nat pool nrouter-085eba_nat_pool 172.16.6.44 172.16.6.44 netmask 255.255.255.224
|
||||
ip nat pool nrouter-085eba_nat_pool 172.17.7.34 172.17.7.34 netmask 255.255.255.224
|
||||
ip nat pool nrouter-b1e18b_nat_pool 172.17.8.36 172.17.8.36 netmask 255.255.255.224
|
||||
!
|
||||
ip route vrf Mgmt - intf 0.0.0.0 0.0.0.0 10.0.100.1
|
||||
ip route vrf nrouter-085eba 0.0.0.0 0.0.0.0 GigabitEthernet/2/0/3.1056 172.16.6.33
|
||||
ip route vrf nrouter-085eba 0.0.0.0 0.0.0.0 GigabitEthernet/2/0/3.1056 172.17.7.33
|
||||
ip route vrf nrouter-b1e18b 0.0.0.0 0.0.0.0 GigabitEthernet/2/0/3.1018 172.17.8.33
|
||||
!
|
||||
ip ssh source - interface GigabitEthernet0
|
||||
ip ssh version 2
|
||||
!
|
||||
ip tftp source - interface GigabitEthernet0
|
||||
!
|
|
@ -0,0 +1,111 @@
|
|||
! Last configuration change at 13:03:29 UTC Tue Mar 07 2017 by stack
|
||||
!
|
||||
hostname ASR-1002X-10_0_100_7
|
||||
!
|
||||
boot-start-marker
|
||||
boot system flash bootflash:/asr1002x-simulated.03.16.00.S-ext.SPA.bin
|
||||
boot-end-marker
|
||||
!
|
||||
vrf definition Mgmt-intf
|
||||
!
|
||||
address-family ipv4
|
||||
exit-address-family
|
||||
!
|
||||
address-family ipv6
|
||||
exit-address-family
|
||||
!
|
||||
vrf definition nrouter-5dd41c
|
||||
!
|
||||
address-family ipv4
|
||||
exit-address-family
|
||||
!
|
||||
address-family ipv6
|
||||
exit-address-family
|
||||
!
|
||||
vrf definition nrouter-718107
|
||||
!
|
||||
address-family ipv4
|
||||
exit-address-family
|
||||
!
|
||||
address-family ipv6
|
||||
exit-address-family
|
||||
!
|
||||
!
|
||||
interface GigabitEthernet/1/0/4.1050
|
||||
description OPENSTACK_NEUTRON_INTF
|
||||
encapsulation dot1Q 1050
|
||||
ip address 10.0.4.3 255.255.255.0
|
||||
ip nat inside
|
||||
standby 1064 ip 10.0.4.1
|
||||
standby 1064 name neutron-hsrp-1064-1050
|
||||
standby 1064 priority 97
|
||||
standby 1064 timers 1 3
|
||||
standby delay minimum 30 reload 60
|
||||
standby version 2
|
||||
vrf forwarding nrouter-718107
|
||||
!
|
||||
interface GigabitEthernet/1/0/4.1086
|
||||
description OPENSTACK_NEUTRON_INTF
|
||||
encapsulation dot1Q 1086
|
||||
ip address 10.0.3.2 255.255.255.0
|
||||
ip nat inside
|
||||
standby 1064 ip 10.0.3.1
|
||||
standby 1064 name neutron-hsrp-1064-1086
|
||||
standby 1064 priority 100
|
||||
standby 1064 timers 1 3
|
||||
standby delay minimum 30 reload 60
|
||||
standby version 2
|
||||
vrf forwarding nrouter-5dd41c
|
||||
!
|
||||
interface GigabitEthernet/1/0/5.1018
|
||||
description OPENSTACK_NEUTRON_EXTERNAL_INTF
|
||||
encapsulation dot1Q 1018
|
||||
ip address 172.17.8.39 255.255.255.224
|
||||
ip nat outside
|
||||
standby 1064 ip 172.17.8.38
|
||||
standby 1064 name neutron-hsrp-1064-1018
|
||||
standby 1064 priority 103
|
||||
standby 1064 timers 1 3
|
||||
standby delay minimum 30 reload 60
|
||||
standby version 2
|
||||
!
|
||||
interface GigabitEthernet/1/0/5.1056
|
||||
description OPENSTACK_NEUTRON_EXTERNAL_INTF
|
||||
encapsulation dot1Q 1056
|
||||
ip address 172.16.6.48 255.255.255.224 secondary
|
||||
ip address 172.17.7.38 255.255.255.224
|
||||
ip nat outside
|
||||
standby 1064 ip 172.16.6.46 secondary
|
||||
standby 1064 ip 172.17.7.36
|
||||
standby 1064 name neutron-hsrp-1064-1056
|
||||
standby 1064 priority 103
|
||||
standby 1064 timers 1 3
|
||||
standby delay minimum 30 reload 60
|
||||
standby version 2
|
||||
!
|
||||
interface GigabitEthernet0
|
||||
ip address 10.0.100.7 255.255.255.0
|
||||
negotiation auto
|
||||
vrf forwarding Mgmt-intf
|
||||
!
|
||||
ip access-list standard neutron_acl_1050_e626fe6a
|
||||
permit 10.0.4.0 0.0.0.255
|
||||
ip access-list standard neutron_acl_1086_0b9c4564
|
||||
permit 10.0.3.0 0.0.0.255
|
||||
!
|
||||
ip nat inside source list neutron_acl_1050_e626fe6a pool nrouter-718107_nat_pool vrf nrouter-718107 overload
|
||||
ip nat inside source list neutron_acl_1086_0b9c4564 pool nrouter-5dd41c_nat_pool vrf nrouter-5dd41c overload
|
||||
ip nat pool nrouter-5dd41c_nat_pool 172.16.6.44 172.16.6.44 netmask 255.255.255.224
|
||||
ip nat pool nrouter-5dd41c_nat_pool 172.17.7.34 172.17.7.34 netmask 255.255.255.224
|
||||
ip nat pool nrouter-718107_nat_pool 172.17.8.36 172.17.8.36 netmask 255.255.255.224
|
||||
!
|
||||
ip route vrf Mgmt - intf 0.0.0.0 0.0.0.0 10.0.100.1
|
||||
ip route vrf nrouter-5dd41c 0.0.0.0 0.0.0.0 GigabitEthernet/1/0/5.1056 172.16.6.33
|
||||
ip route vrf nrouter-5dd41c 0.0.0.0 0.0.0.0 GigabitEthernet/1/0/5.1056 172.17.7.33
|
||||
ip route vrf nrouter-718107 0.0.0.0 0.0.0.0 GigabitEthernet/1/0/5.1018 172.17.8.33
|
||||
!
|
||||
ip ssh source - interface GigabitEthernet0
|
||||
ip ssh version 2
|
||||
!
|
||||
ip tftp source - interface GigabitEthernet0
|
||||
!
|
|
@ -12,16 +12,17 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
|
||||
import mock
|
||||
from neutron.tests import base
|
||||
from oslo_config import cfg
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from networking_cisco.plugins.cisco.cfg_agent.device_drivers.asr1k import (
|
||||
asr1k_cfg_syncer)
|
||||
|
||||
from networking_cisco.plugins.cisco.cfg_agent.device_drivers.asr1k import (
|
||||
asr1k_routing_driver as driver)
|
||||
|
||||
from networking_cisco.plugins.cisco.common.htparser import HTParser
|
||||
|
||||
|
||||
|
@ -1261,6 +1262,93 @@ NEUTRON_DB = [
|
|||
"tenant_id": "ecf8697e8dc04fef8be7c7f9c3594de9"
|
||||
},
|
||||
{
|
||||
"_interfaces": [
|
||||
{
|
||||
"admin_state_up": True,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "asr1k-k7-controller-1-R2",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {
|
||||
"ovs_hybrid_plug": True,
|
||||
"port_filter": True
|
||||
},
|
||||
"binding:vif_type": "ovs",
|
||||
"binding:vnic_type": "normal",
|
||||
"device_id": "213fd355-78c3-44cc-bd6e-492b9ade2602",
|
||||
"device_owner": "network:router_interface",
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [
|
||||
{
|
||||
"ip_address": "172.16.0.105",
|
||||
"prefixlen": 16,
|
||||
"subnet_id": "8f9c885d-a2ad-4fff-8127-2d4b3af6015b"
|
||||
}
|
||||
],
|
||||
"ha_info": {
|
||||
"group": "1064",
|
||||
"ha_port": {
|
||||
"admin_state_up": True,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {},
|
||||
"binding:vif_type": "unbound",
|
||||
"binding:vnic_type": "normal",
|
||||
"device_id": "a2617b46-78ef-49ba-95b5-0f3ff90f1f91",
|
||||
"device_owner": "network:router_interface",
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [{
|
||||
"ip_address": "172.16.0.104",
|
||||
"prefixlen": 16,
|
||||
"subnet_id": "8f9c885d-a2ad-4fff-8127-2d4b3af6015b"
|
||||
}],
|
||||
"id": "b768491c-4b76-492f-a0ee-56bc50867a07",
|
||||
"mac_address": "fa:16:3e:77:ae:bb",
|
||||
"name": "",
|
||||
"network_id": "7a38a5fd-3ad9-4952-ab08-4def22407269",
|
||||
"security_groups": [],
|
||||
"status": "DOWN",
|
||||
"subnets": [
|
||||
{
|
||||
"cidr": "172.16.0.0/16",
|
||||
"gateway_ip": "172.16.0.1",
|
||||
"id": "8f9c885d-a2ad-4fff-8127-2d4b3af6015b",
|
||||
"ipv6_ra_mode": None
|
||||
}
|
||||
],
|
||||
"tenant_id": ""
|
||||
},
|
||||
"other_config": "",
|
||||
"timers_config": "",
|
||||
"tracking_config": "",
|
||||
"type": "HSRP"
|
||||
},
|
||||
"hosting_info": {
|
||||
"hosting_mac": "fa:16:3e:97:ec:f2",
|
||||
"hosting_port_id": "527b7bc0-d6ba-4d07-932a-60e96da86173",
|
||||
"hosting_port_name": "",
|
||||
"physical_interface": "Port-channel10",
|
||||
"segmentation_id": 3000
|
||||
},
|
||||
"id": "527b7bc0-d6ba-4d07-932a-60e96da86173",
|
||||
"mac_address": "fa:16:3e:97:ec:f2",
|
||||
"name": "",
|
||||
"network_id": "7a38a5fd-3ad9-4952-ab08-4def22407269",
|
||||
"security_groups": [],
|
||||
"status": "ACTIVE",
|
||||
"subnets": [
|
||||
{
|
||||
"cidr": "172.16.0.0/16",
|
||||
"gateway_ip": "172.16.0.1",
|
||||
"id": "8f9c885d-a2ad-4fff-8127-2d4b3af6015b",
|
||||
"ipv6_ra_mode": None
|
||||
}
|
||||
],
|
||||
"tenant_id": ""
|
||||
}
|
||||
],
|
||||
"admin_state_up": True,
|
||||
"cisco_ha:details": {
|
||||
"priority": 100,
|
||||
|
@ -1291,94 +1379,7 @@ NEUTRON_DB = [
|
|||
],
|
||||
"network_id": "7a38a5fd-3ad9-4952-ab08-4def22407269"
|
||||
},
|
||||
"gw_port": {
|
||||
"admin_state_up": True,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "asr1k-k7-controller-1-R2",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {
|
||||
"ovs_hybrid_plug": True,
|
||||
"port_filter": True
|
||||
},
|
||||
"binding:vif_type": "ovs",
|
||||
"binding:vnic_type": "normal",
|
||||
"device_id": "213fd355-78c3-44cc-bd6e-492b9ade2602",
|
||||
"device_owner": "network:router_gateway",
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [
|
||||
{
|
||||
"ip_address": "172.16.0.105",
|
||||
"prefixlen": 16,
|
||||
"subnet_id": "8f9c885d-a2ad-4fff-8127-2d4b3af6015b"
|
||||
}
|
||||
],
|
||||
"ha_info": {
|
||||
"group": "1064",
|
||||
"ha_port": {
|
||||
"admin_state_up": True,
|
||||
"allowed_address_pairs": [],
|
||||
"binding:host_id": "",
|
||||
"binding:profile": {},
|
||||
"binding:vif_details": {},
|
||||
"binding:vif_type": "unbound",
|
||||
"binding:vnic_type": "normal",
|
||||
"device_id": "a2617b46-78ef-49ba-95b5-0f3ff90f1f91",
|
||||
"device_owner": "network:router_gateway",
|
||||
"extra_dhcp_opts": [],
|
||||
"extra_subnets": [],
|
||||
"fixed_ips": [
|
||||
{
|
||||
"ip_address": "172.16.0.104",
|
||||
"prefixlen": 16,
|
||||
"subnet_id": "8f9c885d-a2ad-4fff-8127-2d4b3af6015b"
|
||||
}
|
||||
],
|
||||
"id": "b768491c-4b76-492f-a0ee-56bc50867a07",
|
||||
"mac_address": "fa:16:3e:77:ae:bb",
|
||||
"name": "",
|
||||
"network_id": "7a38a5fd-3ad9-4952-ab08-4def22407269",
|
||||
"security_groups": [],
|
||||
"status": "DOWN",
|
||||
"subnets": [
|
||||
{
|
||||
"cidr": "172.16.0.0/16",
|
||||
"gateway_ip": "172.16.0.1",
|
||||
"id": "8f9c885d-a2ad-4fff-8127-2d4b3af6015b",
|
||||
"ipv6_ra_mode": None
|
||||
}
|
||||
],
|
||||
"tenant_id": ""
|
||||
},
|
||||
"other_config": "",
|
||||
"timers_config": "",
|
||||
"tracking_config": "",
|
||||
"type": "HSRP"
|
||||
},
|
||||
"hosting_info": {
|
||||
"hosting_mac": "fa:16:3e:97:ec:f2",
|
||||
"hosting_port_id": "527b7bc0-d6ba-4d07-932a-60e96da86173",
|
||||
"hosting_port_name": "",
|
||||
"physical_interface": "Port-channel10",
|
||||
"segmentation_id": 3000
|
||||
},
|
||||
"id": "527b7bc0-d6ba-4d07-932a-60e96da86173",
|
||||
"mac_address": "fa:16:3e:97:ec:f2",
|
||||
"name": "",
|
||||
"network_id": "7a38a5fd-3ad9-4952-ab08-4def22407269",
|
||||
"security_groups": [],
|
||||
"status": "ACTIVE",
|
||||
"subnets": [
|
||||
{
|
||||
"cidr": "172.16.0.0/16",
|
||||
"gateway_ip": "172.16.0.1",
|
||||
"id": "8f9c885d-a2ad-4fff-8127-2d4b3af6015b",
|
||||
"ipv6_ra_mode": None
|
||||
}
|
||||
],
|
||||
"tenant_id": ""
|
||||
},
|
||||
"gw_port_id": "527b7bc0-d6ba-4d07-932a-60e96da86173",
|
||||
"gw_port_id": None,
|
||||
"hosting_device": {
|
||||
"admin_state_up": True,
|
||||
"booting_time": 360,
|
||||
|
@ -1432,9 +1433,8 @@ class ASR1kCfgSyncer(base.BaseTestCase):
|
|||
self.hosting_device_info = {
|
||||
'id': '00000000-0000-0000-0000-000000000003'}
|
||||
self.driver = mock.Mock()
|
||||
self.config_syncer = asr1k_cfg_syncer.ConfigSyncer(self.router_db_info,
|
||||
self.driver,
|
||||
self.hosting_device_info)
|
||||
self.config_syncer = asr1k_cfg_syncer.ConfigSyncer(
|
||||
self.router_db_info, self.driver, self.hosting_device_info)
|
||||
|
||||
def test_delete_invalid_cfg_empty_routers_list(self):
|
||||
"""
|
||||
|
@ -1655,3 +1655,51 @@ class ASR1kCfgSyncer(base.BaseTestCase):
|
|||
parsed_cfg)
|
||||
|
||||
self.assertEqual([], invalid_cfg)
|
||||
|
||||
def _test_clean_router_multi_ext_net(self, routers_dict_filename,
|
||||
running_cfg_filename, hd_id,
|
||||
expected_invalid_cfg=None):
|
||||
if expected_invalid_cfg is None:
|
||||
expected_invalid_cfg = []
|
||||
path = os.path.dirname(os.path.abspath(__file__)) + '/'
|
||||
with open(path + routers_dict_filename) as routers_dict_file:
|
||||
r_dict_txt = routers_dict_file.read()
|
||||
routers_dict = jsonutils.loads(r_dict_txt)
|
||||
with open(path + running_cfg_filename) as running_config_file:
|
||||
running_cfg = running_config_file.read()
|
||||
hosting_device_info = {'id': hd_id}
|
||||
config_syncer = asr1k_cfg_syncer.ConfigSyncer(
|
||||
routers_dict, self.driver, hosting_device_info)
|
||||
config_syncer.get_running_config = mock.Mock(
|
||||
return_value=running_cfg)
|
||||
invalid_cfg = config_syncer.delete_invalid_cfg()
|
||||
self.assertEqual(expected_invalid_cfg, invalid_cfg)
|
||||
|
||||
def test_clean_router_with_two_subnet_gw(self):
|
||||
self._test_clean_router_multi_ext_net(
|
||||
'json/1/router_dicts_multi_subnets_ext_net.json',
|
||||
'json/1/running_cfg_0005_multi_subnets_ext_net.txt',
|
||||
'00000000-0000-0000-0000-000000000005')
|
||||
|
||||
def test_clean_ha_backup_router_with_two_subnet_gw(self):
|
||||
self._test_clean_router_multi_ext_net(
|
||||
'json/1/router_dicts_multi_subnets_ext_net.json',
|
||||
'json/1/running_cfg_0004_multi_subnets_ext_net.txt',
|
||||
'00000000-0000-0000-0000-000000000004')
|
||||
|
||||
def test_clean_routers_with_two_subnet_gw_and_single_subnet_gw(self):
|
||||
self._test_clean_router_multi_ext_net(
|
||||
'json/2/router_dicts_multi_subnets_ext_net_and_'
|
||||
'single_subnet_ext_net.json',
|
||||
'json/2/running_cfg_0005_multi_subnets_ext_net_and_'
|
||||
'single_subnet_ext_net.txt',
|
||||
'00000000-0000-0000-0000-000000000005')
|
||||
|
||||
def test_clean_ha_backup_routers_with_two_subnet_gw_and_single_subnet_gw(
|
||||
self):
|
||||
self._test_clean_router_multi_ext_net(
|
||||
'json/2/router_dicts_multi_subnets_ext_net_and_'
|
||||
'single_subnet_ext_net.json',
|
||||
'json/2/running_cfg_0004_multi_subnets_ext_net_and_'
|
||||
'single_subnet_ext_net.txt',
|
||||
'00000000-0000-0000-0000-000000000004')
|
||||
|
|
|
@ -76,21 +76,25 @@ class ASR1kRoutingDriver(base.BaseTestCase):
|
|||
self.ex_gw_cidr = '20.0.0.30/24'
|
||||
self.ex_gw_ip_mask = '255.255.255.0'
|
||||
self.ex_gw_ha_group = 1500
|
||||
sn_id = _uuid()
|
||||
self.ex_gw_ha_info = {'group': self.ex_gw_ha_group,
|
||||
'ha_port': {
|
||||
'fixed_ips': [{
|
||||
'subnet_id': sn_id,
|
||||
'ip_address': self.ex_gw_ip_vip,
|
||||
'prefixlen': self.ex_gw_prefixlen}]}}
|
||||
self.ex_gw_gateway_ip = '20.0.0.1'
|
||||
self.vlan_ext = 317
|
||||
self.phy_infc = 'GigabitEthernet0/0/0'
|
||||
|
||||
self.ex_gw_port = {'id': _uuid(),
|
||||
'network_id': _uuid(),
|
||||
'ip_info': {'subnet_id': sn_id,
|
||||
'is_primary': True,
|
||||
'ip_cidr': self.ex_gw_cidr},
|
||||
'fixed_ips': [{'ip_address': self.ex_gw_ip,
|
||||
'prefixlen': self.ex_gw_prefixlen,
|
||||
'subnet_id': _uuid()}],
|
||||
'subnets': [{'cidr': self.ex_gw_cidr,
|
||||
'subnet_id': sn_id}],
|
||||
'subnets': [{'id': sn_id, 'cidr': self.ex_gw_cidr,
|
||||
'gateway_ip': self.ex_gw_gateway_ip}],
|
||||
'device_owner': bc.constants.DEVICE_OWNER_ROUTER_GW,
|
||||
'mac_address': 'ca:fe:de:ad:be:ef',
|
||||
|
@ -109,21 +113,25 @@ class ASR1kRoutingDriver(base.BaseTestCase):
|
|||
self.gw_ip_vip = '10.0.3.1'
|
||||
self.gw_ip_mask = '255.255.255.0'
|
||||
self.gw_ha_group = 1621
|
||||
sn_id = _uuid()
|
||||
self.gw_ha_info = {'group': self.gw_ha_group,
|
||||
'ha_port': {
|
||||
'fixed_ips': [{
|
||||
'subnet_id': sn_id,
|
||||
'ip_address': self.gw_ip_vip,
|
||||
'prefixlen': self.gw_prefixlen}]}}
|
||||
self.port = {'id': PORT_ID,
|
||||
'ip_cidr': self.gw_ip_cidr,
|
||||
'fixed_ips': [{'ip_address': self.gw_ip}],
|
||||
'subnets': [{'cidr': self.gw_ip_cidr,
|
||||
'ip_info': {'subnet_id': sn_id,
|
||||
'is_primary': True,
|
||||
'ip_cidr': self.gw_ip_cidr},
|
||||
'fixed_ips': [{'ip_address': self.gw_ip,
|
||||
'subnet_id': sn_id}],
|
||||
'subnets': [{'id': sn_id, 'cidr': self.gw_ip_cidr,
|
||||
'gateway_ip': self.gw_ip}],
|
||||
'hosting_info': {
|
||||
'physical_interface': self.phy_infc,
|
||||
'segmentation_id': self.vlan_int},
|
||||
HA_INFO: self.gw_ha_info
|
||||
}
|
||||
HA_INFO: self.gw_ha_info}
|
||||
int_ports = [self.port]
|
||||
self.floating_ip = '20.0.0.35'
|
||||
self.fixed_ip = '10.0.3.5'
|
||||
|
@ -165,8 +173,7 @@ class ASR1kRoutingDriver(base.BaseTestCase):
|
|||
'state': 'ACTIVE',
|
||||
'type': 'HSRP'}
|
||||
self.global_router[ha.DETAILS] = self.cisco_ha_details_global
|
||||
self.global_router['gw_port'][HA_INFO]['ha_port']['fixed_ips'][0][
|
||||
'ip_address'] = self.ex_gw_ip_vip
|
||||
self.global_router['gw_port'] = None
|
||||
self.ri_global = routing_svc_helper.RouterInfo(
|
||||
FAKE_ID, self.global_router)
|
||||
self.ri_global.internal_ports = int_ports
|
||||
|
@ -246,6 +253,20 @@ class ASR1kRoutingDriver(base.BaseTestCase):
|
|||
self.assert_edit_run_cfg(
|
||||
snippets.SET_INTC_ASR_HSRP_EXTERNAL, cfg_args_hsrp)
|
||||
|
||||
def test_internal_network_added_global_router_secondary_subnet(self):
|
||||
self.port['ip_info']['is_primary'] = False
|
||||
self.global_router[bc.constants.INTERFACE_KEY][0]['ip_info'][
|
||||
'is_primary'] = False
|
||||
self.driver.internal_network_added(self.ri_global, self.port)
|
||||
sub_interface = self.phy_infc + '.' + str(self.vlan_int)
|
||||
cfg_args_sub = (sub_interface, self.gw_ip, self.gw_ip_mask)
|
||||
self.assert_edit_run_cfg(
|
||||
snippets.SET_SUBINTERFACE_SECONDARY_IP, cfg_args_sub)
|
||||
|
||||
cfg_args_hsrp = (sub_interface, self.gw_ha_group, self.gw_ip_vip)
|
||||
self.assert_edit_run_cfg(
|
||||
snippets.SET_INTC_ASR_SECONDARY_HSRP_EXTERNAL, cfg_args_hsrp)
|
||||
|
||||
def test_internal_network_added_global_router_with_multi_region(self):
|
||||
cfg.CONF.set_override('enable_multi_region', True, 'multi_region')
|
||||
is_multi_region_enabled = cfg.CONF.multi_region.enable_multi_region
|
||||
|
@ -265,6 +286,25 @@ class ASR1kRoutingDriver(base.BaseTestCase):
|
|||
self.assert_edit_run_cfg(
|
||||
snippets.SET_INTC_ASR_HSRP_EXTERNAL, cfg_args_hsrp)
|
||||
|
||||
def test_internal_network_added_global_router_with_multi_region_sec_sn(
|
||||
self):
|
||||
cfg.CONF.set_override('enable_multi_region', True, 'multi_region')
|
||||
is_multi_region_enabled = cfg.CONF.multi_region.enable_multi_region
|
||||
self.assertEqual(True, is_multi_region_enabled)
|
||||
|
||||
self.port['ip_info']['is_primary'] = False
|
||||
self.global_router[bc.constants.INTERFACE_KEY][0]['ip_info'][
|
||||
'is_primary'] = False
|
||||
self.driver.internal_network_added(self.ri_global, self.port)
|
||||
sub_interface = self.phy_infc + '.' + str(self.vlan_int)
|
||||
cfg_args_sub = (sub_interface, self.gw_ip, self.gw_ip_mask)
|
||||
self.assert_edit_run_cfg(
|
||||
snippets.SET_SUBINTERFACE_SECONDARY_IP, cfg_args_sub)
|
||||
|
||||
cfg_args_hsrp = (sub_interface, self.gw_ha_group, self.gw_ip_vip)
|
||||
self.assert_edit_run_cfg(
|
||||
snippets.SET_INTC_ASR_SECONDARY_HSRP_EXTERNAL, cfg_args_hsrp)
|
||||
|
||||
def _make_test_router_non_ha(self):
|
||||
self.ri.router[ha.ENABLED] = False
|
||||
del self.ri.router[ha.DETAILS]
|
||||
|
|
|
@ -37,25 +37,43 @@ HOST = 'myhost'
|
|||
FAKE_ID = _uuid()
|
||||
|
||||
|
||||
def prepare_router_data(enable_snat=None, num_internal_ports=1):
|
||||
def prepare_router_data(enable_snat=None, num_internal_ports=1,
|
||||
num_subnets=1, is_global=False):
|
||||
router_id = _uuid()
|
||||
ext_fixed_ips = []
|
||||
ext_subnets = []
|
||||
sn_ids = sorted([_uuid() for i in range(num_subnets)])
|
||||
for i in range(num_subnets):
|
||||
sn_id = sn_ids[i]
|
||||
ext_fixed_ips.append({'ip_address': '19.4.%s.4' % i,
|
||||
'subnet_id': sn_id})
|
||||
ext_subnets.append({'id': sn_id, 'cidr': '19.4.%s.0/24' % i,
|
||||
'gateway_ip': '19.4.%s.1' % i})
|
||||
ex_gw_port = {'id': _uuid(),
|
||||
'network_id': _uuid(),
|
||||
'admin_state_up': True,
|
||||
'fixed_ips': [{'ip_address': '19.4.4.4',
|
||||
'subnet_id': _uuid()}],
|
||||
'subnets': [{'cidr': '19.4.4.0/24',
|
||||
'gateway_ip': '19.4.4.1'}]}
|
||||
'fixed_ips': ext_fixed_ips,
|
||||
'subnets': ext_subnets}
|
||||
int_ports = []
|
||||
for i in range(num_internal_ports):
|
||||
num_internal_subnets = 1 if is_global is False else num_subnets
|
||||
for j in range(num_internal_ports):
|
||||
k = 35 + j
|
||||
int_fixed_ips = []
|
||||
int_subnets = []
|
||||
sn_ids = sorted([_uuid() for i in range(num_internal_subnets)])
|
||||
for i in range(num_internal_subnets):
|
||||
sn_id = sn_ids[i]
|
||||
int_fixed_ips.append({'ip_address': '%s.4.%s.4' % (k, i),
|
||||
'subnet_id': sn_id})
|
||||
int_subnets.append({'id': sn_id, 'cidr': '%s.4.%s.0/24' % (k, i),
|
||||
'gateway_ip': '%s.4.%s.1' % (k, i)})
|
||||
int_ports.append({'id': _uuid(),
|
||||
'network_id': _uuid(),
|
||||
'admin_state_up': True,
|
||||
'fixed_ips': [{'ip_address': '35.4.%s.4' % i,
|
||||
'subnet_id': _uuid()}],
|
||||
'fixed_ips': int_fixed_ips,
|
||||
'mac_address': 'ca:fe:de:ad:be:ef',
|
||||
'subnets': [{'cidr': '35.4.%s.0/24' % i,
|
||||
'gateway_ip': '35.4.%s.1' % i}]})
|
||||
'subnets': int_subnets})
|
||||
|
||||
hosting_device = {'id': _uuid(),
|
||||
"name": "CSR1kv_template",
|
||||
"booting_time": 300,
|
||||
|
@ -72,10 +90,14 @@ def prepare_router_data(enable_snat=None, num_internal_ports=1):
|
|||
'admin_state_up': True,
|
||||
bc.constants.INTERFACE_KEY: int_ports,
|
||||
'routes': [],
|
||||
'gw_port': ex_gw_port,
|
||||
'hosting_device': hosting_device,
|
||||
'router_type': '',
|
||||
routerrole.ROUTER_ROLE_ATTR: None}
|
||||
'router_type': ''}
|
||||
if is_global is True:
|
||||
router['gw_port'] = None
|
||||
router[routerrole.ROUTER_ROLE_ATTR] = c_constants.ROUTER_ROLE_GLOBAL
|
||||
else:
|
||||
router['gw_port'] = ex_gw_port
|
||||
router[routerrole.ROUTER_ROLE_ATTR] = None
|
||||
if enable_snat is not None:
|
||||
router['enable_snat'] = enable_snat
|
||||
return router, int_ports
|
||||
|
@ -126,12 +148,13 @@ class TestBasicRoutingOperations(base.BaseTestCase):
|
|||
self.conf = cfg.ConfigOpts()
|
||||
self.conf.register_opts(bc.core_opts)
|
||||
self.conf.register_opts(cfg_agent.OPTS, "cfg_agent")
|
||||
sn_id = _uuid()
|
||||
self.ex_gw_port = {'id': _uuid(),
|
||||
'network_id': _uuid(),
|
||||
'admin_state_up': True,
|
||||
'fixed_ips': [{'ip_address': '19.4.4.4',
|
||||
'subnet_id': _uuid()}],
|
||||
'subnets': [{'cidr': '19.4.4.0/24',
|
||||
'subnet_id': sn_id}],
|
||||
'subnets': [{'id': sn_id, 'cidr': '19.4.4.0/24',
|
||||
'gateway_ip': '19.4.4.1'}]}
|
||||
self.hosting_device = {'id': "100",
|
||||
'name': "CSR1kv_template",
|
||||
|
@ -221,6 +244,27 @@ class TestBasicRoutingOperations(base.BaseTestCase):
|
|||
self.assertRaises(SessionCloseError,
|
||||
self.routing_helper._process_router, ri)
|
||||
|
||||
def test_process_router_throw_no_ip_address_on_subnet_error(self):
|
||||
router, ports = prepare_router_data()
|
||||
# change subnet_id to something that does not exist
|
||||
router['gw_port']['subnets'][0]['id'] = 'fake_uuid'
|
||||
ri = routing_svc_helper.RouterInfo(router['id'], router)
|
||||
self.assertRaises(routing_svc_helper.IPAddressMissingException,
|
||||
self.routing_helper._process_router, ri)
|
||||
|
||||
def _test_process_router_throw_multiple_ipv4_subnets_error(self):
|
||||
router, ports = prepare_router_data(num_subnets=2, is_global=True)
|
||||
# make router a regular one which triggers the error condition
|
||||
router[routerrole.ROUTER_ROLE_ATTR] = None
|
||||
ri = routing_svc_helper.RouterInfo(router['id'], router)
|
||||
return ri, router
|
||||
|
||||
def test_process_router_throw_multiple_ipv4_subnets_error(self):
|
||||
ri, router = (
|
||||
self._test_process_router_throw_multiple_ipv4_subnets_error())
|
||||
self.assertRaises(routing_svc_helper.MultipleIPv4SubnetsException,
|
||||
self.routing_helper._process_router, ri)
|
||||
|
||||
def _test_router_admin_port_state(self, router, ri, ex_gw_port):
|
||||
# change the router admin_state_up to false
|
||||
router['admin_state_up'] = False
|
||||
|
@ -252,9 +296,30 @@ class TestBasicRoutingOperations(base.BaseTestCase):
|
|||
self.assertFalse(self.routing_helper._disable_router_interface.called)
|
||||
self._reset_mocks()
|
||||
|
||||
def test_process_router(self, test_admin_state=True):
|
||||
router, ports = prepare_router_data()
|
||||
#Setup mock for call to proceess floating ips
|
||||
# msn means that the router has an external gateway with multiple subnets
|
||||
def _test_process_msn_router(self, num_ext_subnets=3,
|
||||
test_admin_state=True):
|
||||
|
||||
def _verify_ip_info(the_mock):
|
||||
self.assertEqual(num_ext_subnets, len(the_mock.ip_infos))
|
||||
self.assertTrue(the_mock.ip_infos[0]['is_primary'])
|
||||
self.assertEqual('19.4.0.4/24', the_mock.ip_infos[0]['ip_cidr'])
|
||||
for i in range(1, num_ext_subnets):
|
||||
self.assertFalse(the_mock.ip_infos[i]['is_primary'])
|
||||
self.assertEqual('19.4.%s.4/24' % i,
|
||||
the_mock.ip_infos[i]['ip_cidr'])
|
||||
|
||||
# need these helpers to verify that ip_info is correct
|
||||
def _ext_gw_added(ri, ex_gw_port):
|
||||
self.routing_helper._external_gateway_added.ip_infos.append(
|
||||
copy.deepcopy(ex_gw_port['ip_info']))
|
||||
|
||||
def _ext_gw_removed(ri, ex_gw_port):
|
||||
self.routing_helper._external_gateway_removed.ip_infos.append(
|
||||
copy.deepcopy(ex_gw_port['ip_info']))
|
||||
|
||||
router, ports = prepare_router_data(num_subnets=num_ext_subnets)
|
||||
# Setup mock for call to process floating ips
|
||||
self.routing_helper._process_router_floating_ips = mock.Mock()
|
||||
fake_floatingips1 = {'floatingips': [
|
||||
{'id': _uuid(),
|
||||
|
@ -262,17 +327,18 @@ class TestBasicRoutingOperations(base.BaseTestCase):
|
|||
'fixed_ip_address': '7.7.7.7',
|
||||
'port_id': _uuid()}]}
|
||||
ri = routing_svc_helper.RouterInfo(router['id'], router=router)
|
||||
self.routing_helper._external_gateway_added.ip_infos = []
|
||||
self.routing_helper._external_gateway_added.side_effect = _ext_gw_added
|
||||
# Process with initial values
|
||||
self.routing_helper._process_router(ri)
|
||||
ex_gw_port = ri.router.get('gw_port')
|
||||
# Assert that process_floating_ips, internal_network & external network
|
||||
# added were all called with the right params
|
||||
self.routing_helper._process_router_floating_ips.assert_called_with(
|
||||
ri, ex_gw_port)
|
||||
self.routing_helper._internal_network_added.assert_called_with(
|
||||
(self.routing_helper._process_router_floating_ips
|
||||
.assert_called_once_with(ri, ex_gw_port))
|
||||
self.routing_helper._internal_network_added.assert_called_once_with(
|
||||
ri, ports[0], ex_gw_port)
|
||||
self.routing_helper._external_gateway_added.assert_called_with(
|
||||
ri, ex_gw_port)
|
||||
_verify_ip_info(self.routing_helper._external_gateway_added)
|
||||
self._reset_mocks()
|
||||
# remap floating IP to a new fixed ip
|
||||
fake_floatingips2 = copy.deepcopy(fake_floatingips1)
|
||||
|
@ -283,8 +349,8 @@ class TestBasicRoutingOperations(base.BaseTestCase):
|
|||
# was only called.
|
||||
self.routing_helper._process_router(ri)
|
||||
ex_gw_port = ri.router.get('gw_port')
|
||||
self.routing_helper._process_router_floating_ips.assert_called_with(
|
||||
ri, ex_gw_port)
|
||||
(self.routing_helper._process_router_floating_ips
|
||||
.assert_called_once_with(ri, ex_gw_port))
|
||||
self.assertFalse(self.routing_helper._internal_network_added.called)
|
||||
self.assertFalse(self.routing_helper._external_gateway_added.called)
|
||||
self._reset_mocks()
|
||||
|
@ -294,8 +360,8 @@ class TestBasicRoutingOperations(base.BaseTestCase):
|
|||
# process_floating_ips and external_network remove was called
|
||||
self.routing_helper._process_router(ri)
|
||||
ex_gw_port = ri.router.get('gw_port')
|
||||
self.routing_helper._process_router_floating_ips.assert_called_with(
|
||||
ri, ex_gw_port)
|
||||
(self.routing_helper._process_router_floating_ips
|
||||
.assert_called_once_with(ri, ex_gw_port))
|
||||
self.assertFalse(self.routing_helper._internal_network_added.called)
|
||||
self.assertFalse(self.routing_helper._external_gateway_added.called)
|
||||
self._reset_mocks()
|
||||
|
@ -310,18 +376,79 @@ class TestBasicRoutingOperations(base.BaseTestCase):
|
|||
ri.router = router
|
||||
# Keep a copy of the ex_gw_port before its gone after processing.
|
||||
ex_gw_port = ri.ex_gw_port
|
||||
self.routing_helper._external_gateway_removed.ip_infos = []
|
||||
self.routing_helper._external_gateway_removed.side_effect = (
|
||||
_ext_gw_removed)
|
||||
# Process router and verify that internal and external network removed
|
||||
# were called and floating_ips_process was called
|
||||
self.routing_helper._process_router(ri)
|
||||
self.assertFalse(self.routing_helper.
|
||||
_process_router_floating_ips.called)
|
||||
self.assertFalse(self.routing_helper._external_gateway_added.called)
|
||||
self.assertTrue(self.routing_helper._internal_network_removed.called)
|
||||
self.assertTrue(self.routing_helper._external_gateway_removed.called)
|
||||
self.routing_helper._internal_network_removed.assert_called_with(
|
||||
self.routing_helper._internal_network_removed.assert_called_once_with(
|
||||
ri, ports[0], ex_gw_port)
|
||||
self.routing_helper._external_gateway_removed.assert_called_with(
|
||||
ri, ex_gw_port)
|
||||
_verify_ip_info(self.routing_helper._external_gateway_removed)
|
||||
|
||||
def test_process_router(self, test_admin_state=True):
|
||||
self._test_process_msn_router(num_ext_subnets=1,
|
||||
test_admin_state=test_admin_state)
|
||||
|
||||
def test_process_msn_router(self):
|
||||
self._test_process_msn_router()
|
||||
|
||||
def _test_process_global_msn_router(self, num_ext_subnets=3):
|
||||
|
||||
def _verify_ip_info(the_mock):
|
||||
self.assertEqual(num_ext_subnets, len(the_mock.ip_infos))
|
||||
self.assertTrue(the_mock.ip_infos[0]['is_primary'])
|
||||
self.assertEqual('35.4.0.4/24', the_mock.ip_infos[0]['ip_cidr'])
|
||||
for i in range(1, num_ext_subnets):
|
||||
self.assertFalse(the_mock.ip_infos[i]['is_primary'])
|
||||
self.assertEqual('35.4.%s.4/24' % i,
|
||||
the_mock.ip_infos[i]['ip_cidr'])
|
||||
|
||||
# need these helpers to verify that ip_info is correct
|
||||
def _int_nw_added(ri, port, ex_gw_port):
|
||||
self.assertIsNone(ex_gw_port)
|
||||
self.routing_helper._internal_network_added.ip_infos.append(
|
||||
copy.deepcopy(port['ip_info']))
|
||||
|
||||
router, ports = prepare_router_data(num_subnets=num_ext_subnets,
|
||||
is_global=True)
|
||||
# Setup mock for call to process floating ips
|
||||
self.routing_helper._process_router_floating_ips = mock.Mock()
|
||||
ri = routing_svc_helper.RouterInfo(router['id'], router=router)
|
||||
self.routing_helper._internal_network_added.ip_infos = []
|
||||
self.routing_helper._internal_network_added.side_effect = _int_nw_added
|
||||
# Process with initial values
|
||||
self.routing_helper._process_router(ri)
|
||||
self.assertFalse(self.routing_helper.
|
||||
_process_router_floating_ips.called)
|
||||
self.assertFalse(self.routing_helper._external_gateway_added.called)
|
||||
_verify_ip_info(self.routing_helper._internal_network_added)
|
||||
self._reset_mocks()
|
||||
|
||||
# now no ports so state is torn down
|
||||
del router[bc.constants.INTERFACE_KEY]
|
||||
# Update router_info object
|
||||
ri.router = router
|
||||
|
||||
# Process router and verify that internal and external network removed
|
||||
# were called and floating_ips_process was called
|
||||
self.routing_helper._process_router(ri)
|
||||
self.assertFalse(self.routing_helper.
|
||||
_process_router_floating_ips.called)
|
||||
self.assertFalse(self.routing_helper._external_gateway_added.called)
|
||||
self.assertFalse(self.routing_helper._external_gateway_removed.called)
|
||||
self.assertFalse(self.routing_helper._internal_network_added.called)
|
||||
self.routing_helper._internal_network_removed.assert_called_once_with(
|
||||
ri, ports[0], None)
|
||||
|
||||
def test_process_global_router(self):
|
||||
self._test_process_global_msn_router(num_ext_subnets=1,)
|
||||
|
||||
def test_process_global_msn_router(self):
|
||||
self._test_process_global_msn_router()
|
||||
|
||||
def test_routing_table_update(self):
|
||||
router = self.router
|
||||
|
|
|
@ -80,10 +80,20 @@ class TestBasicRoutingOperationsAci(helper.TestBasicRoutingOperations):
|
|||
self.driver = self._mock_driver_and_hosting_device(
|
||||
self.routing_helper)
|
||||
|
||||
def test_process_router_throw_multiple_ipv4_subnets_error(self):
|
||||
ri, router = (
|
||||
self._test_process_router_throw_multiple_ipv4_subnets_error())
|
||||
router['gw_port'] = {'id': ''}
|
||||
self.assertRaises(svc_helper.MultipleIPv4SubnetsException,
|
||||
self.routing_helper._process_router, ri)
|
||||
|
||||
def test_process_router(self):
|
||||
super(TestBasicRoutingOperationsAci,
|
||||
self).test_process_router(test_admin_state=False)
|
||||
|
||||
def test_process_msn_router(self):
|
||||
self._test_process_msn_router(test_admin_state=False)
|
||||
|
||||
def test_process_router_2_rids_1_vrf(self):
|
||||
driver = self._mock_driver_and_hosting_device(self.routing_helper)
|
||||
router1, ports = helper.prepare_router_data()
|
||||
|
|
|
@ -146,6 +146,7 @@ class TestHwVLANTrunkingPlugDriver(
|
|||
fake_port_db_obj.hosting_info = mock.MagicMock()
|
||||
fake_port_db_obj.hosting_info.segmentation_id = 50
|
||||
fake_port_db_obj.device_owner = bc.constants.DEVICE_OWNER_ROUTER_INTF
|
||||
fake_port_db_obj.networks.external = None
|
||||
hosting_device = {'id': '00000000-0000-0000-0000-000000000002'}
|
||||
tenant_id = 'tenant_uuid1'
|
||||
ctx = context.Context('', tenant_id, is_admin=True)
|
||||
|
@ -162,6 +163,7 @@ class TestHwVLANTrunkingPlugDriver(
|
|||
fake_port_db_obj.hosting_info = mock.MagicMock()
|
||||
fake_port_db_obj.hosting_info.segmentation_id = 40
|
||||
fake_port_db_obj.device_owner = bc.constants.DEVICE_OWNER_ROUTER_GW
|
||||
fake_port_db_obj.networks.external = {'external': True}
|
||||
hosting_device = {'id': '00000000-0000-0000-0000-000000000002'}
|
||||
tenant_id = 'tenant_uuid1'
|
||||
ctx = context.Context('', tenant_id, is_admin=True)
|
||||
|
|
|
@ -63,6 +63,9 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
router_type = 'Nexus_ToR_Neutron_router'
|
||||
|
||||
def _verify_global_router(self, role, hd_id, ext_net_ids):
|
||||
# The 'ext_net_ids' argument is a dict where key is ext_net_id and
|
||||
# value is a list of subnet_ids that the global router should be
|
||||
# connected to
|
||||
if role == ROUTER_ROLE_LOGICAL_GLOBAL or hd_id is None:
|
||||
q_p = '%s=%s' % (ROUTER_ROLE_ATTR, role)
|
||||
else:
|
||||
|
@ -85,10 +88,18 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
DEVICE_OWNER_GLOBAL_ROUTER_GW)
|
||||
aux_gw_ports = self._list('ports', query_params=q_p)['ports']
|
||||
self.assertEqual(len(ext_net_ids), len(aux_gw_ports))
|
||||
ids = copy.copy(ext_net_ids)
|
||||
ids = copy.deepcopy(ext_net_ids)
|
||||
# check that there are ports on each external network
|
||||
for aux_gw_port in aux_gw_ports:
|
||||
self.assertIn(aux_gw_port['network_id'], ids)
|
||||
ids.remove(aux_gw_port['network_id'])
|
||||
self.assertEqual(len(aux_gw_port['fixed_ips']),
|
||||
len(ids[aux_gw_port['network_id']]))
|
||||
# check that port has ip on correct subnets
|
||||
for ips in aux_gw_port['fixed_ips']:
|
||||
self.assertIn(ips['subnet_id'],
|
||||
ids[aux_gw_port['network_id']])
|
||||
ids[aux_gw_port['network_id']].remove(ips['subnet_id'])
|
||||
ids.pop(aux_gw_port['network_id'])
|
||||
return router['id']
|
||||
|
||||
def _verify_routers(self, router_ids, ext_net_ids, hd_id=None,
|
||||
|
@ -134,16 +145,21 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
self.network(tenant_id=tenant_id_2) as n_external_2:
|
||||
ext_net_1_id = n_external_1['network']['id']
|
||||
self._set_net_external(ext_net_1_id)
|
||||
self._create_subnet(self.fmt, ext_net_1_id, cidr='10.0.1.0/24',
|
||||
tenant_id=tenant_id_1)
|
||||
sn_1 = self._make_subnet(
|
||||
self.fmt, n_external_1, '10.0.1.1', cidr='10.0.1.0/24',
|
||||
tenant_id=tenant_id_1)['subnet']
|
||||
ext_net_ids = {ext_net_1_id: [sn_1['id']]}
|
||||
ext_gw_1 = {'network_id': ext_net_1_id}
|
||||
if same_ext_net is False:
|
||||
ext_net_2_id = n_external_2['network']['id']
|
||||
self._set_net_external(ext_net_2_id)
|
||||
self._create_subnet(self.fmt, ext_net_2_id, cidr='10.0.2.0/24',
|
||||
tenant_id=tenant_id_2)
|
||||
sn_2 = self._make_subnet(
|
||||
self.fmt, n_external_2, '10.0.2.1', cidr='10.0.2.0/24',
|
||||
tenant_id=tenant_id_2)['subnet']
|
||||
ext_gw_2_subnets = [sn_2['id']]
|
||||
else:
|
||||
ext_net_2_id = ext_net_1_id
|
||||
ext_gw_1 = {'network_id': ext_net_1_id}
|
||||
ext_gw_2_subnets = [sn_1['id']]
|
||||
ext_gw_2 = {'network_id': ext_net_2_id}
|
||||
with self.router(
|
||||
tenant_id=tenant_id_1, external_gateway_info=ext_gw_1,
|
||||
|
@ -153,14 +169,14 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
r1_after = self._show('routers', r1['id'])['router']
|
||||
hd_id = r1_after[HOSTING_DEVICE_ATTR]
|
||||
# should have one global router now
|
||||
self._verify_routers({r1['id']}, {ext_net_1_id}, hd_id)
|
||||
self._verify_routers({r1['id']}, ext_net_ids, hd_id)
|
||||
with self.router(
|
||||
tenant_id=tenant_id_2, external_gateway_info=ext_gw_1,
|
||||
set_context=set_context) as router2:
|
||||
r2 = router2['router']
|
||||
self.l3_plugin._process_backlogged_routers()
|
||||
# should still have only one global router
|
||||
self._verify_routers({r1['id'], r2['id']}, {ext_net_1_id},
|
||||
self._verify_routers({r1['id'], r2['id']}, ext_net_ids,
|
||||
hd_id)
|
||||
with self.router(name='router2', tenant_id=tenant_id_2,
|
||||
external_gateway_info=ext_gw_2,
|
||||
|
@ -169,9 +185,9 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
self.l3_plugin._process_backlogged_routers()
|
||||
# should still have only one global router but now with
|
||||
# one extra auxiliary gateway port
|
||||
ext_net_ids[ext_net_2_id] = ext_gw_2_subnets
|
||||
self._verify_routers(
|
||||
{r1['id'], r2['id'], r3['id']},
|
||||
{ext_net_1_id, ext_net_2_id}, hd_id)
|
||||
{r1['id'], r2['id'], r3['id']}, ext_net_ids, hd_id)
|
||||
|
||||
# single tenant and single external network
|
||||
def test_create_gateway_router(self):
|
||||
|
@ -202,12 +218,89 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
self._test_create_gateway_router(True, same_tenant=False,
|
||||
same_ext_net=False)
|
||||
|
||||
# msn - multiple subnets (on a single neutron external network)
|
||||
def _test_create_msn_gateway_router(self, set_context=False,
|
||||
same_tenant=True, same_ext_net=True):
|
||||
tenant_id_1 = _uuid()
|
||||
tenant_id_2 = tenant_id_1 if same_tenant is True else _uuid()
|
||||
with self.network(tenant_id=tenant_id_1) as msn_n_external_1,\
|
||||
self.network(tenant_id=tenant_id_2) as n_external_2:
|
||||
msn_ext_net_1_id = msn_n_external_1['network']['id']
|
||||
self._set_net_external(msn_ext_net_1_id)
|
||||
sn_1 = self._make_subnet(
|
||||
self.fmt, msn_n_external_1, '10.0.1.1', cidr='10.0.1.0/24',
|
||||
tenant_id=tenant_id_1)['subnet']
|
||||
sn_2 = self._make_subnet(
|
||||
self.fmt, msn_n_external_1, '20.0.1.1', cidr='20.0.1.0/24',
|
||||
tenant_id=tenant_id_1)['subnet']
|
||||
ext_gw_1_subnets = [sn_1['id'], sn_2['id']]
|
||||
ext_net_ids = {msn_ext_net_1_id: ext_gw_1_subnets}
|
||||
ext_gw_1 = {
|
||||
'network_id': msn_ext_net_1_id,
|
||||
'external_fixed_ips': [{'subnet_id': sid}
|
||||
for sid in ext_gw_1_subnets]}
|
||||
if same_ext_net is False:
|
||||
ext_net_2_id = n_external_2['network']['id']
|
||||
self._set_net_external(ext_net_2_id)
|
||||
sn_3 = self._make_subnet(
|
||||
self.fmt, n_external_2, '10.0.2.1', cidr='10.0.2.0/24',
|
||||
tenant_id=tenant_id_2)['subnet']
|
||||
ext_gw_2_subnets = [sn_3['id']]
|
||||
ext_gw_2 = {'network_id': ext_net_2_id,
|
||||
'external_fixed_ips': [{'subnet_id': sn_3['id']}]}
|
||||
else:
|
||||
ext_net_2_id = msn_ext_net_1_id
|
||||
ext_gw_2_subnets = ext_gw_1_subnets
|
||||
ext_gw_2 = ext_gw_1
|
||||
with self.router(
|
||||
tenant_id=tenant_id_1, external_gateway_info=ext_gw_1,
|
||||
set_context=set_context) as router1:
|
||||
r1 = router1['router']
|
||||
self.l3_plugin._process_backlogged_routers()
|
||||
r1_after = self._show('routers', r1['id'])['router']
|
||||
hd_id = r1_after[HOSTING_DEVICE_ATTR]
|
||||
# should have one global router now
|
||||
self._verify_routers({r1['id']}, ext_net_ids, hd_id)
|
||||
with self.router(
|
||||
tenant_id=tenant_id_2, external_gateway_info=ext_gw_1,
|
||||
set_context=set_context) as router2:
|
||||
r2 = router2['router']
|
||||
self.l3_plugin._process_backlogged_routers()
|
||||
# should still have only one global router
|
||||
self._verify_routers({r1['id'], r2['id']}, ext_net_ids,
|
||||
hd_id)
|
||||
with self.router(name='router2', tenant_id=tenant_id_2,
|
||||
external_gateway_info=ext_gw_2,
|
||||
set_context=set_context) as router3:
|
||||
r3 = router3['router']
|
||||
self.l3_plugin._process_backlogged_routers()
|
||||
# should still have only one global router but now with
|
||||
# one extra auxiliary gateway port
|
||||
ext_net_ids[ext_net_2_id] = ext_gw_2_subnets
|
||||
self._verify_routers(
|
||||
{r1['id'], r2['id'], r3['id']},
|
||||
ext_net_ids, hd_id)
|
||||
|
||||
# single tenant and single external network with two subnets
|
||||
def test_create_msn_gateway_router(self):
|
||||
self._test_create_msn_gateway_router()
|
||||
|
||||
def test_create_msn_gateway_router_dt(self):
|
||||
self._test_create_msn_gateway_router(same_tenant=False)
|
||||
|
||||
def test_create_msn_gateway_router_den(self):
|
||||
self._test_create_msn_gateway_router(same_ext_net=False)
|
||||
|
||||
def test_create_msn_gateway_router_dt_den(self):
|
||||
self._test_create_msn_gateway_router(same_tenant=False,
|
||||
same_ext_net=False)
|
||||
|
||||
def _test_create_router_adds_no_global_router(self, set_context=False):
|
||||
with self.router(set_context=set_context) as router:
|
||||
r = router['router']
|
||||
self.l3_plugin._process_backlogged_routers()
|
||||
# should have no global routers
|
||||
self._verify_routers({r['id']}, set(), None)
|
||||
self._verify_routers({r['id']}, {}, None)
|
||||
|
||||
def test_create_router_adds_no_global_router(self):
|
||||
self._test_create_router_adds_no_global_router()
|
||||
|
@ -222,8 +315,10 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
with self.network(tenant_id=tenant_id_1) as n_external_1:
|
||||
ext_net_1_id = n_external_1['network']['id']
|
||||
self._set_net_external(ext_net_1_id)
|
||||
self._create_subnet(self.fmt, ext_net_1_id, cidr='10.0.1.0/24',
|
||||
tenant_id=tenant_id_1)
|
||||
sn_1 = self._make_subnet(
|
||||
self.fmt, n_external_1, '10.0.1.1', cidr='10.0.1.0/24',
|
||||
tenant_id=tenant_id_1)['subnet']
|
||||
ext_net_ids = {ext_net_1_id: [sn_1['id']]}
|
||||
ext_gw_1 = {'network_id': ext_net_1_id}
|
||||
with self.router(
|
||||
tenant_id=tenant_id_1, external_gateway_info=ext_gw_1,
|
||||
|
@ -238,8 +333,7 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
# backlog processing will trigger one routers_updated
|
||||
# notification containing r1 and r2
|
||||
self.l3_plugin._process_backlogged_routers()
|
||||
self._verify_routers({r1['id'], r2['id']}, {ext_net_1_id},
|
||||
hd_id)
|
||||
self._verify_routers({r1['id'], r2['id']}, ext_net_ids, hd_id)
|
||||
|
||||
def test_create_router_adds_no_aux_gw_port_to_global_router(self):
|
||||
self._test_create_router_adds_no_aux_gw_port_to_global_router()
|
||||
|
@ -265,16 +359,21 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
self.network(tenant_id=tenant_id_2) as n_external_2:
|
||||
ext_net_1_id = n_external_1['network']['id']
|
||||
self._set_net_external(ext_net_1_id)
|
||||
self._create_subnet(self.fmt, ext_net_1_id, cidr='10.0.1.0/24',
|
||||
tenant_id=tenant_id_1)
|
||||
sn_1 = self._make_subnet(
|
||||
self.fmt, n_external_1, '10.0.1.1', cidr='10.0.1.0/24',
|
||||
tenant_id=tenant_id_1)['subnet']
|
||||
ext_net_ids = {ext_net_1_id: [sn_1['id']]}
|
||||
ext_gw_1 = {'network_id': ext_net_1_id}
|
||||
if same_ext_net is False:
|
||||
ext_net_2_id = n_external_2['network']['id']
|
||||
self._set_net_external(ext_net_2_id)
|
||||
self._create_subnet(self.fmt, ext_net_2_id, cidr='10.0.2.0/24',
|
||||
tenant_id=tenant_id_2)
|
||||
sn_2 = self._make_subnet(
|
||||
self.fmt, n_external_2, '10.0.2.1', cidr='10.0.2.0/24',
|
||||
tenant_id=tenant_id_2)['subnet']
|
||||
ext_gw_2_subnets = [sn_2['id']]
|
||||
else:
|
||||
ext_net_2_id = ext_net_1_id
|
||||
ext_gw_1 = {'network_id': ext_net_1_id}
|
||||
ext_gw_2_subnets = [sn_1['id']]
|
||||
ext_gw_2 = {'network_id': ext_net_2_id}
|
||||
with self.router(tenant_id=tenant_id_1,
|
||||
set_context=set_context) as router1, \
|
||||
|
@ -287,7 +386,6 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
self.l3_plugin._process_backlogged_routers()
|
||||
# should have no global router yet
|
||||
r_ids = {r1['id'], r2['id']}
|
||||
ext_net_ids = {ext_net_1_id}
|
||||
self._verify_routers(r_ids, ext_net_ids)
|
||||
r_spec = {'router': {l3.EXTERNAL_GW_INFO: ext_gw_1}}
|
||||
r1_after = self._update('routers', r1['id'], r_spec)['router']
|
||||
|
@ -298,7 +396,7 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
self._update('routers', r2['id'], r_spec)['router']
|
||||
# should still have only one global router but now with
|
||||
# one extra auxiliary gateway port
|
||||
ext_net_ids = {ext_net_1_id, ext_net_2_id}
|
||||
ext_net_ids[ext_net_2_id] = ext_gw_2_subnets
|
||||
self._verify_routers(r_ids, ext_net_ids, hd_id, [1, 3])
|
||||
|
||||
def test_update_router_set_gateway(self):
|
||||
|
@ -327,6 +425,90 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
self._test_update_router_set_gateway(True, same_tenant=False,
|
||||
same_ext_net=False)
|
||||
|
||||
def _test_update_router_set_msn_gateway(
|
||||
self, set_context=False, same_tenant=True, same_ext_net=True):
|
||||
tenant_id_1 = _uuid()
|
||||
tenant_id_2 = tenant_id_1 if same_tenant is True else _uuid()
|
||||
with self.network(tenant_id=tenant_id_1) as msn_n_external_1, \
|
||||
self.network(tenant_id=tenant_id_2) as n_external_2:
|
||||
msn_ext_net_1_id = msn_n_external_1['network']['id']
|
||||
self._set_net_external(msn_ext_net_1_id)
|
||||
sn_1 = self._make_subnet(
|
||||
self.fmt, msn_n_external_1, '10.0.1.1', cidr='10.0.1.0/24',
|
||||
tenant_id=tenant_id_1)['subnet']
|
||||
sn_2 = self._make_subnet(
|
||||
self.fmt, msn_n_external_1, '20.0.1.1', cidr='20.0.1.0/24',
|
||||
tenant_id=tenant_id_1)['subnet']
|
||||
ext_net_ids = {msn_ext_net_1_id: [sn_1['id'], sn_2['id']]}
|
||||
ext_gw_1 = {
|
||||
'network_id': msn_ext_net_1_id,
|
||||
'external_fixed_ips': [{'subnet_id': sn_1['id']}]}
|
||||
if same_ext_net is False:
|
||||
ext_net_2_id = n_external_2['network']['id']
|
||||
self._set_net_external(ext_net_2_id)
|
||||
sn_3 = self._make_subnet(
|
||||
self.fmt, n_external_2, '10.0.2.1', cidr='10.0.2.0/24',
|
||||
tenant_id=tenant_id_2)['subnet']
|
||||
ext_gw_2_subnets = [sn_3['id']]
|
||||
ext_gw_2 = {'network_id': ext_net_2_id,
|
||||
'external_fixed_ips': [{'subnet_id': sn_3['id']}]}
|
||||
else:
|
||||
ext_net_2_id = msn_ext_net_1_id
|
||||
ext_gw_2_subnets = ext_net_ids[msn_ext_net_1_id]
|
||||
ext_gw_2 = ext_gw_1
|
||||
with self.router(tenant_id=tenant_id_1,
|
||||
set_context=set_context) as router1, \
|
||||
self.router(name='router2', tenant_id=tenant_id_2,
|
||||
set_context=set_context) as router2:
|
||||
r1 = router1['router']
|
||||
r2 = router2['router']
|
||||
# backlog processing will trigger one routers_updated
|
||||
# notification containing r1 and r2
|
||||
self.l3_plugin._process_backlogged_routers()
|
||||
# should have no global router yet
|
||||
r_ids = {r1['id'], r2['id']}
|
||||
self._verify_routers(r_ids, ext_net_ids)
|
||||
r_spec = {'router': {l3.EXTERNAL_GW_INFO: ext_gw_1}}
|
||||
r1_after = self._update('routers', r1['id'], r_spec)['router']
|
||||
res_ips = r1_after[l3.EXTERNAL_GW_INFO]['external_fixed_ips']
|
||||
self.assertEqual(1, len(res_ips))
|
||||
self.assertEqual(sn_1['id'], res_ips[0]['subnet_id'])
|
||||
hd_id = r1_after[HOSTING_DEVICE_ATTR]
|
||||
# should now have one global router
|
||||
self._verify_routers(r_ids, ext_net_ids, hd_id, [1])
|
||||
ext_gw_1_2 = {'network_id': msn_ext_net_1_id,
|
||||
'external_fixed_ips': [{'subnet_id': sn_1['id']},
|
||||
{'subnet_id': sn_2['id']}]}
|
||||
r_spec = {'router': {l3.EXTERNAL_GW_INFO: ext_gw_1_2}}
|
||||
r1_final = self._update('routers', r1['id'], r_spec)['router']
|
||||
res_ips = r1_final[l3.EXTERNAL_GW_INFO]['external_fixed_ips']
|
||||
self.assertEqual(2, len(res_ips))
|
||||
self.assertIn(res_ips[0]['subnet_id'],
|
||||
ext_net_ids[msn_ext_net_1_id])
|
||||
self.assertIn(res_ips[1]['subnet_id'],
|
||||
ext_net_ids[msn_ext_net_1_id])
|
||||
# should now have one global router
|
||||
self._verify_routers(r_ids, ext_net_ids, hd_id, [1])
|
||||
r_spec = {'router': {l3.EXTERNAL_GW_INFO: ext_gw_2}}
|
||||
self._update('routers', r2['id'], r_spec)['router']
|
||||
# should still have only one global router but now with
|
||||
# one extra auxiliary gateway port
|
||||
ext_net_ids[ext_net_2_id] = ext_gw_2_subnets
|
||||
self._verify_routers(r_ids, ext_net_ids, hd_id, [1, 3])
|
||||
|
||||
def test_update_router_set_msn_gateway(self):
|
||||
self._test_update_router_set_msn_gateway()
|
||||
|
||||
def test_update_router_set_msn_gateway_dt(self):
|
||||
self._test_update_router_set_msn_gateway(same_tenant=False)
|
||||
|
||||
def test_update_router_set_msn_gateway_den(self):
|
||||
self._test_update_router_set_msn_gateway(same_ext_net=False)
|
||||
|
||||
def test_update_router_set_msn_gateway_dt_den(self):
|
||||
self._test_update_router_set_msn_gateway(same_tenant=False,
|
||||
same_ext_net=False)
|
||||
|
||||
def _test_router_update_unset_gw_or_delete(
|
||||
self, set_context=False, same_tenant=True, same_ext_net=True,
|
||||
update_operation=True):
|
||||
|
@ -336,16 +518,22 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
self.network(tenant_id=tenant_id_1) as n_external_2:
|
||||
ext_net_1_id = n_external_1['network']['id']
|
||||
self._set_net_external(ext_net_1_id)
|
||||
self._create_subnet(self.fmt, ext_net_1_id, cidr='10.0.1.0/24',
|
||||
tenant_id=tenant_id_1)
|
||||
sn_1 = self._make_subnet(
|
||||
self.fmt, n_external_1, '10.0.1.1', cidr='10.0.1.0/24',
|
||||
tenant_id=tenant_id_1)['subnet']
|
||||
ext_net_ids = {ext_net_1_id: [sn_1['id']]}
|
||||
ext_gw_1 = {'network_id': ext_net_1_id}
|
||||
if same_ext_net is False:
|
||||
ext_net_2_id = n_external_2['network']['id']
|
||||
self._set_net_external(ext_net_2_id)
|
||||
self._create_subnet(self.fmt, ext_net_2_id, cidr='10.0.2.0/24',
|
||||
tenant_id=tenant_id_2)
|
||||
sn_2 = self._make_subnet(
|
||||
self.fmt, n_external_2, '10.0.2.1', cidr='10.0.2.0/24',
|
||||
tenant_id=tenant_id_2)['subnet']
|
||||
ext_gw_2_subnets = [sn_2['id']]
|
||||
else:
|
||||
ext_net_2_id = ext_net_1_id
|
||||
ext_gw_1 = {'network_id': ext_net_1_id}
|
||||
ext_gw_2_subnets = [sn_1['id']]
|
||||
ext_net_ids[ext_net_2_id] = ext_gw_2_subnets
|
||||
ext_gw_2 = {'network_id': ext_net_2_id}
|
||||
with self.router(tenant_id=tenant_id_1,
|
||||
external_gateway_info=ext_gw_1,
|
||||
|
@ -361,7 +549,6 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
r1_after = self._show('routers', r1['id'])['router']
|
||||
hd_id = r1_after[HOSTING_DEVICE_ATTR]
|
||||
r_ids = {r1['id'], r2['id']}
|
||||
ext_net_ids = {ext_net_1_id, ext_net_2_id}
|
||||
# should have one global router now
|
||||
self._verify_routers(r_ids, ext_net_ids, hd_id, [0, 1])
|
||||
if update_operation is True:
|
||||
|
@ -370,8 +557,9 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
else:
|
||||
self._delete('routers', r1['id'])
|
||||
r_ids = {r2['id']}
|
||||
ext_net_ids = {ext_net_2_id}
|
||||
# should still have one global router
|
||||
if same_ext_net is False:
|
||||
ext_net_ids.pop(ext_net_1_id)
|
||||
self._verify_routers(r_ids, ext_net_ids, hd_id, [0, 1])
|
||||
if update_operation is True:
|
||||
self._update('routers', r2['id'], r_spec)
|
||||
|
@ -379,6 +567,7 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
self._delete('routers', r2['id'])
|
||||
r_ids = {}
|
||||
# should have no global router now
|
||||
ext_net_ids.pop(ext_net_2_id, None)
|
||||
self._verify_routers(r_ids, ext_net_ids)
|
||||
|
||||
def test_router_update_unset_gw(self):
|
||||
|
@ -407,6 +596,88 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
self._test_router_update_unset_gw_or_delete(True, same_tenant=False,
|
||||
same_ext_net=False)
|
||||
|
||||
def _test_router_update_unset_msn_gw(
|
||||
self, set_context=False, same_tenant=True, same_ext_net=True):
|
||||
tenant_id_1 = _uuid()
|
||||
tenant_id_2 = tenant_id_1 if same_tenant is True else _uuid()
|
||||
with self.network(tenant_id=tenant_id_1) as msn_n_external_1, \
|
||||
self.network(tenant_id=tenant_id_1) as n_external_2:
|
||||
msn_ext_net_1_id = msn_n_external_1['network']['id']
|
||||
self._set_net_external(msn_ext_net_1_id)
|
||||
sn_1 = self._make_subnet(
|
||||
self.fmt, msn_n_external_1, '10.0.1.1', cidr='10.0.1.0/24',
|
||||
tenant_id=tenant_id_1)['subnet']
|
||||
sn_2 = self._make_subnet(
|
||||
self.fmt, msn_n_external_1, '20.0.1.1', cidr='20.0.1.0/24',
|
||||
tenant_id=tenant_id_1)['subnet']
|
||||
ext_gw_1_subnets = [sn_1['id'], sn_2['id']]
|
||||
ext_net_ids = {msn_ext_net_1_id: ext_gw_1_subnets}
|
||||
ext_gw_1 = {
|
||||
'network_id': msn_ext_net_1_id,
|
||||
'external_fixed_ips': [{'subnet_id': sid}
|
||||
for sid in ext_gw_1_subnets]}
|
||||
if same_ext_net is False:
|
||||
ext_net_2_id = n_external_2['network']['id']
|
||||
self._set_net_external(ext_net_2_id)
|
||||
sn_3 = self._make_subnet(
|
||||
self.fmt, n_external_2, '10.0.2.1', cidr='10.0.2.0/24',
|
||||
tenant_id=tenant_id_2)['subnet']
|
||||
ext_gw_2_subnets = [sn_3['id']]
|
||||
ext_gw_2 = {'network_id': ext_net_2_id,
|
||||
'external_fixed_ips': [{'subnet_id': sn_3['id']}]}
|
||||
else:
|
||||
ext_net_2_id = msn_ext_net_1_id
|
||||
ext_gw_2_subnets = ext_gw_1_subnets
|
||||
ext_gw_2 = ext_gw_1
|
||||
ext_net_ids[ext_net_2_id] = ext_gw_2_subnets
|
||||
with self.router(tenant_id=tenant_id_1,
|
||||
external_gateway_info=ext_gw_1,
|
||||
set_context=set_context) as router1,\
|
||||
self.router(name='router2', tenant_id=tenant_id_2,
|
||||
external_gateway_info=ext_gw_2,
|
||||
set_context=set_context) as router2:
|
||||
r1 = router1['router']
|
||||
r2 = router2['router']
|
||||
# backlog processing will trigger one routers_updated
|
||||
# notification containing r1 and r2
|
||||
self.l3_plugin._process_backlogged_routers()
|
||||
r1_after = self._show('routers', r1['id'])['router']
|
||||
hd_id = r1_after[HOSTING_DEVICE_ATTR]
|
||||
r_ids = {r1['id'], r2['id']}
|
||||
# should have one global router now
|
||||
self._verify_routers(r_ids, ext_net_ids, hd_id, [0, 1])
|
||||
ext_gw_1['external_fixed_ips'] = [{'subnet_id': sn_1['id']}]
|
||||
r_spec = {'router': {l3.EXTERNAL_GW_INFO: ext_gw_1}}
|
||||
r1_after_2 = self._update('routers', r1['id'],
|
||||
r_spec)['router']
|
||||
res_ips = r1_after_2[l3.EXTERNAL_GW_INFO]['external_fixed_ips']
|
||||
self.assertEqual(1, len(res_ips))
|
||||
self.assertEqual(sn_1['id'], res_ips[0]['subnet_id'])
|
||||
# should still have one global router
|
||||
self._verify_routers(r_ids, ext_net_ids, hd_id, [0, 1])
|
||||
r_spec = {'router': {l3.EXTERNAL_GW_INFO: None}}
|
||||
self._update('routers', r1['id'], r_spec)
|
||||
# should still have one global router
|
||||
if same_ext_net is False:
|
||||
ext_net_ids.pop(msn_ext_net_1_id)
|
||||
self._verify_routers(r_ids, ext_net_ids, hd_id, [0, 1])
|
||||
self._update('routers', r2['id'], r_spec)
|
||||
# should have no global router now
|
||||
self._verify_routers(r_ids, ext_net_ids)
|
||||
|
||||
def test_router_update_unset_msn_gw(self):
|
||||
self._test_router_update_unset_msn_gw()
|
||||
|
||||
def test_router_update_unset_msn_gw_dt(self):
|
||||
self._test_router_update_unset_msn_gw(same_tenant=False)
|
||||
|
||||
def test_router_update_unset_msn_gw_den(self):
|
||||
self._test_router_update_unset_msn_gw(same_ext_net=False)
|
||||
|
||||
def test_router_update_unset_msn_gw_dt_den(self):
|
||||
self._test_router_update_unset_msn_gw(same_tenant=False,
|
||||
same_ext_net=False)
|
||||
|
||||
def _test_delete_gateway_router(self, set_context=False, same_tenant=True,
|
||||
same_ext_net=True):
|
||||
self._test_router_update_unset_gw_or_delete(
|
||||
|
@ -437,6 +708,80 @@ class Asr1kRouterTypeDriverTestCase(
|
|||
self._test_delete_gateway_router(True, same_tenant=False,
|
||||
same_ext_net=False)
|
||||
|
||||
def _test_delete_msn_gateway_router(self, set_context=False,
|
||||
same_tenant=True, same_ext_net=True):
|
||||
tenant_id_1 = _uuid()
|
||||
tenant_id_2 = tenant_id_1 if same_tenant is True else _uuid()
|
||||
with self.network(tenant_id=tenant_id_1) as msn_n_external_1, \
|
||||
self.network(tenant_id=tenant_id_1) as n_external_2:
|
||||
msn_ext_net_1_id = msn_n_external_1['network']['id']
|
||||
self._set_net_external(msn_ext_net_1_id)
|
||||
sn_1 = self._make_subnet(
|
||||
self.fmt, msn_n_external_1, '10.0.1.1', cidr='10.0.1.0/24',
|
||||
tenant_id=tenant_id_1)['subnet']
|
||||
sn_2 = self._make_subnet(
|
||||
self.fmt, msn_n_external_1, '20.0.1.1', cidr='20.0.1.0/24',
|
||||
tenant_id=tenant_id_1)['subnet']
|
||||
ext_gw_1_subnets = [sn_1['id'], sn_2['id']]
|
||||
ext_net_ids = {msn_ext_net_1_id: ext_gw_1_subnets}
|
||||
ext_gw_1 = {
|
||||
'network_id': msn_ext_net_1_id,
|
||||
'external_fixed_ips': [{'subnet_id': sid}
|
||||
for sid in ext_gw_1_subnets]}
|
||||
if same_ext_net is False:
|
||||
ext_net_2_id = n_external_2['network']['id']
|
||||
self._set_net_external(ext_net_2_id)
|
||||
sn_3 = self._make_subnet(
|
||||
self.fmt, n_external_2, '10.0.2.1', cidr='10.0.2.0/24',
|
||||
tenant_id=tenant_id_2)['subnet']
|
||||
ext_gw_2_subnets = [sn_3['id']]
|
||||
ext_gw_2 = {'network_id': ext_net_2_id,
|
||||
'external_fixed_ips': [{'subnet_id': sn_3['id']}]}
|
||||
else:
|
||||
ext_net_2_id = msn_ext_net_1_id
|
||||
ext_gw_2_subnets = ext_gw_1_subnets
|
||||
ext_gw_2 = ext_gw_1
|
||||
ext_net_ids[ext_net_2_id] = ext_gw_2_subnets
|
||||
with self.router(tenant_id=tenant_id_1,
|
||||
external_gateway_info=ext_gw_1,
|
||||
set_context=set_context) as router1,\
|
||||
self.router(name='router2', tenant_id=tenant_id_2,
|
||||
external_gateway_info=ext_gw_2,
|
||||
set_context=set_context) as router2:
|
||||
r1 = router1['router']
|
||||
r2 = router2['router']
|
||||
# backlog processing will trigger one routers_updated
|
||||
# notification containing r1 and r2
|
||||
self.l3_plugin._process_backlogged_routers()
|
||||
r1_after = self._show('routers', r1['id'])['router']
|
||||
hd_id = r1_after[HOSTING_DEVICE_ATTR]
|
||||
r_ids = {r1['id'], r2['id']}
|
||||
# should have one global router now
|
||||
self._verify_routers(r_ids, ext_net_ids, hd_id, [0, 1])
|
||||
self._delete('routers', r1['id'])
|
||||
r_ids = {r2['id']}
|
||||
# should still have one global router
|
||||
if same_ext_net is False:
|
||||
ext_net_ids.pop(msn_ext_net_1_id)
|
||||
self._verify_routers(r_ids, ext_net_ids, hd_id, [0, 1])
|
||||
self._delete('routers', r2['id'])
|
||||
r_ids = {}
|
||||
# should have no global router now
|
||||
self._verify_routers(r_ids, ext_net_ids)
|
||||
|
||||
def test_delete_msn_gateway_router(self):
|
||||
self._test_delete_msn_gateway_router()
|
||||
|
||||
def test_delete_msn_gateway_router_dt(self):
|
||||
self._test_delete_msn_gateway_router(same_tenant=False)
|
||||
|
||||
def test_delete_msn_gateway_router_den(self):
|
||||
self._test_delete_msn_gateway_router(same_ext_net=False)
|
||||
|
||||
def test_delete_msn_gateway_router_dt_den(self):
|
||||
self._test_delete_msn_gateway_router(same_tenant=False,
|
||||
same_ext_net=False)
|
||||
|
||||
def _test_router_interface_add_refused_for_unsupported_topology(
|
||||
self, num_expected_ports=2, set_context=False, same_tenant=True):
|
||||
tenant_id_1 = _uuid()
|
||||
|
@ -518,6 +863,9 @@ class Asr1kHARouterTypeDriverTestCase(
|
|||
|
||||
def _verify_routers(self, router_ids, ext_net_ids, hd_id=None,
|
||||
call_indices=None):
|
||||
# The 'ext_net_ids' argument is a dict where key is ext_net_id and
|
||||
# value is a list of subnet_ids that the global router should be
|
||||
# connected to
|
||||
# tenant routers
|
||||
q_p = '%s=None' % ROUTER_ROLE_ATTR
|
||||
r_ids = {r['id'] for r in self._list(
|
||||
|
@ -574,6 +922,9 @@ class L3CfgAgentAsr1kRouterTypeDriverTestCase(
|
|||
super(L3CfgAgentAsr1kRouterTypeDriverTestCase, self).tearDown()
|
||||
|
||||
def _verify_global_router(self, role, hd_id, ext_net_ids):
|
||||
# The 'ext_net_ids' argument is a dict where key is ext_net_id and
|
||||
# value is a list of subnet_ids that the global router should be
|
||||
# connected to
|
||||
if hd_id is None:
|
||||
q_p = '%s=%s' % (ROUTER_ROLE_ATTR, role)
|
||||
else:
|
||||
|
@ -593,10 +944,17 @@ class L3CfgAgentAsr1kRouterTypeDriverTestCase(
|
|||
DEVICE_OWNER_GLOBAL_ROUTER_GW)
|
||||
aux_gw_ports = self._list('ports', query_params=q_p)['ports']
|
||||
self.assertEqual(len(ext_net_ids), len(aux_gw_ports))
|
||||
ids = copy.copy(ext_net_ids)
|
||||
ids = copy.deepcopy(ext_net_ids)
|
||||
for aux_gw_port in aux_gw_ports:
|
||||
self.assertIn(aux_gw_port['network_id'], ids)
|
||||
ids.remove(aux_gw_port['network_id'])
|
||||
self.assertEqual(len(aux_gw_port['fixed_ips']),
|
||||
len(ids[aux_gw_port['network_id']]))
|
||||
# check that port has ip on correct subnets
|
||||
for ips in aux_gw_port['fixed_ips']:
|
||||
self.assertIn(ips['subnet_id'],
|
||||
ids[aux_gw_port['network_id']])
|
||||
ids[aux_gw_port['network_id']].remove(ips['subnet_id'])
|
||||
ids.pop(aux_gw_port['network_id'])
|
||||
return router
|
||||
|
||||
def _verify_ha_settings(self, router, expected_ha):
|
||||
|
@ -628,6 +986,9 @@ class L3CfgAgentAsr1kRouterTypeDriverTestCase(
|
|||
ha_port['fixed_ips'][0]['ip_address'])
|
||||
|
||||
def _verify_sync_data(self, router, router_ids, ext_net_ids):
|
||||
# The 'ext_net_ids' argument is a dict where key is ext_net_id and
|
||||
# value is a list of subnet_ids that the global router should be
|
||||
# connected to
|
||||
hd_id = router[HOSTING_DEVICE_ATTR]
|
||||
id_r_ha_backup = router[ha.DETAILS][ha.REDUNDANCY_ROUTERS][0]['id']
|
||||
router_ha_backup = self._show('routers', id_r_ha_backup)['router']
|
||||
|
@ -675,21 +1036,34 @@ class L3CfgAgentAsr1kRouterTypeDriverTestCase(
|
|||
'allocated_vlan': 5})
|
||||
tenant_id_1 = _uuid()
|
||||
tenant_id_2 = tenant_id_1 if same_tenant is True else _uuid()
|
||||
with self.network(tenant_id=tenant_id_1) as n_external_1, \
|
||||
with self.network(tenant_id=tenant_id_1) as msn_n_external_1, \
|
||||
self.network(tenant_id=tenant_id_1) as n_external_2:
|
||||
ext_net_1_id = n_external_1['network']['id']
|
||||
self._set_net_external(ext_net_1_id)
|
||||
self._create_subnet(self.fmt, ext_net_1_id, cidr='10.0.1.0/24',
|
||||
tenant_id=tenant_id_1)
|
||||
msn_ext_net_1_id = msn_n_external_1['network']['id']
|
||||
self._set_net_external(msn_ext_net_1_id)
|
||||
sn_1 = self._make_subnet(
|
||||
self.fmt, msn_n_external_1, '10.0.1.1', cidr='10.0.1.0/24',
|
||||
tenant_id=tenant_id_1)['subnet']
|
||||
sn_2 = self._make_subnet(
|
||||
self.fmt, msn_n_external_1, '20.0.1.1', cidr='20.0.1.0/24',
|
||||
tenant_id=tenant_id_1)['subnet']
|
||||
ext_net_ids = {msn_ext_net_1_id: [sn_1['id'], sn_2['id']]}
|
||||
ext_gw_1 = {
|
||||
'network_id': msn_ext_net_1_id,
|
||||
'external_fixed_ips': [{'subnet_id': sn_1['id']}]}
|
||||
if same_ext_net is False:
|
||||
ext_net_2_id = n_external_2['network']['id']
|
||||
self._set_net_external(ext_net_2_id)
|
||||
self._create_subnet(self.fmt, ext_net_2_id, cidr='10.0.2.0/24',
|
||||
tenant_id=tenant_id_2)
|
||||
sn_3 = self._make_subnet(
|
||||
self.fmt, n_external_2, '10.0.2.1', cidr='10.0.2.0/24',
|
||||
tenant_id=tenant_id_2)['subnet']
|
||||
ext_gw_2_subnets = [sn_3['id']]
|
||||
ext_gw_2 = {'network_id': ext_net_2_id,
|
||||
'external_fixed_ips': [{'subnet_id': sn_3['id']}]}
|
||||
else:
|
||||
ext_net_2_id = ext_net_1_id
|
||||
ext_gw_1 = {'network_id': ext_net_1_id}
|
||||
ext_gw_2 = {'network_id': ext_net_2_id}
|
||||
ext_net_2_id = msn_ext_net_1_id
|
||||
ext_gw_2_subnets = ext_net_ids[msn_ext_net_1_id]
|
||||
ext_gw_2 = ext_gw_1
|
||||
ext_net_ids[ext_net_2_id] = ext_gw_2_subnets
|
||||
with self.router(tenant_id=tenant_id_1,
|
||||
external_gateway_info=ext_gw_1,
|
||||
set_context=set_context) as router1, \
|
||||
|
@ -705,7 +1079,6 @@ class L3CfgAgentAsr1kRouterTypeDriverTestCase(
|
|||
self.l3_plugin._process_backlogged_routers()
|
||||
r1_after = self._show('routers', r1['id'])['router']
|
||||
r_ids = [r1['id'], r2['id'], r3['id']]
|
||||
ext_net_ids = {ext_net_1_id, ext_net_2_id}
|
||||
self._verify_sync_data(r1_after, r_ids, ext_net_ids)
|
||||
|
||||
def test_l3_cfg_agent_query_global_router_info(self):
|
||||
|
|
Loading…
Reference in New Issue