From abb9a09d1550f37338155280e9330cab60b86a70 Mon Sep 17 00:00:00 2001 From: Taoyu Li Date: Tue, 24 Oct 2017 01:14:03 +0000 Subject: [PATCH 1/2] [cfg engine] Seperate portconfig.py as individual module for port_config.ini parsing --- src/sonic-config-engine/minigraph.py | 62 +++---------------- src/sonic-config-engine/portconfig.py | 54 ++++++++++++++++ .../tests/sample_output/table_everflow.json | 2 +- src/sonic-config-engine/tests/test_cfggen.py | 2 +- 4 files changed, 63 insertions(+), 57 deletions(-) create mode 100644 src/sonic-config-engine/portconfig.py diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 2cb1c89981e1..3e1e603e6412 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -12,27 +12,13 @@ from lxml import etree as ET from lxml.etree import QName -DOCUMENTATION = ''' ---- -module: minigraph_facts +from portconfig import get_port_config + +"""minigraph.py version_added: "1.9" author: Guohan Lu (gulv@microsoft.com) -short_description: Retrive minigraph facts for a device. -description: - - Retrieve minigraph facts for a device, the facts will be - inserted to the ansible_facts key. -options: - host: - description: - - Set to target snmp server (normally {{inventory_hostname}}) - required: true -''' - -EXAMPLES = ''' -# Gather minigraph facts -- name: Gathering minigraph facts about the device - minigraph_facts: host={{ hostname }} -''' +short_description: Parse minigraph xml file and device description xml file +""" ns = "Microsoft.Search.Autopilot.Evolution" ns1 = "http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution" @@ -319,40 +305,6 @@ def parse_deviceinfo(meta, hwsku): ethernet_interfaces[port_alias_map.get(alias, alias)] = speed return ethernet_interfaces -def parse_port_config(hwsku, platform=None, port_config_file=None): - port_config_candidates = [] - if port_config_file != None: - port_config_candidates.append(port_config_file) - port_config_candidates.append('/usr/share/sonic/hwsku/port_config.ini') - if platform != None: - port_config_candidates.append(os.path.join('/usr/share/sonic/device', platform, hwsku, 'port_config.ini')) - port_config_candidates.append(os.path.join('/usr/share/sonic/platform', hwsku, 'port_config.ini')) - port_config_candidates.append(os.path.join('/usr/share/sonic', hwsku, 'port_config.ini')) - port_config = None - for candidate in port_config_candidates: - if os.path.isfile(candidate): - port_config = candidate - break - if port_config == None: - return None - - ports = {} - with open(port_config) as data: - for line in data: - if line.startswith('#'): - continue - tokens = line.split() - if len(tokens) < 2: - continue - name = tokens[0].strip() - if len(tokens) == 2: - alias = name - else: - alias = tokens[2].strip() - ports[name] = {'alias': alias} - port_alias_map[alias] = name - return ports - def parse_xml(filename, platform=None, port_config_file=None): root = ET.parse(filename).getroot() mini_graph_path = filename @@ -389,8 +341,8 @@ def parse_xml(filename, platform=None, port_config_file=None): if child.tag == str(hostname_qn): hostname = child.text - ports = parse_port_config(hwsku, platform, port_config_file) - + (ports, alias_map) = get_port_config(hwsku, platform, port_config_file) + port_alias_map.update(alias_map) for child in root: if child.tag == str(QName(ns, "DpgDec")): (intfs, lo_intfs, mgmt_intf, vlans, pcs, acls) = parse_dpg(child, hostname) diff --git a/src/sonic-config-engine/portconfig.py b/src/sonic-config-engine/portconfig.py new file mode 100644 index 000000000000..db2baa308174 --- /dev/null +++ b/src/sonic-config-engine/portconfig.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +import os +import sys + + +def get_port_config_file_name(hwsku=None, platform=None): + port_config_candidates = [] + port_config_candidates.append('/usr/share/sonic/hwsku/port_config.ini') + if hwsku: + if platform: + port_config_candidates.append(os.path.join('/usr/share/sonic/device', platform, hwsku, 'port_config.ini')) + port_config_candidates.append(os.path.join('/usr/share/sonic/platform', hwsku, 'port_config.ini')) + port_config_candidates.append(os.path.join('/usr/share/sonic', hwsku, 'port_config.ini')) + for candidate in port_config_candidates: + if os.path.isfile(candidate): + return candidate + return None + + +def get_port_config(hwsku=None, platform=None, port_config_file=None): + if not port_config_file: + port_config_file = get_port_config_file_name(hwsku, platform) + if not port_config_file: + return ({}, {}) + return parse_port_config_file(port_config_file) + + +def parse_port_config_file(port_config_file): + ports = {} + port_alias_map = {} + # Default column definition + titles = ['name', 'lanes', 'alias', 'index'] + with open(port_config_file) as data: + for line in data: + if line.startswith('#'): + if "name" in line: + titles = line.strip('#').split() + continue; + tokens = line.split() + if len(tokens) < 2: + continue + name_index = titles.index('name') + name = tokens[name_index] + data = {} + for i, item in enumerate(tokens): + if i == name_index: + continue + data[titles[i]] = item + data.setdefault('alias', name) + ports[name] = data + port_alias_map[data['alias']] = name + return (ports, port_alias_map) + + diff --git a/src/sonic-config-engine/tests/sample_output/table_everflow.json b/src/sonic-config-engine/tests/sample_output/table_everflow.json index 9686f8e3890d..a4ad52bfe553 100644 --- a/src/sonic-config-engine/tests/sample_output/table_everflow.json +++ b/src/sonic-config-engine/tests/sample_output/table_everflow.json @@ -2,7 +2,7 @@ { "ACL_TABLE:EVERFLOW":{ "policy_desc":"everflow", - "ports":"Ethernet24,Ethernet40,Ethernet20,Ethernet44,Ethernet48,Ethernet28,Ethernet96,Ethernet92,Ethernet76,Ethernet116,Ethernet72,Ethernet112,Ethernet52,Ethernet108,Ethernet56,Ethernet32,Ethernet16,Ethernet36,Ethernet12,Ethernet120,Ethernet8,Ethernet4,Ethernet0,Ethernet124,Ethernet68,Ethernet84,Ethernet100,Ethernet80,Ethernet60,Ethernet104,Ethernet64,Ethernet88", + "ports":"Ethernet24,Ethernet40,Ethernet20,Ethernet44,Ethernet48,Ethernet28,Ethernet96,Ethernet92,Ethernet76,Ethernet116,Ethernet72,Ethernet112,Ethernet52,Ethernet80,Ethernet56,Ethernet32,Ethernet16,Ethernet36,Ethernet12,Ethernet60,Ethernet8,Ethernet4,Ethernet0,Ethernet64,Ethernet68,Ethernet84,Ethernet88,Ethernet108,Ethernet120,Ethernet104,Ethernet124,Ethernet100", "type":"mirror" }, "OP":"SET" diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py index 91d14a043042..57172af97c39 100644 --- a/src/sonic-config-engine/tests/test_cfggen.py +++ b/src/sonic-config-engine/tests/test_cfggen.py @@ -128,4 +128,4 @@ def test_minigraph_deployment_id(self): def test_minigraph_ethernet_interfaces(self): argument = '-m "' + self.sample_graph_simple + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet8\']"' output = self.run_script(argument) - self.assertEqual(output.strip(), "{'alias': 'fortyGigE0/8', 'speed': '40000'}") + self.assertEqual(output.strip(), "{'alias': 'fortyGigE0/8', 'lanes': '37,38,39,40', 'speed': '40000'}") From 555f0274a60a6f38974780290821260eb92592f6 Mon Sep 17 00:00:00 2001 From: Taoyu Li Date: Tue, 24 Oct 2017 01:43:07 +0000 Subject: [PATCH 2/2] Fix setup.py --- src/sonic-config-engine/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-config-engine/setup.py b/src/sonic-config-engine/setup.py index ac4eb16b30e1..1bb597f395f6 100755 --- a/src/sonic-config-engine/setup.py +++ b/src/sonic-config-engine/setup.py @@ -15,7 +15,7 @@ def get_test_suite(): author='Taoyu Li', author_email='taoyl@microsoft.com', url='https://github.com/Azure/sonic-buildimage', - py_modules=['minigraph', 'openconfig_acl', 'sonic_platform'], + py_modules=['portconfig', 'minigraph', 'openconfig_acl', 'sonic_platform'], scripts=['sonic-cfggen', 'translate_acl'], install_requires=['lxml', 'jinja2', 'netaddr', 'ipaddr', 'pyyaml', 'pyangbind'], test_suite='setup.get_test_suite',