diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index f64cbefafbd5..3ee60706d7e2 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -30,6 +30,10 @@ spine_chassis_frontend_role = 'SpineChassisFrontendRouter' chassis_backend_role = 'ChassisBackendRouter' +backend_device_types = ['BackEndToRRouter', 'BackEndLeafRouter'] +VLAN_SUB_INTERFACE_SEPARATOR = '.' +VLAN_SUB_INTERFACE_VLAN_ID = '10' + # Default Virtual Network Index (VNI) vni_default = 8000 @@ -612,6 +616,7 @@ def parse_xml(filename, platform=None, port_config_file=None): vlan_intfs = {} pc_intfs = {} vlan_invert_mapping = { v['alias']:k for k,v in vlans.items() if v.has_key('alias') } + vlan_sub_intfs = {} for intf in intfs: if intf[0][0:4] == 'Vlan': @@ -713,6 +718,32 @@ def parse_xml(filename, platform=None, port_config_file=None): results['PORTCHANNEL_INTERFACE'] = pc_intfs + if current_device['type'] in backend_device_types: + del results['INTERFACE'] + del results['PORTCHANNEL_INTERFACE'] + + for intf in phyport_intfs.keys(): + if isinstance(intf, tuple): + intf_info = list(intf) + intf_info[0] = intf_info[0] + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID + sub_intf = tuple(intf_info) + vlan_sub_intfs[sub_intf] = {} + else: + sub_intf = intf + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID + vlan_sub_intfs[sub_intf] = {"admin_status" : "up"} + + for pc_intf in pc_intfs.keys(): + if isinstance(pc_intf, tuple): + pc_intf_info = list(pc_intf) + pc_intf_info[0] = pc_intf_info[0] + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID + sub_intf = tuple(pc_intf_info) + vlan_sub_intfs[sub_intf] = {} + else: + sub_intf = pc_intf + VLAN_SUB_INTERFACE_SEPARATOR + VLAN_SUB_INTERFACE_VLAN_ID + vlan_sub_intfs[sub_intf] = {"admin_status" : "up"} + + results['VLAN_SUB_INTERFACE'] = vlan_sub_intfs + results['VLAN'] = vlans results['VLAN_MEMBER'] = vlan_members diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index fb85c54cfc90..00c5bfa65ea0 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -2,6 +2,9 @@ import subprocess import os +TOR_ROUTER = 'ToRRouter' +BACKEND_TOR_ROUTER = 'BackEndToRRouter' + class TestCfgGen(TestCase): def setUp(self): @@ -55,10 +58,12 @@ def test_print_data(self): output = self.run_script(argument) self.assertTrue(len(output.strip()) > 0) - def test_jinja_expression(self): - argument = '-m "' + self.sample_graph + '" -v "DEVICE_METADATA[\'localhost\'][\'type\']"' + def test_jinja_expression(self, graph=None, expected_router_type='LeafRouter'): + if graph is None: + graph = self.sample_graph + argument = '-m "' + graph + '" -v "DEVICE_METADATA[\'localhost\'][\'type\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), 'LeafRouter') + self.assertEqual(output.strip(), expected_router_type) def test_additional_json_data(self): argument = '-a \'{"key1":"value1"}\' -v key1' @@ -266,3 +271,55 @@ def test_minigraph_bgp_mon(self): output = self.run_script(argument) self.assertEqual(output.strip(), "{'10.20.30.40': {'rrclient': 0, 'name': 'BGPMonitor', 'local_addr': '10.1.0.32', 'nhopself': 0, 'holdtime': '10', 'asn': '0', 'keepalive': '3'}}") + def test_minigraph_sub_port_interfaces(self, check_stderr=True): + try: + print '\n Change device type to %s' % (BACKEND_TOR_ROUTER) + if check_stderr: + output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (TOR_ROUTER, BACKEND_TOR_ROUTER, self.sample_graph_simple), stderr=subprocess.STDOUT, shell=True) + else: + output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (TOR_ROUTER, BACKEND_TOR_ROUTER, self.sample_graph_simple), shell=True) + + self.test_jinja_expression(self.sample_graph_simple, BACKEND_TOR_ROUTER) + + + # INTERFACE table does not exist + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "INTERFACE"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "") + + # PORTCHANNEL_INTERFACE table does not exist + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORTCHANNEL_INTERFACE"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "") + + # All the other tables stay unchanged + self.test_var_json_data() + self.test_minigraph_vlans() + self.test_minigraph_vlan_members() + self.test_minigraph_vlan_interfaces() + self.test_minigraph_portchannels() + self.test_minigraph_ethernet_interfaces() + self.test_minigraph_extra_ethernet_interfaces() + self.test_minigraph_vnet() + self.test_minigraph_vxlan() + + # VLAN_SUB_INTERFACE + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v VLAN_SUB_INTERFACE' + output = self.run_script(argument) + print output.strip() + self.assertEqual(output.strip(), \ + "{('PortChannel01.10', '10.0.0.56/31'): {}, " + "'Ethernet0.10': {'admin_status': 'up'}, " + "('Ethernet0.10', '10.0.0.58/31'): {}, " + "('PortChannel01.10', 'FC00::71/126'): {}, " + "'PortChannel01.10': {'admin_status': 'up'}, " + "('Ethernet0.10', 'FC00::75/126'): {}}") + + finally: + print '\n Change device type back to %s' % (TOR_ROUTER) + if check_stderr: + output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (BACKEND_TOR_ROUTER, TOR_ROUTER, self.sample_graph_simple), stderr=subprocess.STDOUT, shell=True) + else: + output = subprocess.check_output("sed -i \'s/%s/%s/g\' %s" % (BACKEND_TOR_ROUTER, TOR_ROUTER, self.sample_graph_simple), shell=True) + + self.test_jinja_expression(self.sample_graph_simple, TOR_ROUTER)