Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion ansible/config_sonic_basedon_testbed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
card_type: "{{ card_type | default('fixed') }}"
hostname: "{{ inventory_hostname | default('') }}"
switchids: "{{ switchids | default([]) }}"
slotid: "{{ slot_num | default(None) }}"
delegate_to: localhost
when: deploy is not defined or deploy|bool == false

Expand All @@ -101,19 +102,44 @@
num_fabric_asic: "{{ num_fabric_asics | default(0) }}"
asics_host_basepfx: "{{ asics_host_ip | default(None) }}"
asics_host_basepfx6: "{{ asics_host_ipv6 | default(None) }}"
delegate_to: localhost

- name: set all VoQ system ports information
set_fact:
all_sysports: "{{ all_sysports | default( [] ) + hostvars[item]['sysports'] }}"
when: hostvars[item]['sysports'] is defined
loop: "{{ ansible_play_batch }}"

- name: set all VoQ information for iBGP
- name: set all v4 Inband Ip information for iBGP chassis voq
set_fact:
all_inbands: "{{ all_inbands | default( {} ) | combine( { item : hostvars[item]['voq_inband_ip']}) }}"
when: hostvars[item]['voq_inband_ip'] is defined
loop: "{{ ansible_play_batch }}"

- name: set all v6 Inband Ip information for iBGP chassis voq
set_fact:
all_inbands_ipv6: "{{ all_inbands_ipv6 | default( {} ) | combine( { item : hostvars[item]['voq_inband_ipv6']}) }}"
when: hostvars[item]['voq_inband_ipv6'] is defined
loop: "{{ ansible_play_batch }}"

- name: set all Loopback4096 information for iBGP chassis
set_fact:
all_loopback4096: "{{ all_loopback4096 | default( {} ) | combine( { item : hostvars[item]['loopback4096_ip']}) }}"
when: hostvars[item]['loopback4096_ip'] is defined
loop: "{{ ansible_play_batch }}"

- name: set all Loopback4096 ipv6 information for iBGP chassis
set_fact:
all_loopback4096_ipv6: "{{ all_loopback4096_ipv6 | default( {} ) | combine( { item : hostvars[item]['loopback4096_ipv6']}) }}"
when: hostvars[item]['loopback4096_ipv6'] is defined
loop: "{{ ansible_play_batch }}"

- name: set all slot information for chassis
set_fact:
all_slots: "{{ all_slots | default( {} ) | combine( { item : hostvars[item]['slot_num']}) }}"
when: hostvars[item]['slot_num'] is defined
loop: "{{ ansible_play_batch }}"

- name: find all enabled host_interfaces
set_fact:
host_if_indexes: "{{ vm_topo_config['host_interfaces_by_dut'][dut_index|int] | difference(vm_topo_config['disabled_host_interfaces_by_dut'][dut_index|int]) }}"
Expand Down
38 changes: 38 additions & 0 deletions ansible/lab
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ all:
sonic_a7260:
sonic_multi_asic:
sonic_multi_asic_2:
sonic_msft_sup:
sonic_msft_lc_100G:
fanout:
hosts:
str-7260-10:
Expand Down Expand Up @@ -148,3 +150,39 @@ sonic_multi_asic_2:
vlab-08:
ansible_host: 10.250.0.112
ansible_hostv6: fec0::ffff:afa:c

sonic_msft_sup:
vars:
HwSku: msft-RP-O
slot_num: slot0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some dependencies on slot_num that I believe are expecting this host variable to be int.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have fixed in latest commit to strip "slot" from the string.

card_type: supervisor
hosts:
lab-msft-sup-1:
ansible_host: 2.2.2.2
hwsku: msft-RP-O
num_asics: 2

