From bab6ca08c5a1e455715843598d0fbb87e0c61dea Mon Sep 17 00:00:00 2001 From: Renuka Manavalan Date: Mon, 1 Feb 2021 17:07:25 +0000 Subject: [PATCH 1/6] Update minigraph.py to parse kubernetes config from minigraph.xml, from DeviceMetadata section. --- src/sonic-config-engine/minigraph.py | 17 +++++++++++++++-- .../tests/simple-sample-graph-case.xml | 10 ++++++++++ .../tests/test_minigraph_case.py | 9 ++++++++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index ba81e8faf771..b46b9231eec4 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -780,6 +780,7 @@ def parse_meta(meta, hname): region = None cloudtype = None resource_type = None + kube_data = {} device_metas = meta.find(str(QName(ns, "Devices"))) for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))): if device.find(str(QName(ns1, "Name"))).text.lower() == hname.lower(): @@ -808,7 +809,11 @@ def parse_meta(meta, hname): cloudtype = value elif name == "ResourceType": resource_type = value - return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type + elif name == "KubernetesEnabled": + kube_data["disable"] = value + elif name == "KubernetesServerIp": + kube_data["ip"] = value + return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, kube_data def parse_linkmeta(meta, hname): @@ -1097,6 +1102,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw host_lo_intfs = None is_storage_device = False local_devices = [] + kube_data = {} # hostname is the asic_name, get the asic_id from the asic_name if asic_name is not None: @@ -1133,7 +1139,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw elif child.tag == str(QName(ns, "UngDec")): (u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname, None) elif child.tag == str(QName(ns, "MetadataDeclaration")): - (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type) = parse_meta(child, hostname) + (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, kube_data) = parse_meta(child, hostname) elif child.tag == str(QName(ns, "LinkMetadataDeclaration")): linkmetas = parse_linkmeta(child, hostname) elif child.tag == str(QName(ns, "DeviceInfos")): @@ -1174,6 +1180,13 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw } } + if kube_data: + results['KUBERNETES_MASTER'] = { 'SERVER': { + 'disable': 'True' if kube_data.get('disable', '0') == '0' else 'False', + 'ip': kube_data.get('ip', '') + } + } + results['PEER_SWITCH'] = get_peer_switch_info(linkmetas, devices) if bool(results['PEER_SWITCH']): diff --git a/src/sonic-config-engine/tests/simple-sample-graph-case.xml b/src/sonic-config-engine/tests/simple-sample-graph-case.xml index ce0174adc8dd..95f501200c83 100644 --- a/src/sonic-config-engine/tests/simple-sample-graph-case.xml +++ b/src/sonic-config-engine/tests/simple-sample-graph-case.xml @@ -390,6 +390,16 @@ 10.0.10.7;10.0.10.8 + + KubernetesEnabled + + 0 + + + KubernetesServerIp + + 10.10.10.10 + diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index 6fa7c5352d05..2a46dedda56f 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -1,3 +1,4 @@ +import json import os import subprocess @@ -195,6 +196,12 @@ def test_metadata_tacacs(self): output = self.run_script(argument) self.assertEqual(output.strip(), "{'10.0.10.7': {'priority': '1', 'tcp_port': '49'}, '10.0.10.8': {'priority': '1', 'tcp_port': '49'}}") + def test_metadata_kube(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "KUBERNETES_MASTER[\'SERVER\']"' + output = self.run_script(argument) + self.assertEqual(json.loads(output.strip().replace("'", "\"")), + json.loads('{"ip": "10.10.10.10", "disable": "True"}')) + def test_minigraph_mgmt_port(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "MGMT_PORT"' output = self.run_script(argument) @@ -289,4 +296,4 @@ def test_minigraph_mux_cable_table(self): utils.to_dict(output.strip()), expected_table ) - \ No newline at end of file + From ac3c708251b6cbb7b6cd4d4582e0a85ad3fa1443 Mon Sep 17 00:00:00 2001 From: Renuka Manavalan Date: Tue, 2 Feb 2021 00:09:15 +0000 Subject: [PATCH 2/6] Added cluster to "DEVICE_METADATA|localhost" --- src/sonic-config-engine/minigraph.py | 23 +++++++++++++------ .../tests/test_minigraph_case.py | 5 ++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index b46b9231eec4..624198b6b977 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -84,6 +84,7 @@ def parse_device(device): hwsku = None name = None deployment_id = None + cluster = None for node in device: if node.tag == str(QName(ns, "Address")): @@ -100,11 +101,13 @@ def parse_device(device): deployment_id = node.text elif node.tag == str(QName(ns, "ElementType")): d_type = node.text + elif node.tag == str(QName(ns, "ClusterName")): + cluster = node.text if d_type is None and str(QName(ns3, "type")) in device.attrib: d_type = device.attrib[str(QName(ns3, "type"))] - return (lo_prefix, lo_prefix_v6, mgmt_prefix, name, hwsku, d_type, deployment_id) + return (lo_prefix, lo_prefix_v6, mgmt_prefix, name, hwsku, d_type, deployment_id, cluster) def calculate_lcm_for_ecmp (nhdevices_bank_map, nhip_bank_map): banks_enumerated = {} @@ -244,8 +247,10 @@ def parse_png(png, hname, dpg_ecmp_content = None): if child.tag == str(QName(ns, "Devices")): for device in child.findall(str(QName(ns, "Device"))): - (lo_prefix, lo_prefix_v6, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device) + (lo_prefix, lo_prefix_v6, mgmt_prefix, name, hwsku, d_type, deployment_id, cluster) = parse_device(device) device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku } + if cluster: + device_data['cluster'] = cluster if deployment_id: device_data['deployment_id'] = deployment_id if lo_prefix_v6: @@ -253,9 +258,7 @@ def parse_png(png, hname, dpg_ecmp_content = None): devices[name] = device_data if name == hname: - cluster = device.find(str(QName(ns, "ClusterName"))) - - if cluster != None and cluster.text != None and "str" in cluster.text.lower(): + if cluster and "str" in cluster.lower(): is_storage_device = True if child.tag == str(QName(ns, "DeviceInterfaceLinks")): @@ -380,8 +383,10 @@ def parse_asic_png(png, asic_name, hostname): if child.tag == str(QName(ns, "Devices")): for device in child.findall(str(QName(ns, "Device"))): - (lo_prefix, lo_prefix_v6, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device) + (lo_prefix, lo_prefix_v6, mgmt_prefix, name, hwsku, d_type, deployment_id, cluster) = parse_device(device) device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku } + if cluster: + device_data['cluster'] = cluster if deployment_id: device_data['deployment_id'] = deployment_id if lo_prefix_v6: @@ -1180,6 +1185,10 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw } } + cluster = [devices[key] for key in devices if key.lower() == hostname.lower()][0].get('cluster', "") + if cluster: + results['DEVICE_METADATA']['localhost']['cluster'] = cluster + if kube_data: results['KUBERNETES_MASTER'] = { 'SERVER': { 'disable': 'True' if kube_data.get('disable', '0') == '0' else 'False', @@ -1537,7 +1546,7 @@ def get_mux_cable_entries(mux_cable_ports, neighbors, devices): def parse_device_desc_xml(filename): root = ET.parse(filename).getroot() - (lo_prefix, lo_prefix_v6, mgmt_prefix, hostname, hwsku, d_type, _) = parse_device(root) + (lo_prefix, lo_prefix_v6, mgmt_prefix, hostname, hwsku, d_type, _, _) = parse_device(root) results = {} results['DEVICE_METADATA'] = {'localhost': { diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index 2a46dedda56f..d445c316334f 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -146,6 +146,11 @@ def test_minigraph_deployment_id(self): output = self.run_script(argument) self.assertEqual(output.strip(), "1") + def test_minigraph_cluster(self): + argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_METADATA[\'localhost\'][\'cluster\']"' + output = self.run_script(argument) + self.assertEqual(output.strip(), "AAA00PrdStr00") + def test_minigraph_neighbor_metadata(self): argument = '-m "' + self.sample_graph + '" -p "' + self.port_config + '" -v "DEVICE_NEIGHBOR_METADATA"' From e7c67f0dd9a02a6b1e2eeefe6bbc30a680ec5b6b Mon Sep 17 00:00:00 2001 From: Renuka Manavalan Date: Tue, 2 Feb 2021 00:13:47 +0000 Subject: [PATCH 3/6] Name change to make it better readable. No logical change. --- src/sonic-config-engine/minigraph.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 624198b6b977..4a18a9c778ca 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -815,7 +815,7 @@ def parse_meta(meta, hname): elif name == "ResourceType": resource_type = value elif name == "KubernetesEnabled": - kube_data["disable"] = value + kube_data["enable"] = value elif name == "KubernetesServerIp": kube_data["ip"] = value return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, kube_data @@ -1191,7 +1191,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw if kube_data: results['KUBERNETES_MASTER'] = { 'SERVER': { - 'disable': 'True' if kube_data.get('disable', '0') == '0' else 'False', + 'disable': 'True' if kube_data.get('enable', '0') == '0' else 'False', 'ip': kube_data.get('ip', '') } } From 8d4af6811760019e6d823a8a28347741275c8d3f Mon Sep 17 00:00:00 2001 From: Renuka Manavalan Date: Tue, 2 Feb 2021 00:20:35 +0000 Subject: [PATCH 4/6] Use str(bool) for shorter code. No logical code change --- src/sonic-config-engine/minigraph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 4a18a9c778ca..986d8a84dad4 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -1191,7 +1191,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw if kube_data: results['KUBERNETES_MASTER'] = { 'SERVER': { - 'disable': 'True' if kube_data.get('enable', '0') == '0' else 'False', + 'disable': str(kube_data.get('enable', '0') == '0'), 'ip': kube_data.get('ip', '') } } From d210d14a0622149ef411fed136e9acccb123c714 Mon Sep 17 00:00:00 2001 From: Renuka Manavalan Date: Tue, 2 Feb 2021 01:17:24 +0000 Subject: [PATCH 5/6] Dropped blank line. --- src/sonic-config-engine/tests/test_minigraph_case.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sonic-config-engine/tests/test_minigraph_case.py b/src/sonic-config-engine/tests/test_minigraph_case.py index d445c316334f..64e0bb09d730 100644 --- a/src/sonic-config-engine/tests/test_minigraph_case.py +++ b/src/sonic-config-engine/tests/test_minigraph_case.py @@ -301,4 +301,3 @@ def test_minigraph_mux_cable_table(self): utils.to_dict(output.strip()), expected_table ) - From 89a427febea655c4448ed1828ca6a6875179436e Mon Sep 17 00:00:00 2001 From: Renuka Manavalan Date: Tue, 2 Feb 2021 14:55:30 +0000 Subject: [PATCH 6/6] Little formatting update. No logical code changes. --- src/sonic-config-engine/minigraph.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 986d8a84dad4..06b799cdeff7 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -1190,9 +1190,10 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw results['DEVICE_METADATA']['localhost']['cluster'] = cluster if kube_data: - results['KUBERNETES_MASTER'] = { 'SERVER': { - 'disable': str(kube_data.get('enable', '0') == '0'), - 'ip': kube_data.get('ip', '') + results['KUBERNETES_MASTER'] = { + 'SERVER': { + 'disable': str(kube_data.get('enable', '0') == '0'), + 'ip': kube_data.get('ip', '') } }