From ba1a7a545f7edf6659d268b12a8c5989d5a60130 Mon Sep 17 00:00:00 2001 From: Sangita Maity Date: Thu, 5 Dec 2019 15:58:56 -0800 Subject: [PATCH] [cfg engine] Add support of platform.json parsing to portconfig.py file (#7) * [buildImage] Add support of platform.json parsing to portconfig.py file Signed-off-by: Sangita Maity * [sonic-cfggen] Add a unit-test to test platform capability file Signed-off-by: Sangita Maity * Minor Update Signed-off-by: Sangita Maity * Created One Logic for symmetric and asymmetric modes Signed-off-by: Sangita Maity * Passing tuple from Match_list Signed-off-by: Sangita Maity --- src/sonic-config-engine/portconfig.py | 186 +++- .../tests/sample_output/platform_output.json | 812 ++++++++++++++++++ .../tests/sample_platform.json | 226 +++++ .../tests/test_cfggen_platformJson.py | 75 ++ .../sonic_daemon_base/daemon_base.py | 15 +- 5 files changed, 1298 insertions(+), 16 deletions(-) create mode 100644 src/sonic-config-engine/tests/sample_output/platform_output.json create mode 100644 src/sonic-config-engine/tests/sample_platform.json create mode 100644 src/sonic-config-engine/tests/test_cfggen_platformJson.py diff --git a/src/sonic-config-engine/portconfig.py b/src/sonic-config-engine/portconfig.py index db2baa308174..427ee0e500db 100644 --- a/src/sonic-config-engine/portconfig.py +++ b/src/sonic-config-engine/portconfig.py @@ -1,29 +1,98 @@ #!/usr/bin/env python -import os -import sys +try: + import os + import sys + import json + import ast + import re + from collections import OrderedDict + from swsssdk import ConfigDBConnector +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) +# Global Variable +PLATFORM_ROOT_PATH = '/usr/share/sonic/device' +PLATFORM_ROOT_PATH_DOCKER = '/usr/share/sonic/platform' +SONIC_ROOT_PATH = '/usr/share/sonic' +HWSKU_ROOT_PATH = '/usr/share/sonic/hwsku' + +PLATFORM_JSON = 'platform.json' +PORT_CONFIG_INI = 'portconfig.ini' + +PORT_STR = "Ethernet" +BRKOUT_MODE = "default_brkout_mode" + +BRKOUT_PATTERN = r'(\d{1,3})x(\d{1,3}G)(\[\d{1,3}G\])?(\((\d{1,3})\))?' + +def db_connect_configdb(): + """ + Connect to configdb + """ + config_db = ConfigDBConnector() + if config_db is None: + return None + try: + config_db.connect() + except Exception as e: + print("Config DB is not available with error {}".format(str(e))) + config_db = None + return config_db def get_port_config_file_name(hwsku=None, platform=None): + + # check 'platform.json' file presence + port_config_candidates_Json = [] + port_config_candidates_Json.append(os.path.join(HWSKU_ROOT_PATH, PLATFORM_JSON)) + if platform and hwsku: + port_config_candidates_Json.append(os.path.join(PLATFORM_ROOT_PATH, platform, hwsku, PLATFORM_JSON)) + elif platform and not hwsku: + port_config_candidates_Json.append(os.path.join(PLATFORM_ROOT_PATH, platform, PLATFORM_JSON)) + elif hwsku and not platform: + port_config_candidates_Json.append(os.path.join(PLATFORM_ROOT_PATH_DOCKER, hwsku, PLATFORM_JSON)) + port_config_candidates_Json.append(os.path.join(SONIC_ROOT_PATH, hwsku, PLATFORM_JSON)) + + # check 'portconfig.ini' file presence 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: + port_config_candidates.append(os.path.join(HWSKU_ROOT_PATH, PORT_CONFIG_INI)) + if platform and hwsku: + port_config_candidates.append(os.path.join(PLATFORM_ROOT_PATH, platform, hwsku, PORT_CONFIG_INI)) + elif platform and not hwsku: + port_config_candidates.append(os.path.join(PLATFORM_ROOT_PATH, platform, PORT_CONFIG_INI)) + elif hwsku and not platform: + port_config_candidates.append(os.path.join(PLATFORM_ROOT_PATH_DOCKER, hwsku, PORT_CONFIG_INI)) + port_config_candidates.append(os.path.join(SONIC_ROOT_PATH, hwsku, PORT_CONFIG_INI)) + + for candidate in port_config_candidates_Json + port_config_candidates: if os.path.isfile(candidate): return candidate return None - def get_port_config(hwsku=None, platform=None, port_config_file=None): + config_db = db_connect_configdb() + + # If available, Read from CONFIG DB first + if config_db is not None: + + port_data = config_db.get_table("PORT") + if port_data is not None: + ports = ast.literal_eval(json.dumps(port_data)) + port_alias_map = {} + for intf_name in ports.keys(): + port_alias_map[ports[intf_name]["alias"]]= intf_name + return (ports, port_alias_map) + 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) + # Read from 'platform.json' file + if port_config_file.endswith('.json'): + return parse_platform_json_file(port_config_file) + + # If 'platform.json' file is not available, read from 'port_config.ini' + else: + return parse_port_config_file(port_config_file) def parse_port_config_file(port_config_file): ports = {} @@ -52,3 +121,98 @@ def parse_port_config_file(port_config_file): return (ports, port_alias_map) +# Generate configs (i.e. alias, lanes, speed, index) for port +def gen_port_config(ports, parent_intf_id, index, alias_at_lanes, lanes, k, offset): + if k is not None: + num_lane_used, speed, alt_speed, _ , assigned_lane = k[0], k[1], k[2], k[3], k[4] + + # In case of symmetric mode + if assigned_lane is None: + assigned_lane = len(lanes.split(",")) + + parent_intf_id = int(offset)+int(parent_intf_id) + alias_start = 0 + offset + + step = int(assigned_lane)/int(num_lane_used) + for i in range(0,int(assigned_lane), step): + intf_name = PORT_STR + str(parent_intf_id) + ports[intf_name] = {} + ports[intf_name]['alias'] = alias_at_lanes.split(",")[alias_start] + ports[intf_name]['lanes'] = ','.join(lanes.split(",")[alias_start:alias_start+step]) + if speed: + ports[intf_name]['speed'] = speed + else: + raise Exception('Regex return for speed is None...') + ports[intf_name]['index'] = index.split(",")[alias_start] + ports[intf_name]['admin_status'] = "up" + + parent_intf_id += step + alias_start += step + + offset = int(assigned_lane) + int(offset) + return offset + else: + raise Exception('Regex return for k is None...') + +def parse_platform_json_file(port_config_file, interface_name=None, target_brkout_mode=None): + ports = {} + port_alias_map = {} + + # Read 'platform.json' file + try: + with open(port_config_file) as fp: + try: + data = json.load(fp) + except json.JSONDecodeError as e: + raise Exception("JSONDecodeError:", e) + global port_dict + port_dict = ast.literal_eval(json.dumps(data)) + except: + print("error occurred while parsing json:", sys.exc_info()[1]) + + for intf in port_dict: + if str(interface_name) == intf: + brkout_mode = target_brkout_mode + else: + brkout_mode = port_dict[intf][BRKOUT_MODE] + index = port_dict[intf]['index'] + alias_at_lanes = port_dict[intf]['alias_at_lanes'] + lanes = port_dict[intf]['lanes'] + + # if User does not specify brkout_mode, take default_brkout_mode from platform.json + if brkout_mode is None: + brkout_mode = port_dict[intf][BRKOUT_MODE] + + # Get match_list for Asymmetric breakout mode + if re.search("\+",brkout_mode) is not None: + brkout_parts = brkout_mode.split("+") + match_list = [re.match(BRKOUT_PATTERN, i).groups() for i in brkout_parts] + + # Get match_list for Symmetric breakout mode + else: + match_list = [re.match(BRKOUT_PATTERN, brkout_mode).groups()] + + """ + Example of match_list for some breakout_mode using regex + Breakout Mode -------> Match_list + ----------------------------- + 2x25G(2)+1x50G(2) ---> [('2', '25G', None, '(2)', '2'), ('1', '50G', None, '(2)', '2')] + 1x50G(2)+2x25G(2) ---> [('1', '50G', None, '(2)', '2'), ('2', '25G', None, '(2)', '2')] + 1x100G[40G] ---------> [('1', '100G', '[40G]', None, None)] + 2x50G ---------------> [('2', '50G', None, None, None)] + """ + if match_list is not None: + offset = 0 + parent_intf_id = int(re.search("Ethernet(\d+)", intf).group(1)) + for k in match_list: + # k is a tuple in "match_list" + offset = gen_port_config(ports, parent_intf_id, index, alias_at_lanes, lanes, k, offset) + brkout_mode = None + else: + raise Exception("match_list should not be None.") + if not ports: + raise Exception("Ports dictionary is empty") + + for i in ports.keys(): + port_alias_map[ports[i]["alias"]]= i + return (ports, port_alias_map) diff --git a/src/sonic-config-engine/tests/sample_output/platform_output.json b/src/sonic-config-engine/tests/sample_output/platform_output.json new file mode 100644 index 000000000000..7f187a87b718 --- /dev/null +++ b/src/sonic-config-engine/tests/sample_output/platform_output.json @@ -0,0 +1,812 @@ +{ + "Ethernet8": { + "index": "3", + "lanes": "8", + "description": "Eth3/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth3/1", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet9": { + "index": "3", + "lanes": "9", + "description": " Eth3/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth3/2", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet36": { + "index": "10", + "lanes": "36,37", + "description": "Eth10/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth10/1", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet98": { + "index": "25", + "lanes": "98", + "description": " Eth25/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth25/3", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet0": { + "index": "1", + "lanes": "0,1,2,3", + "description": "Eth1/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth1/1", + "pfc_asym": "off", + "speed": "100G" + }, + "Ethernet6": { + "index": "2", + "lanes": "6,7", + "description": " Eth2/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth2/3", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet4": { + "index": "2", + "lanes": "4,5", + "description": "Eth2/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth2/1", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet109": { + "index": "28", + "lanes": "109", + "description": " Eth28/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth28/2", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet108": { + "index": "28", + "lanes": "108", + "description": "Eth28/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth28/1", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet18": { + "index": "5", + "lanes": "18", + "description": " Eth5/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth5/3", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet100": { + "index": "26", + "lanes": "100,101,102,103", + "description": "Eth26/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth26/1", + "pfc_asym": "off", + "speed": "100G" + }, + "Ethernet34": { + "index": "9", + "lanes": "34,35", + "description": " Eth9/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth9/3", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet104": { + "index": "27", + "lanes": "104,105", + "description": "Eth27/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth27/1", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet106": { + "index": "27", + "lanes": "106,107", + "description": " Eth27/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth27/3", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet94": { + "index": "24", + "lanes": "94,95", + "description": " Eth24/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth24/3", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet126": { + "index": "32", + "lanes": "126,127", + "description": " Eth32/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth32/3", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet96": { + "index": "25", + "lanes": "96,97", + "description": "Eth25/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth25/1", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet124": { + "index": "32", + "lanes": "124,125", + "description": "Eth32/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth32/1", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet90": { + "index": "23", + "lanes": "90", + "description": " Eth23/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth23/3", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet91": { + "index": "23", + "lanes": "91", + "description": " Eth23/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth23/4", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet92": { + "index": "24", + "lanes": "92", + "description": "Eth24/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth24/1", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet93": { + "index": "24", + "lanes": "93", + "description": " Eth24/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth24/2", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet50": { + "index": "13", + "lanes": "50", + "description": " Eth13/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth13/3", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet51": { + "index": "13", + "lanes": "51", + "description": " Eth13/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth13/4", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet52": { + "index": "14", + "lanes": "52", + "description": "Eth14/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth14/1", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet53": { + "index": "14", + "lanes": "53", + "description": " Eth14/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth14/2", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet54": { + "index": "14", + "lanes": "54,55", + "description": " Eth14/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth14/3", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet99": { + "index": "25", + "lanes": "99", + "description": " Eth25/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth25/4", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet56": { + "index": "15", + "lanes": "56,57", + "description": "Eth15/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth15/1", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet113": { + "index": "29", + "lanes": "113", + "description": " Eth29/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth29/2", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet76": { + "index": "20", + "lanes": "76,77", + "description": "Eth20/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth20/1", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet74": { + "index": "19", + "lanes": "74,75", + "description": " Eth19/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth19/3", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet39": { + "index": "10", + "lanes": "39", + "description": " Eth10/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth10/4", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet72": { + "index": "19", + "lanes": "72", + "description": "Eth19/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth19/1", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet73": { + "index": "19", + "lanes": "73", + "description": " Eth19/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth19/2", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet70": { + "index": "18", + "lanes": "70", + "description": " Eth18/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth18/3", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet71": { + "index": "18", + "lanes": "71", + "description": " Eth18/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth18/4", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet32": { + "index": "9", + "lanes": "32", + "description": "Eth9/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth9/1", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet33": { + "index": "9", + "lanes": "33", + "description": " Eth9/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth9/2", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet16": { + "index": "5", + "lanes": "16,17", + "description": "Eth5/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth5/1", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet111": { + "index": "28", + "lanes": "111", + "description": " Eth28/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth28/4", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet10": { + "index": "3", + "lanes": "10", + "description": " Eth3/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth3/3", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet11": { + "index": "3", + "lanes": "11", + "description": " Eth3/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth3/4", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet12": { + "index": "4", + "lanes": "12", + "description": "Eth4/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth4/1", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet13": { + "index": "4", + "lanes": "13", + "description": " Eth4/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth4/2", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet58": { + "index": "15", + "lanes": "58", + "description": " Eth15/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth15/3", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet19": { + "index": "5", + "lanes": "19", + "description": " Eth5/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth5/4", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet59": { + "index": "15", + "lanes": "59", + "description": " Eth15/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth15/4", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet38": { + "index": "10", + "lanes": "38", + "description": " Eth10/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth10/3", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet78": { + "index": "20", + "lanes": "78", + "description": " Eth20/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth20/3", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet68": { + "index": "18", + "lanes": "68", + "description": "Eth18/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth18/1", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet14": { + "index": "4", + "lanes": "14,15", + "description": " Eth4/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth4/3", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet89": { + "index": "23", + "lanes": "89", + "description": " Eth23/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth23/2", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet88": { + "index": "23", + "lanes": "88", + "description": "Eth23/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth23/1", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet118": { + "index": "30", + "lanes": "118", + "description": " Eth30/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth30/3", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet119": { + "index": "30", + "lanes": "119", + "description": " Eth30/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth30/4", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet116": { + "index": "30", + "lanes": "116,117", + "description": "Eth30/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth30/1", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet114": { + "index": "29", + "lanes": "114,115", + "description": " Eth29/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth29/3", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet80": { + "index": "21", + "lanes": "80,81,82,83", + "description": "Eth21/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth21/1", + "pfc_asym": "off", + "speed": "100G" + }, + "Ethernet112": { + "index": "29", + "lanes": "112", + "description": "Eth29/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth29/1", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet86": { + "index": "22", + "lanes": "86,87", + "description": " Eth22/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth22/3", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet110": { + "index": "28", + "lanes": "110", + "description": " Eth28/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth28/3", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet84": { + "index": "22", + "lanes": "84,85", + "description": "Eth22/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth22/1", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet31": { + "index": "8", + "lanes": "31", + "description": " Eth8/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth8/4", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet49": { + "index": "13", + "lanes": "49", + "description": " Eth13/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth13/2", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet48": { + "index": "13", + "lanes": "48", + "description": "Eth13/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth13/1", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet46": { + "index": "12", + "lanes": "46,47", + "description": " Eth12/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth12/3", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet30": { + "index": "8", + "lanes": "30", + "description": " Eth8/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth8/3", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet29": { + "index": "8", + "lanes": "29", + "description": " Eth8/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth8/2", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet40": { + "index": "11", + "lanes": "40,41,42,43", + "description": "Eth11/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth11/1", + "pfc_asym": "off", + "speed": "100G" + }, + "Ethernet120": { + "index": "31", + "lanes": "120,121,122,123", + "description": "Eth31/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth31/1", + "pfc_asym": "off", + "speed": "100G" + }, + "Ethernet28": { + "index": "8", + "lanes": "28", + "description": "Eth8/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth8/1", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet66": { + "index": "17", + "lanes": "66,67", + "description": " Eth17/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth17/3", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet60": { + "index": "16", + "lanes": "60,61,62,63", + "description": "Eth16/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth16/1", + "pfc_asym": "off", + "speed": "100G" + }, + "Ethernet64": { + "index": "17", + "lanes": "64,65", + "description": "Eth17/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth17/1", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet44": { + "index": "12", + "lanes": "44,45", + "description": "Eth12/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth12/1", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet20": { + "index": "6", + "lanes": "20,21,22,23", + "description": "Eth6/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth6/1", + "pfc_asym": "off", + "speed": "100G" + }, + "Ethernet79": { + "index": "20", + "lanes": "79", + "description": " Eth20/4", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth20/4", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet69": { + "index": "18", + "lanes": "69", + "description": " Eth18/2", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth18/2", + "pfc_asym": "off", + "speed": "25G" + }, + "Ethernet24": { + "index": "7", + "lanes": "24,25", + "description": "Eth7/1", + "admin_status": "up", + "mtu": "9100", + "alias": "Eth7/1", + "pfc_asym": "off", + "speed": "50G" + }, + "Ethernet26": { + "index": "7", + "lanes": "26,27", + "description": " Eth7/3", + "admin_status": "up", + "mtu": "9100", + "alias": " Eth7/3", + "pfc_asym": "off", + "speed": "50G" + } +} diff --git a/src/sonic-config-engine/tests/sample_platform.json b/src/sonic-config-engine/tests/sample_platform.json new file mode 100644 index 000000000000..af463fa0614f --- /dev/null +++ b/src/sonic-config-engine/tests/sample_platform.json @@ -0,0 +1,226 @@ +{ + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "0,1,2,3", + "alias_at_lanes": "Eth1/1, Eth1/2, Eth1/3, Eth1/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet4": { + "index": "2,2,2,2", + "lanes": "4,5,6,7", + "alias_at_lanes": "Eth2/1, Eth2/2, Eth2/3, Eth2/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G]", + "default_brkout_mode": "2x50G" + }, + "Ethernet8": { + "index": "3,3,3,3", + "lanes": "8,9,10,11", + "alias_at_lanes": "Eth3/1, Eth3/2, Eth3/3, Eth3/4", + "breakout_modes": "1x100G[40G],2x50G,2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet12": { + "index": "4,4,4,4", + "lanes": "12,13,14,15", + "alias_at_lanes": "Eth4/1, Eth4/2, Eth4/3, Eth4/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet16": { + "index": "5,5,5,5", + "lanes": "16,17,18,19", + "alias_at_lanes": "Eth5/1, Eth5/2, Eth5/3, Eth5/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet20": { + "index": "6,6,6,6", + "lanes": "20,21,22,23", + "alias_at_lanes": "Eth6/1, Eth6/2, Eth6/3, Eth6/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet24": { + "index": "7,7,7,7", + "lanes": "24,25,26,27", + "alias_at_lanes": "Eth7/1, Eth7/2, Eth7/3, Eth7/4", + "breakout_modes": "1x100G[40G],4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "2x50G" + }, + "Ethernet28": { + "index": "8,8,8,8", + "lanes": "28,29,30,31", + "alias_at_lanes": "Eth8/1, Eth8/2, Eth8/3, Eth8/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet32": { + "index": "9,9,9,9", + "lanes": "32,33,34,35", + "alias_at_lanes": "Eth9/1, Eth9/2, Eth9/3, Eth9/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet36": { + "index": "10,10,10,10", + "lanes": "36,37,38,39", + "alias_at_lanes": "Eth10/1, Eth10/2, Eth10/3, Eth10/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet40": { + "index": "11,11,11,11", + "lanes": "40,41,42,43", + "alias_at_lanes": "Eth11/1, Eth11/2, Eth11/3, Eth11/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet44": { + "index": "12,12,12,12", + "lanes": "44,45,46,47", + "alias_at_lanes": "Eth12/1, Eth12/2, Eth12/3, Eth12/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "2x50G" + }, + "Ethernet48": { + "index": "13,13,13,13", + "lanes": "48,49,50,51", + "alias_at_lanes": "Eth13/1, Eth13/2, Eth13/3, Eth13/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet52": { + "index": "14,14,14,14", + "lanes": "52,53,54,55", + "alias_at_lanes": "Eth14/1, Eth14/2, Eth14/3, Eth14/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet56": { + "index": "15,15,15,15", + "lanes": "56,57,58,59", + "alias_at_lanes": "Eth15/1, Eth15/2, Eth15/3, Eth15/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet60": { + "index": "16,16,16,16", + "lanes": "60,61,62,63", + "alias_at_lanes": "Eth16/1, Eth16/2, Eth16/3, Eth16/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet64": { + "index": "17,17,17,17", + "lanes": "64,65,66,67", + "alias_at_lanes": "Eth17/1, Eth17/2, Eth17/3, Eth17/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "2x50G" + }, + "Ethernet68": { + "index": "18,18,18,18", + "lanes": "68,69,70,71", + "alias_at_lanes": "Eth18/1, Eth18/2, Eth18/3, Eth18/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet72": { + "index": "19,19,19,19", + "lanes": "72,73,74,75", + "alias_at_lanes": "Eth19/1, Eth19/2, Eth19/3, Eth19/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet76": { + "index": "20,20,20,20", + "lanes": "76,77,78,79", + "alias_at_lanes": "Eth20/1, Eth20/2, Eth20/3, Eth20/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet80": { + "index": "21,21,21,21", + "lanes": "80,81,82,83", + "alias_at_lanes": "Eth21/1, Eth21/2, Eth21/3, Eth21/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet84": { + "index": "22,22,22,22", + "lanes": "84,85,86,87", + "alias_at_lanes": "Eth22/1, Eth22/2, Eth22/3, Eth22/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "2x50G" + }, + "Ethernet88": { + "index": "23,23,23,23", + "lanes": "88,89,90,91", + "alias_at_lanes": "Eth23/1, Eth23/2, Eth23/3, Eth23/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet92": { + "index": "24,24,24,24", + "lanes": "92,93,94,95", + "alias_at_lanes": "Eth24/1, Eth24/2, Eth24/3, Eth24/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet96": { + "index": "25,25,25,25", + "lanes": "96,97,98,99", + "alias_at_lanes": "Eth25/1, Eth25/2, Eth25/3, Eth25/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet100": { + "index": "26,26,26,26", + "lanes": "100,101,102,103", + "alias_at_lanes": "Eth26/1, Eth26/2, Eth26/3, Eth26/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet104": { + "index": "27,27,27,27", + "lanes": "104,105,106,107", + "alias_at_lanes": "Eth27/1, Eth27/2, Eth27/3, Eth27/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "2x50G" + }, + "Ethernet108": { + "index": "28,28,28,28", + "lanes": "108,109,110,111", + "alias_at_lanes": "Eth28/1, Eth28/2, Eth28/3, Eth28/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "4x25G[10G]" + }, + "Ethernet112": { + "index": "29,29,29,29", + "lanes": "112,113,114,115", + "alias_at_lanes": "Eth29/1, Eth29/2, Eth29/3, Eth29/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "2x25G(2)+1x50G(2)" + }, + "Ethernet116": { + "index": "30,30,30,30", + "lanes": "116,117,118,119", + "alias_at_lanes": "Eth30/1, Eth30/2, Eth30/3, Eth30/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "1x50G(2)+2x25G(2)" + }, + "Ethernet120": { + "index": "31,31,31,31", + "lanes": "120,121,122,123", + "alias_at_lanes": "Eth31/1, Eth31/2, Eth31/3, Eth31/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "1x100G[40G]" + }, + "Ethernet124": { + "index": "32,32,32,32", + "lanes": "124,125,126,127", + "alias_at_lanes": "Eth32/1, Eth32/2, Eth32/3, Eth32/4", + "breakout_modes": "1x100G[40G],2x50G,4x25G[10G],2x25G(2)+1x50G(2),1x50G(2)+2x25G(2)", + "default_brkout_mode": "2x50G" + } +} diff --git a/src/sonic-config-engine/tests/test_cfggen_platformJson.py b/src/sonic-config-engine/tests/test_cfggen_platformJson.py new file mode 100644 index 000000000000..31e586934c03 --- /dev/null +++ b/src/sonic-config-engine/tests/test_cfggen_platformJson.py @@ -0,0 +1,75 @@ +from unittest import TestCase +import subprocess +import os +import json +import ast + +# Global Variable +PLATFORM_CAP = "platform_output.json" + +class TestCfgGenPlatformJson(TestCase): + + def setUp(self): + self.test_dir = os.path.dirname(os.path.realpath(__file__)) + self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen') + self.sample_graph_simple = os.path.join(self.test_dir, 'simple-sample-graph.xml') + self.platform_json = os.path.join(self.test_dir, 'sample_platform.json') + + + def run_script(self, argument, check_stderr=False): + print '\n Running sonic-cfggen ' + argument + if check_stderr: + output = subprocess.check_output(self.script_file + ' ' + argument, stderr=subprocess.STDOUT, shell=True) + else: + output = subprocess.check_output(self.script_file + ' ' + argument, shell=True) + + linecount = output.strip().count('\n') + if linecount <= 0: + print ' Output: ' + output.strip() + else: + print ' Output: ({0} lines, {1} bytes)'.format(linecount + 1, len(output)) + return output + + def test_dummy_run(self): + argument = '' + output = self.run_script(argument) + self.assertEqual(output, '') + + def test_print_data(self): + argument = '-m "' + self.sample_graph_simple + '" --print-data' + output = self.run_script(argument) + self.assertTrue(len(output.strip()) > 0) + + # Check whether all interfaces present or not as per platform.json + def test_platform_json_interfaces_keys(self): + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -v "PORT.keys()"' + output = self.run_script(argument) + expected = "['Ethernet8', 'Ethernet9', 'Ethernet36', 'Ethernet98', 'Ethernet0', 'Ethernet6', 'Ethernet4', 'Ethernet109', 'Ethernet108', 'Ethernet18', 'Ethernet100', 'Ethernet34', 'Ethernet104', 'Ethernet106', 'Ethernet94', 'Ethernet126', 'Ethernet96', 'Ethernet124', 'Ethernet90', 'Ethernet91', 'Ethernet92', 'Ethernet93', 'Ethernet50', 'Ethernet51', 'Ethernet52', 'Ethernet53', 'Ethernet54', 'Ethernet99', 'Ethernet56', 'Ethernet113', 'Ethernet76', 'Ethernet74', 'Ethernet39', 'Ethernet72', 'Ethernet73', 'Ethernet70', 'Ethernet71', 'Ethernet32', 'Ethernet33', 'Ethernet16', 'Ethernet111', 'Ethernet10', 'Ethernet11', 'Ethernet12', 'Ethernet13', 'Ethernet58', 'Ethernet19', 'Ethernet59', 'Ethernet38', 'Ethernet78', 'Ethernet68', 'Ethernet14', 'Ethernet89', 'Ethernet88', 'Ethernet118', 'Ethernet119', 'Ethernet116', 'Ethernet114', 'Ethernet80', 'Ethernet112', 'Ethernet86', 'Ethernet110', 'Ethernet84', 'Ethernet31', 'Ethernet49', 'Ethernet48', 'Ethernet46', 'Ethernet30', 'Ethernet29', 'Ethernet40', 'Ethernet120', 'Ethernet28', 'Ethernet66', 'Ethernet60', 'Ethernet64', 'Ethernet44', 'Ethernet20', 'Ethernet79', 'Ethernet69', 'Ethernet24', 'Ethernet26']" + self.assertEqual(output.strip(), expected) + + # Check specific Interface with it's proper configuration as per platform.json + def test_platform_json_specific_ethernet_interfaces(self): + + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -v "PORT[\'Ethernet8\']"' + output = self.run_script(argument) + expected = "{'index': '3', 'lanes': '8', 'description': 'Eth3/1', 'admin_status': 'up', 'mtu': '9100', 'alias': 'Eth3/1', 'pfc_asym': 'off', 'speed': '25G'}" + self.assertEqual(output.strip(), expected) + + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -v "PORT[\'Ethernet112\']"' + output = self.run_script(argument) + expected = "{'index': '29', 'lanes': '112', 'description': 'Eth29/1', 'admin_status': 'up', 'mtu': '9100', 'alias': 'Eth29/1', 'pfc_asym': 'off', 'speed': '25G'}" + self.assertEqual(output.strip(), expected) + + # Check all Interface with it's proper configuration as per platform.json + def test_platform_json_all_ethernet_interfaces(self): + argument = '-m "' + self.sample_graph_simple + '" -p "' + self.platform_json + '" -v "PORT"' + output = self.run_script(argument) + + sample_file = os.path.join(self.test_dir, 'sample_output', "platform_output.json") + fh = open(sample_file, 'rb') + fh_data = json.load(fh) + fh.close() + + output_dict = ast.literal_eval(output.strip()) + expected = ast.literal_eval(json.dumps(fh_data)) + self.assertDictEqual(output_dict, expected) diff --git a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py index a0a5bff0a297..c8dc96db6018 100644 --- a/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py +++ b/src/sonic-daemon-base/sonic_daemon_base/daemon_base.py @@ -28,6 +28,7 @@ # Port config information PORT_CONFIG = 'port_config.ini' PORTMAP = 'portmap.ini' +PLATFORM_CAP = 'platform.json' EEPROM_MODULE_NAME = 'eeprom' EEPROM_CLASS_NAME = 'board' @@ -151,13 +152,17 @@ def get_path_to_port_config_file(self): # Get platform and hwsku path (platform_path, hwsku_path) = self.get_path_to_platform_and_hwsku() - # First check for the presence of the new 'port_config.ini' file - port_config_file_path = "/".join([hwsku_path, PORT_CONFIG]) + # First check for the presence of the new 'platform.json' file + port_config_file_path = "/".join([hwsku_path, PLATFORM_CAP]) if not os.path.isfile(port_config_file_path): - # port_config.ini doesn't exist. Try loading the legacy 'portmap.ini' file - port_config_file_path = "/".join([hwsku_path, PORTMAP]) + + # platform.json doesn't exist. Try loading the legacy 'port_config.ini' file + port_config_file_path = "/".join([hwsku_path, PORT_CONFIG]) if not os.path.isfile(port_config_file_path): - raise IOError("Failed to detect port config file: %s" % (port_config_file_path)) + # port_config.ini doesn't exist. Try loading the legacy 'portmap.ini' file + port_config_file_path = "/".join([hwsku_path, PORTMAP]) + if not os.path.isfile(port_config_file_path): + raise IOError("Failed to detect port config file: %s" % (port_config_file_path)) return port_config_file_path