From c33682d9ae4e128197bdca1ff31468fd4cc76896 Mon Sep 17 00:00:00 2001 From: Dmytro Shevchuk Date: Tue, 11 May 2021 11:00:28 -0700 Subject: [PATCH] Add platform/hwsku support in deploy_mg flow --- ansible/library/port_alias.py | 95 +++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/ansible/library/port_alias.py b/ansible/library/port_alias.py index a3c094782b6..83ef950997f 100755 --- a/ansible/library/port_alias.py +++ b/ansible/library/port_alias.py @@ -4,9 +4,12 @@ import os import traceback import subprocess +import json +import ast from operator import itemgetter from itertools import groupby from collections import defaultdict +from collections import OrderedDict try: from sonic_py_common import multi_asic @@ -50,6 +53,8 @@ PORTMAP_FILE = 'port_config.ini' ALLOWED_HEADER = ['name', 'lanes', 'alias', 'index', 'asic_port_name', 'role', 'speed'] +PLATFORM_FILE = 'platform.json' +HWSKU_FILE = 'hwsku.json' MACHINE_CONF = '/host/machine.conf' ONIE_PLATFORM_KEY = 'onie_platform' ABOOT_PLATFORM_KEY = 'aboot_platform' @@ -89,6 +94,88 @@ def get_portconfig_path(self, asic_id=None): return portconfig return None + def get_platform_path(self): + platform = self.get_platform_type() + if platform is None: + return None + platform_path = os.path.join(FILE_PATH, platform, PLATFORM_FILE) + if os.path.exists(platform_path): + return platform_path + return None + + def get_hwsku_path(self): + platform = self.get_platform_type() + if platform is None: + return None + hwsku_path = os.path.join(FILE_PATH, platform, self.hwsku, HWSKU_FILE) + if os.path.exists(hwsku_path): + return hwsku_path + return None + + def get_portmap_from_platform_hwsku(self, platform_file, hwsku_file, aliases, portmap, aliasmap, portspeed): + decoder = json.JSONDecoder(object_pairs_hook=OrderedDict) + brkout_pattern = r'(\d{1,3})x(\d{1,3}G)(\[\d{1,3}G\])?(\((\d{1,3})\))?' + with open(platform_file) as f: + data = json.load(f, object_pairs_hook=OrderedDict) + platform_dict = decoder.decode(json.dumps(data)) + with open(hwsku_file) as f: + data = json.load(f) + hwsku_dict = ast.literal_eval(json.dumps(data)) + for interface in platform_dict["interfaces"]: + if interface not in hwsku_dict["interfaces"]: + raise Exception("interface {} not in hwsku dict".format(interface)) + lanes = platform_dict["interfaces"][interface]['lanes'] + breakout_mode = hwsku_dict["interfaces"][interface]["default_brkout_mode"] + alias_list = platform_dict["interfaces"][interface]['breakout_modes'][breakout_mode] + + # Asymmetric breakout mode + if re.search("\+", breakout_mode) is not None: + breakout_parts = breakout_mode.split("+") + match_list = [re.match(brkout_pattern, i).groups() for i in breakout_parts] + # Symmetric breakout mode + else: + match_list = [re.match(brkout_pattern, breakout_mode).groups()] + + offset = 0 + parent_intf_id = int(re.search("Ethernet(\d+)", interface).group(1)) + for k in match_list: + if k is not None: + num_lane_used, speed, assigned_lane = k[0], k[1], 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_position = 0 + int(offset)//int(num_lane_used) + + step = int(assigned_lane)//int(num_lane_used) + for i in range(0,int(assigned_lane), step): + + intf_name = "Ethernet" + str(parent_intf_id) + alias = alias_list[alias_position] + + aliases.append(str(alias)) + portmap[intf_name] = str(alias) + aliasmap[str(alias)] = intf_name + if speed: + speed_pat = re.search("^((\d+)G|\d+)$", speed.upper()) + if speed_pat is None: + raise Exception('{} speed is not Supported...'.format(speed)) + speed_G, speed_orig = speed_pat.group(2), speed_pat.group(1) + if speed_G: + portspeed[alias] = str(int(speed_G)*1000) + else: + portspeed[alias] = speed_orig + else: + raise Exception('Regex return for speed is None...') + + parent_intf_id += step + alias_position += 1 + + parent_intf_id = 0 + offset = int(assigned_lane) + int(offset) + def get_portmap(self, asic_id=None, include_internal=False): aliases = [] portmap = {} @@ -99,6 +186,14 @@ def get_portmap(self, asic_id=None, include_internal=False): # All asic names asic_if_names = [] + # if platform.json and hwsku.json exist, than get portmap from hwsku + platform_file = self.get_platform_path() + hwsku_file = self.get_hwsku_path() + if platform_file and hwsku_file: + self.get_portmap_from_platform_hwsku(platform_file, hwsku_file, aliases, portmap, aliasmap, portspeed) + return (aliases, portmap, aliasmap, portspeed) + + # platform.json or hwsku.json does not exist so get portmap from port_config.ini filename = self.get_portconfig_path(asic_id) if filename is None: raise Exception("Something wrong when trying to find the portmap file, either the hwsku is not available or file location is not correct")