sonic_msft_lc_100G:
vars:
switch_type: chassis-packet
num_asics: 2
frontend_asics: [0,1]
hosts:
lab-msft-lc0-1:
hwsku: msft-LC-48H-O
slot_num: slot1
loopback4096_ip: [3.3.3.3/32,3.3.3.4/32]
loopback4096_ipv6: [2603:10e2:400::3/128,2603:10e2:400::4/128]
ansible_host: 2.2.2.3
lab-msft-lc1-1:
hwsku: msft-LC-48H-O
slot_num: slot2
loopback4096_ip: [3.3.3.5/32,3.3.3.6/32]
loopback4096_ipv6: [2603:10e2:400::5/128,2603:10e2:400::6/128]
ansible_host: 2.2.2.4
lab-msft-lc2-1:
hwsku: msft-LC-48H-O
slot_num: slot3
loopback4096_ip: [3.3.3.7/32,3.3.3.8/32]
loopback4096_ipv6: [2603:10e2:400::7/128,2603:10e2:400::8/128]
ansible_host: 2.2.2.5
21 changes: 14 additions & 7 deletions ansible/library/port_alias.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,22 @@ def get_platform_type(self):
return value
return None

def get_portconfig_path(self, asic_id=None):
def get_portconfig_path(self, slotid=None, asic_id=None):
platform = self.get_platform_type()
if platform is None:
return None
if asic_id is None:
if asic_id is None or asic_id == '':
portconfig = os.path.join(FILE_PATH, platform, self.hwsku, PORTMAP_FILE)
else:
elif slotid is None or slotid == '':
portconfig = os.path.join(FILE_PATH, platform, self.hwsku, str(asic_id), PORTMAP_FILE)
else:
portconfig = os.path.join(FILE_PATH, platform, self.hwsku, str(slotid), str(asic_id), PORTMAP_FILE)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the port_config.ini file different for a card with the same hwsku being in a different slot?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, Backend connectivity can be different based on slot the card is inserted.

if os.path.exists(portconfig):
return portconfig
return None

def get_portmap(self, asic_id=None, include_internal=False,
hostname=None, switchid=None):
hostname=None, switchid=None, slotid=None):
aliases = []
portmap = {}
aliasmap = {}
Expand All @@ -107,7 +109,7 @@ def get_portmap(self, asic_id=None, include_internal=False,
# default to Asic0 as minigraph.py parsing code has that assumption.
asic_name = "Asic0" if asic_id is None else "asic" + str(asic_id)

filename = self.get_portconfig_path(asic_id)
filename = self.get_portconfig_path(slotid, 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")
with open(filename) as f:
Expand Down Expand Up @@ -209,7 +211,8 @@ def main():
include_internal=dict(required=False, type='bool', default=False),
card_type=dict(type='str', required=False),
hostname=dict(type='str', required=False),
switchids=dict(type='list', required=False)
switchids=dict(type='list', required=False),
slotid=dict(type='str', required=False)
),
supports_check_mode=True
)
Expand All @@ -236,8 +239,12 @@ def main():
return
allmap = SonicPortAliasMap(m_args['hwsku'])
switchids = None
slotid = None
if 'switchids' in m_args and m_args['switchids'] != None and len(m_args['switchids']):
switchids = m_args['switchids']

if 'slotid' in m_args and m_args['slotid'] != None:
slotid = m_args['slotid']
# When this script is invoked on sonic-mgmt docker, num_asic
# parameter is passed.
if m_args['num_asic'] is not None:
Expand Down Expand Up @@ -269,7 +276,7 @@ def main():
if num_asic == 1:
asic_id = None
(aliases_asic, portmap_asic, aliasmap_asic, portspeed_asic, front_panel_asic, asicifnames_asic,
sysport_asic) = allmap.get_portmap(asic_id, include_internal, hostname, switchid)
sysport_asic) = allmap.get_portmap(asic_id, include_internal, hostname, switchid, slotid)
if aliases_asic is not None:
aliases.extend(aliases_asic)
if portmap_asic is not None:
Expand Down
157 changes: 84 additions & 73 deletions ansible/library/topo_facts.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ def __init__(self):
self.asic_topo_config = {}

def parse_topo_defintion(self, topo_definition, po_map, dut_num, neigh_type='VMs'):
dut_asn = topo_definition['configuration_properties']['common']['dut_asn']
vmconfig = dict()
for vm in topo_definition['topology'][neigh_type]:
vmconfig[vm] = dict()
Expand All @@ -106,77 +105,93 @@ def parse_topo_defintion(self, topo_definition, po_map, dut_num, neigh_type='VMs
for asic_intf in topo_definition['topology'][neigh_type][vm]['asic_intfs']:
vmconfig[vm]['asic_intfs'][dut_index].append(asic_intf)


# physical interface
for intf in topo_definition['configuration'][vm]['interfaces']:
if (neigh_type == 'VMs' and 'Ethernet' in intf) or \
(neigh_type == 'NEIGH_ASIC' and re.match("Eth(\d+)-", intf)):
dut_index = 0
if 'dut_index' in topo_definition['configuration'][vm]['interfaces'][intf]:
dut_index = topo_definition['configuration'][vm]['interfaces'][intf]['dut_index']
if 'lacp' in topo_definition['configuration'][vm]['interfaces'][intf]:
po_map[topo_definition['configuration'][vm]['interfaces'][intf]['lacp']] = dut_index

vmconfig[vm]['intfs'][dut_index].append(intf)
if 'configuration' in topo_definition:
if 'interfaces' in topo_definition['configuration'][vm]:
for intf in topo_definition['configuration'][vm]['interfaces']:
dut_index = 0
if neigh_type == 'NEIGH_ASIC' and re.match("Eth(\d+)-", intf):
vmconfig[vm]['intfs'][dut_index].append(intf)
elif 'Ethernet' in intf:
if 'dut_index' in topo_definition['configuration'][vm]['interfaces'][intf]:
dut_index = topo_definition['configuration'][vm]['interfaces'][intf]['dut_index']
if 'lacp' in topo_definition['configuration'][vm]['interfaces'][intf]:
po_map[topo_definition['configuration'][vm]['interfaces'][intf]['lacp']] = dut_index
vmconfig[vm]['intfs'][dut_index].append(intf)

# ip interface
vmconfig[vm]['ip_intf'] = [None] * dut_num
vmconfig[vm]['peer_ipv4'] = [None] * dut_num
vmconfig[vm]['ipv4mask'] = [None] * dut_num
vmconfig[vm]['peer_ipv6'] = [None] * dut_num
vmconfig[vm]['ipv6mask'] = [None] * dut_num


for intf in topo_definition['configuration'][vm]['interfaces']:
dut_index = 0
if (neigh_type == 'VMs' and 'Ethernet' in intf) or \
(neigh_type == 'NEIGH_ASIC' and re.match("Eth(\d+)-", intf)):
if 'dut_index' in topo_definition['configuration'][vm]['interfaces'][intf]:
dut_index = topo_definition['configuration'][vm]['interfaces'][intf]['dut_index']
elif 'Port-Channel' in intf:
m = re.search("(\d+)", intf)
dut_index = po_map[int(m.group(1))]

if 'ipv4' in topo_definition['configuration'][vm]['interfaces'][intf] and ('loopback' not in intf.lower()):
(peer_ipv4, ipv4_mask) = topo_definition['configuration'][vm]['interfaces'][intf]['ipv4'].split('/')
vmconfig[vm]['peer_ipv4'][dut_index] = peer_ipv4
vmconfig[vm]['ipv4mask'][dut_index] = ipv4_mask
vmconfig[vm]['ip_intf'][dut_index] = intf
if 'ipv6' in topo_definition['configuration'][vm]['interfaces'][intf] and ('loopback' not in intf.lower()):
(ipv6_addr, ipv6_mask) = topo_definition['configuration'][vm]['interfaces'][intf]['ipv6'].split('/')
vmconfig[vm]['peer_ipv6'][dut_index] = ipv6_addr.upper()
vmconfig[vm]['ipv6mask'][dut_index] = ipv6_mask
vmconfig[vm]['ip_intf'][dut_index] = intf

# bgp
vmconfig[vm]['bgp_ipv4'] = [None] * dut_num
vmconfig[vm]['bgp_ipv6'] = [None] * dut_num
vmconfig[vm]['bgp_asn'] = topo_definition['configuration'][vm]['bgp']['asn']
for ipstr in topo_definition['configuration'][vm]['bgp']['peers'][dut_asn]:
if sys.version_info < (3, 0):
ip = ipaddress.ip_address(ipstr.decode('utf8'))
else:
ip = ipaddress.ip_address(ipstr)
for dut_index in range(0, dut_num):
if ip.version == 4:
# Each VM might not be connected to all the DUT's, so check if this VM is a peer to DUT at dut_index
if vmconfig[vm]['peer_ipv4'][dut_index]:
ipsubnet_str = vmconfig[vm]['peer_ipv4'][dut_index]+'/'+vmconfig[vm]['ipv4mask'][dut_index]
if sys.version_info < (3, 0):
ipsubnet = ipaddress.ip_interface(ipsubnet_str.decode('utf8'))
else:
ipsubnet = ipaddress.ip_interface(ipsubnet_str)
if ip in ipsubnet.network:
vmconfig[vm]['bgp_asn'] = None


if 'configuration' in topo_definition:
if 'interfaces' in topo_definition['configuration'][vm]:
for intf in topo_definition['configuration'][vm]['interfaces']:
dut_index = 0
if neigh_type == 'NEIGH_ASIC':
pass
elif 'Ethernet' in intf:
if 'dut_index' in topo_definition['configuration'][vm]['interfaces'][intf]:
dut_index = topo_definition['configuration'][vm]['interfaces'][intf]['dut_index']
elif 'Port-Channel' in intf:
m = re.search("(\d+)", intf)
dut_index = po_map[int(m.group(1))]

if isinstance(topo_definition['configuration'][vm]['interfaces'],dict) and 'ipv4' in topo_definition['configuration'][vm]['interfaces'][intf] and ('loopback' not in intf.lower()):
(peer_ipv4, ipv4_mask) = topo_definition['configuration'][vm]['interfaces'][intf]['ipv4'].split('/')
vmconfig[vm]['peer_ipv4'][dut_index] = peer_ipv4
vmconfig[vm]['ipv4mask'][dut_index] = ipv4_mask
vmconfig[vm]['ip_intf'][dut_index] = intf
if isinstance(topo_definition['configuration'][vm]['interfaces'],dict) and 'ipv6' in topo_definition['configuration'][vm]['interfaces'][intf] and ('loopback' not in intf.lower()):
(ipv6_addr, ipv6_mask) = topo_definition['configuration'][vm]['interfaces'][intf]['ipv6'].split('/')
vmconfig[vm]['peer_ipv6'][dut_index] = ipv6_addr.upper()
vmconfig[vm]['ipv6mask'][dut_index] = ipv6_mask
vmconfig[vm]['ip_intf'][dut_index] = intf
# bgp
vmconfig[vm]['bgp_asn'] = topo_definition['configuration'][vm]['bgp']['asn']
dut_asn = topo_definition['configuration_properties']['common']['dut_asn']
for ipstr in topo_definition['configuration'][vm]['bgp']['peers'][dut_asn]:
ip_mask = None
if '/' in ipstr:
(ipstr, ip_mask) = ipstr.split('/')
if sys.version_info < (3, 0):
ip = ipaddress.ip_address(ipstr.decode('utf8'))
else:
ip = ipaddress.ip_address(ipstr)
for dut_index in range(0, dut_num):
if ip.version == 4:
# Each VM might not be connected to all the DUT's, so check if this VM is a peer to DUT at dut_index
if vmconfig[vm]['peer_ipv4'][dut_index]:
ipsubnet_str = vmconfig[vm]['peer_ipv4'][dut_index]+'/'+vmconfig[vm]['ipv4mask'][dut_index]
if sys.version_info < (3, 0):
ipsubnet = ipaddress.ip_interface(ipsubnet_str.decode('utf8'))
else:
ipsubnet = ipaddress.ip_interface(ipsubnet_str)
if ip in ipsubnet.network:
vmconfig[vm]['bgp_ipv4'][dut_index] = ipstr.upper()
elif neigh_type == "NEIGH_ASIC":
vmconfig[vm]['bgp_ipv4'][dut_index] = ipstr.upper()
elif ip.version == 6:
# Each VM might not be connected to all the DUT's, so check if this VM is a peer to DUT at dut_index
if vmconfig[vm]['peer_ipv6'][dut_index]:
ipsubnet_str = vmconfig[vm]['peer_ipv6'][dut_index]+'/'+vmconfig[vm]['ipv6mask'][dut_index]
if sys.version_info < (3, 0):
ipsubnet = ipaddress.ip_interface(ipsubnet_str.decode('utf8'))
else:
ipsubnet = ipaddress.ip_interface(ipsubnet_str)
if ip in ipsubnet.network:
vmconfig[vm]['ipv4mask'][dut_index] = ip_mask if ip_mask else '32'
elif ip.version == 6:
# Each VM might not be connected to all the DUT's, so check if this VM is a peer to DUT at dut_index
if vmconfig[vm]['peer_ipv6'][dut_index]:
ipsubnet_str = vmconfig[vm]['peer_ipv6'][dut_index]+'/'+vmconfig[vm]['ipv6mask'][dut_index]
if sys.version_info < (3, 0):
ipsubnet = ipaddress.ip_interface(ipsubnet_str.decode('utf8'))
else:
ipsubnet = ipaddress.ip_interface(ipsubnet_str)
if ip in ipsubnet.network:
vmconfig[vm]['bgp_ipv6'][dut_index] = ipstr.upper()
elif neigh_type == "NEIGH_ASIC":
vmconfig[vm]['bgp_ipv6'][dut_index] = ipstr.upper()
vmconfig[vm]['ipv6mask'][dut_index] = ip_mask if ip_mask else '128'
return vmconfig

def get_topo_config(self, topo_name, hwsku):
Expand All @@ -201,10 +216,10 @@ def get_topo_config(self, topo_name, hwsku):
topo_definition = yaml.load(f)

if not os.path.isfile(asic_topo_filename):
asic_definition = {}
slot_definition = {}
else:
with open(asic_topo_filename) as f:
asic_definition = yaml.load(f)
slot_definition = yaml.load(f)

### parse topo file specified in vars/ to reverse as dut config
dut_num = 1
Expand All @@ -225,17 +240,13 @@ def get_topo_config(self, topo_name, hwsku):
vm_topo_config['dut_type'] = topo_definition['configuration_properties']['common']['dut_type']
vm_topo_config['dut_asn'] = dut_asn


for asic in asic_definition:
po_map_asic = [None] * 16 # maximum 16 port channel interfaces
asic_topo_config[asic] = dict()
asic_topo_config[asic]['dut_asn'] = asic_definition[asic]['configuration_properties']['common']['dut_asn']
asic_topo_config[asic]['asic_type'] = asic_definition[asic]['configuration_properties']['common']['asic_type']
asic_topo_config[asic]['Loopback4096'] = []
for lo4096 in asic_definition[asic]['configuration_properties']['common']['Loopback4096']:
asic_topo_config[asic]['Loopback4096'].append(lo4096)

asic_topo_config[asic]['neigh_asic'] = self.parse_topo_defintion(asic_definition[asic], po_map_asic, 1, 'NEIGH_ASIC')
for slot,asic_definition in slot_definition.items():
asic_topo_config[slot] = dict()
for asic in asic_definition:
po_map_asic = [None] * 16 # maximum 16 port channel interfaces
asic_topo_config[slot][asic] = dict()
asic_topo_config[slot][asic]['asic_type'] = asic_definition[asic]['configuration_properties']['common']['asic_type']
asic_topo_config[slot][asic]['neigh_asic'] = self.parse_topo_defintion(asic_definition[asic], po_map_asic, 1, 'NEIGH_ASIC')

vm_topo_config['host_interfaces_by_dut'] = [[] for i in range(dut_num)]
if 'host_interfaces' in topo_definition['topology']:
Expand Down
Loading