[chassis] VoQ configuration using minigraph.xml file (#5991)

This commit contains the following changes to support for configuring a VoQ switch using a minigraph.xml file.:
- Add support for system ports configuration to minigraph
- Add support for SwitchId, SwitchType and MaxCores to minigraph
- Add support for inband vlan configuration in minigraph
- `asic_name` is now a mandatory attribute in CONFIG_DB on VoQ switches

Co-authored-by: Maxime Lorrillere <mlorrillere@arista.com>
This commit is contained in:
Maxime Lorrillere 2021-04-27 12:18:45 -07:00 committed by GitHub
parent 5f435f2296
commit a92da83047
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 470 additions and 12 deletions

View File

@ -456,6 +456,17 @@ def parse_dpg(dpg, hname):
gwaddr = ipaddress.ip_address(next(mgmtipn.hosts()))
mgmt_intf[(intfname, ipprefix)] = {'gwaddr': gwaddr}
voqinbandintfs = child.find(str(QName(ns, "VoqInbandInterfaces")))
voq_inband_intfs = {}
if voqinbandintfs:
for voqintf in voqinbandintfs.findall(str(QName(ns1, "VoqInbandInterface"))):
intfname = voqintf.find(str(QName(ns, "Name"))).text
intftype = voqintf.find(str(QName(ns, "Type"))).text
ipprefix = voqintf.find(str(QName(ns1, "PrefixStr"))).text
if intfname not in voq_inband_intfs:
voq_inband_intfs[intfname] = {'inband_type': intftype}
voq_inband_intfs["%s|%s" % (intfname, ipprefix)] = {}
pcintfs = child.find(str(QName(ns, "PortChannelInterfaces")))
pc_intfs = []
pcs = {}
@ -667,8 +678,8 @@ def parse_dpg(dpg, hname):
if mg_key in mg_tunnel.attrib:
tunnelintfs[tunnel_type][tunnel_name][table_key] = mg_tunnel.attrib[mg_key]
return intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnelintfs, dpg_ecmp_content
return None, None, None, None, None, None, None, None, None, None
return intfs, lo_intfs, mvrf, mgmt_intf, voq_inband_intfs, vlans, vlan_members, pcs, pc_members, acls, vni, tunnelintfs, dpg_ecmp_content
return None, None, None, None, None, None, None, None, None, None, None, None, None
def parse_host_loopback(dpg, hname):
for child in dpg:
@ -794,6 +805,9 @@ def parse_meta(meta, hname):
cloudtype = None
resource_type = None
downstream_subrole = None
switch_id = None
switch_type = None
max_cores = None
kube_data = {}
device_metas = meta.find(str(QName(ns, "Devices")))
for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))):
@ -825,11 +839,17 @@ def parse_meta(meta, hname):
resource_type = value
elif name == "DownStreamSubRole":
downstream_subrole = value
elif name == "SwitchId":
switch_id = value
elif name == "SwitchType":
switch_type = value
elif name == "MaxCores":
max_cores = value
elif name == "KubernetesEnabled":
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, downstream_subrole, kube_data
return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, switch_id, switch_type, max_cores, kube_data
def parse_linkmeta(meta, hname):
@ -886,6 +906,9 @@ def parse_linkmeta(meta, hname):
def parse_asic_meta(meta, hname):
sub_role = None
switch_id = None
switch_type = None
max_cores = None
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():
@ -895,7 +918,13 @@ def parse_asic_meta(meta, hname):
value = device_property.find(str(QName(ns1, "Value"))).text
if name == "SubRole":
sub_role = value
return sub_role
elif name == "SwitchId":
switch_id = value
elif name == "SwitchType":
switch_type = value
elif name == "MaxCores":
max_cores = value
return sub_role, switch_id, switch_type, max_cores
def parse_deviceinfo(meta, hwsku):
port_speeds = {}
@ -912,7 +941,28 @@ def parse_deviceinfo(meta, hwsku):
if desc != None:
port_descriptions[port_alias_map.get(alias, alias)] = desc.text
port_speeds[port_alias_map.get(alias, alias)] = speed
return port_speeds, port_descriptions
sysports = device_info.find(str(QName(ns, "SystemPorts")))
sys_ports = {}
if sysports is not None:
for sysport in sysports.findall(str(QName(ns, "SystemPort"))):
portname = sysport.find(str(QName(ns, "Name"))).text
hostname = sysport.find(str(QName(ns, "Hostname")))
asic_name = sysport.find(str(QName(ns, "AsicName")))
system_port_id = sysport.find(str(QName(ns, "SystemPortId"))).text
switch_id = sysport.find(str(QName(ns, "SwitchId"))).text
core_id = sysport.find(str(QName(ns, "CoreId"))).text
core_port_id = sysport.find(str(QName(ns, "CorePortId"))).text
speed = sysport.find(str(QName(ns, "Speed"))).text
num_voq = sysport.find(str(QName(ns, "NumVoq"))).text
key = portname
if asic_name is not None:
key = "%s|%s" % (asic_name.text, key)
if hostname is not None:
key = "%s|%s" % (hostname.text, key)
sys_ports[key] = {"system_port_id": system_port_id, "switch_id": switch_id, "core_index": core_id, "core_port_index": core_port_id, "speed": speed, "num_voq": num_voq}
return port_speeds, port_descriptions, sys_ports
# Function to check if IP address is present in the key.
# If it is present, then the key would be a tuple.
@ -1097,6 +1147,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
vlan_members = None
pcs = None
mgmt_intf = None
voq_inband_intfs = None
lo_intfs = None
neighbors = None
devices = None
@ -1107,6 +1158,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
port_speeds_default = {}
port_speed_png = {}
port_descriptions = {}
sys_ports = {}
console_ports = {}
mux_cable_ports = {}
syslog_servers = []
@ -1119,6 +1171,9 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
deployment_id = None
region = None
cloudtype = None
switch_id = None
switch_type = None
max_cores = None
hostname = None
linkmetas = {}
host_lo_intfs = None
@ -1153,7 +1208,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
for child in root:
if asic_name is None:
if child.tag == str(QName(ns, "DpgDec")):
(intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, hostname)
(intfs, lo_intfs, mvrf, mgmt_intf, voq_inband_intfs, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, hostname)
elif child.tag == str(QName(ns, "CpgDec")):
(bgp_sessions, bgp_internal_sessions, bgp_voq_chassis_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, hostname)
elif child.tag == str(QName(ns, "PngDec")):
@ -1161,25 +1216,25 @@ 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, downstream_subrole, kube_data) = parse_meta(child, hostname)
(syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, switch_id, switch_type, max_cores, 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")):
(port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku)
(port_speeds_default, port_descriptions, sys_ports) = parse_deviceinfo(child, hwsku)
else:
if child.tag == str(QName(ns, "DpgDec")):
(intfs, lo_intfs, mvrf, mgmt_intf, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, asic_name)
(intfs, lo_intfs, mvrf, mgmt_intf, voq_inband_intfs, vlans, vlan_members, pcs, pc_members, acls, vni, tunnel_intfs, dpg_ecmp_content) = parse_dpg(child, asic_name)
host_lo_intfs = parse_host_loopback(child, hostname)
elif child.tag == str(QName(ns, "CpgDec")):
(bgp_sessions, bgp_internal_sessions, bgp_voq_chassis_sessions, bgp_asn, bgp_peers_with_range, bgp_monitors) = parse_cpg(child, asic_name, local_devices)
elif child.tag == str(QName(ns, "PngDec")):
(neighbors, devices, port_speed_png) = parse_asic_png(child, asic_name, hostname)
elif child.tag == str(QName(ns, "MetadataDeclaration")):
(sub_role) = parse_asic_meta(child, asic_name)
(sub_role, switch_id, switch_type, max_cores ) = parse_asic_meta(child, asic_name)
elif child.tag == str(QName(ns, "LinkMetadataDeclaration")):
linkmetas = parse_linkmeta(child, hostname)
elif child.tag == str(QName(ns, "DeviceInfos")):
(port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku)
(port_speeds_default, port_descriptions, sys_ports) = parse_deviceinfo(child, hwsku)
# set the host device type in asic metadata also
device_type = [devices[key]['type'] for key in devices if key.lower() == hostname.lower()][0]
@ -1232,6 +1287,26 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
current_device['sub_role'] = sub_role
results['DEVICE_METADATA']['localhost']['sub_role'] = sub_role
results['DEVICE_METADATA']['localhost']['asic_name'] = asic_name
elif switch_type == "voq":
# On Voq switches asic_name is mandatory even on single-asic devices
results['DEVICE_METADATA']['localhost']['asic_name'] = 'Asic0'
# on Voq system each asic has a switch_id
if switch_id is not None:
results['DEVICE_METADATA']['localhost']['switch_id'] = switch_id
# on Voq system each asic has a switch_type
if switch_type is not None:
results['DEVICE_METADATA']['localhost']['switch_type'] = switch_type
# on Voq system each asic has a max_cores
if max_cores is not None:
results['DEVICE_METADATA']['localhost']['max_cores'] = max_cores
# Voq systems have an inband interface
if voq_inband_intfs is not None:
results['VOQ_INBAND_INTERFACE'] = {}
for key in voq_inband_intfs:
results['VOQ_INBAND_INTERFACE'][key] = voq_inband_intfs[key]
if resource_type is not None:
results['DEVICE_METADATA']['localhost']['resource_type'] = resource_type
@ -1312,6 +1387,9 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
results['INTERFACE'] = phyport_intfs
results['VLAN_INTERFACE'] = vlan_intfs
if sys_ports:
results['SYSTEM_PORT'] = sys_ports
for port_name in port_speeds_default:
# ignore port not in port_config.ini
if port_name not in ports:
@ -1597,7 +1675,7 @@ def parse_asic_sub_role(filename, asic_name):
root = ET.parse(filename).getroot()
for child in root:
if child.tag == str(QName(ns, "MetadataDeclaration")):
sub_role = parse_asic_meta(child, asic_name)
sub_role, _, _, _ = parse_asic_meta(child, asic_name)
return sub_role
def parse_asic_meta_get_devices(root):

View File

@ -0,0 +1,338 @@
<DeviceMiniGraph xmlns="Microsoft.Search.Autopilot.Evolution" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<CpgDec>
<PeeringSessions/>
<Routers xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
</CpgDec>
<DpgDec>
<DeviceDataPlaneInfo>
<IPSecTunnels/>
<LoopbackIPInterfaces xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
<a:LoopbackIPInterface>
<Name>HostIP</Name>
<AttachTo>Loopback0</AttachTo>
<a:Prefix xmlns:b="Microsoft.Search.Autopilot.Evolution">
<b:IPPrefix>10.1.0.32/32</b:IPPrefix>
</a:Prefix>
<a:PrefixStr>10.1.0.32/32</a:PrefixStr>
</a:LoopbackIPInterface>
<a:LoopbackIPInterface>
<Name>HostIP1</Name>
<AttachTo>Loopback0</AttachTo>
<a:Prefix xmlns:b="Microsoft.Search.Autopilot.Evolution">
<b:IPPrefix>FC00:1::32/128</b:IPPrefix>
</a:Prefix>
<a:PrefixStr>FC00:1::32/128</a:PrefixStr>
</a:LoopbackIPInterface>
</LoopbackIPInterfaces>
<ManagementIPInterfaces xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
<a:ManagementIPInterface>
<Name>HostIP</Name>
<AttachTo>eth0</AttachTo>
<a:Prefix xmlns:b="Microsoft.Search.Autopilot.Evolution">
<b:IPPrefix>10.0.0.100/24</b:IPPrefix>
</a:Prefix>
<a:PrefixStr>10.0.0.100/24</a:PrefixStr>
</a:ManagementIPInterface>
</ManagementIPInterfaces>
<ManagementVIPInterfaces xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
<MplsInterfaces/>
<MplsTeInterfaces/>
<RsvpInterfaces/>
<Hostname>linecard-1</Hostname>
<PortChannelInterfaces/>
<VlanInterfaces/>
<IPInterfaces/>
<VoqInbandInterfaces xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
<a:VoqInbandInterface>
<Name>Vlan3094</Name>
<Type>Vlan</Type>
<a:PrefixStr>1.1.1.1/24</a:PrefixStr>
</a:VoqInbandInterface>
</VoqInbandInterfaces>
<DataAcls/>
<AclInterfaces/>
<DownstreamSummaries/>
<DownstreamSummarySet xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
</DeviceDataPlaneInfo>
</DpgDec>
<PngDec>
<DeviceInterfaceLinks/>
<Devices>
<Device i:type="ToRRouter">
<Hostname>linecard-1</Hostname>
<HwSku>Force10-S6000</HwSku>
</Device>
</Devices>
</PngDec>
<MetadataDeclaration>
<Devices xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
<a:DeviceMetadata>
<a:Name>linecard-1</a:Name>
<a:Properties>
<a:DeviceProperty>
<a:Name>DeploymentId</a:Name>
<a:Reference i:nil="true"/>
<a:Value>1</a:Value>
</a:DeviceProperty>
<a:DeviceProperty>
<a:Name>Region</a:Name>
<a:Reference i:nil="true"/>
<a:Value>usfoo</a:Value>
</a:DeviceProperty>
<a:DeviceProperty>
<a:Name>CloudType</a:Name>
<a:Reference i:nil="true"/>
<a:Value>Public</a:Value>
</a:DeviceProperty>
<a:DeviceProperty>
<a:Name>ErspanDestinationIpv4</a:Name>
<a:Reference i:nil="true"/>
<a:Value>10.0.100.1</a:Value>
</a:DeviceProperty>
<a:DeviceProperty>
<a:Name>NtpResources</a:Name>
<a:Value>
10.0.10.1;10.0.10.2
</a:Value>
</a:DeviceProperty>
<a:DeviceProperty>
<a:Name>SnmpResources</a:Name>
<a:Value>
10.0.10.3;10.0.10.4
</a:Value>
</a:DeviceProperty>
<a:DeviceProperty>
<a:Name>SyslogResources</a:Name>
<a:Value>
10.0.10.5;10.0.10.6;
</a:Value>
</a:DeviceProperty>
<a:DeviceProperty>
<a:Name>TacacsServer</a:Name>
<a:Reference i:nil="true"/>
<a:Value>10.0.10.7;10.0.10.8</a:Value>
</a:DeviceProperty>
<a:DeviceProperty>
<a:Name>ResourceType</a:Name>
<a:Reference i:nil="true"/>
<a:Value>resource_type_x</a:Value>
</a:DeviceProperty>
<a:DeviceProperty>
<a:Name>SwitchId</a:Name>
<a:Reference i:nil="true"/>
<a:Value>0</a:Value>
</a:DeviceProperty>
<a:DeviceProperty>
<a:Name>SwitchType</a:Name>
<a:Reference i:nil="true"/>
<a:Value>voq</a:Value>
</a:DeviceProperty>
<a:DeviceProperty>
<a:Name>MaxCores</a:Name>
<a:Reference i:nil="true"/>
<a:Value>16</a:Value>
</a:DeviceProperty>
</a:Properties>
</a:DeviceMetadata>
</Devices>
<Properties xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
</MetadataDeclaration>
<DeviceInfos>
<DeviceInfo>
<EthernetInterfaces xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
<a:EthernetInterface>
<ElementType>DeviceInterface</ElementType>
<AlternateSpeeds i:nil="true"/>
<EnableFlowControl>true</EnableFlowControl>
<Index>1</Index>
<InterfaceName>fortyGigE0/0</InterfaceName>
<InterfaceType i:nil="true"/>
<MultiPortsInterface>false</MultiPortsInterface>
<PortName>0</PortName>
<Priority>0</Priority>
<Speed>10000</Speed>
</a:EthernetInterface>
<a:EthernetInterface>
<ElementType>DeviceInterface</ElementType>
<AlternateSpeeds i:nil="true"/>
<EnableFlowControl>true</EnableFlowControl>
<Index>1</Index>
<InterfaceName>fortyGigE0/4</InterfaceName>
<InterfaceType i:nil="true"/>
<MultiPortsInterface>false</MultiPortsInterface>
<PortName>0</PortName>
<Priority>0</Priority>
<Speed>25000</Speed>
</a:EthernetInterface>
<a:EthernetInterface>
<ElementType>DeviceInterface</ElementType>
<AlternateSpeeds i:nil="true"/>
<EnableFlowControl>true</EnableFlowControl>
<Index>1</Index>
<InterfaceName>fortyGigE0/8</InterfaceName>
<InterfaceType i:nil="true"/>
<MultiPortsInterface>false</MultiPortsInterface>
<PortName>0</PortName>
<Priority>0</Priority>
<Speed>40000</Speed>
<Description>Interface description</Description>
</a:EthernetInterface>
<a:EthernetInterface>
<ElementType>DeviceInterface</ElementType>
<AlternateSpeeds i:nil="true"/>
<EnableFlowControl>true</EnableFlowControl>
<Index>1</Index>
<InterfaceName>fortyGigE0/12</InterfaceName>
<InterfaceType i:nil="true"/>
<MultiPortsInterface>false</MultiPortsInterface>
<PortName>0</PortName>
<Priority>0</Priority>
<Speed>100000</Speed>
<Description>Interface description</Description>
</a:EthernetInterface>
</EthernetInterfaces>
<FlowControl>true</FlowControl>
<Height>0</Height>
<HwSku>Force10-S6000</HwSku>
<ManagementInterfaces xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
<a:ManagementInterface>
<ElementType>DeviceInterface</ElementType>
<AlternateSpeeds i:nil="true"/>
<EnableFlowControl>true</EnableFlowControl>
<Index>1</Index>
<InterfaceName>Management1</InterfaceName>
<MultiPortsInterface>false</MultiPortsInterface>
<PortName>mgmt1</PortName>
<Speed>1000</Speed>
</a:ManagementInterface>
</ManagementInterfaces>
<SystemPorts>
<SystemPort>
<Name>Cpu0</Name>
<Hostname>linecard-1</Hostname>
<AsicName>Asic0</AsicName>
<Speed>1000</Speed>
<SystemPortId>1</SystemPortId>
<SwitchId>0</SwitchId>
<CoreId>0</CoreId>
<CorePortId>0</CorePortId>
<NumVoq>8</NumVoq>
</SystemPort>
<SystemPort>
<Name>Ethernet1/1</Name>
<Hostname>linecard-1</Hostname>
<AsicName>Asic0</AsicName>
<Speed>40000</Speed>
<SystemPortId>2</SystemPortId>
<SwitchId>0</SwitchId>
<CoreId>0</CoreId>
<CorePortId>1</CorePortId>
<NumVoq>8</NumVoq>
</SystemPort>
<SystemPort>
<Name>Ethernet1/2</Name>
<Hostname>linecard-1</Hostname>
<AsicName>Asic0</AsicName>
<Speed>40000</Speed>
<SystemPortId>3</SystemPortId>
<SwitchId>0</SwitchId>
<CoreId>0</CoreId>
<CorePortId>2</CorePortId>
<NumVoq>8</NumVoq>
</SystemPort>
<SystemPort>
<Name>Ethernet1/3</Name>
<Hostname>linecard-1</Hostname>
<AsicName>Asic0</AsicName>
<Speed>40000</Speed>
<SystemPortId>4</SystemPortId>
<SwitchId>0</SwitchId>
<CoreId>1</CoreId>
<CorePortId>3</CorePortId>
<NumVoq>8</NumVoq>
</SystemPort>
<SystemPort>
<Name>Ethernet1/4</Name>
<Hostname>linecard-1</Hostname>
<AsicName>Asic0</AsicName>
<Speed>40000</Speed>
<SystemPortId>5</SystemPortId>
<SwitchId>0</SwitchId>
<CoreId>1</CoreId>
<CorePortId>4</CorePortId>
<NumVoq>8</NumVoq>
</SystemPort>
<SystemPort>
<Name>Cpu0</Name>
<Hostname>linecard-2</Hostname>
<AsicName>Asic0</AsicName>
<Speed>1000</Speed>
<AttachTo>Cpu0</AttachTo>
<SystemPortId>256</SystemPortId>
<SwitchId>2</SwitchId>
<CoreId>0</CoreId>
<CorePortId>0</CorePortId>
<NumVoq>8</NumVoq>
</SystemPort>
<SystemPort>
<Name>Ethernet1/5</Name>
<Hostname>linecard-2</Hostname>
<AsicName>Asic0</AsicName>
<Speed>40000</Speed>
<SystemPortId>257</SystemPortId>
<SwitchId>2</SwitchId>
<CoreId>0</CoreId>
<CorePortId>1</CorePortId>
<NumVoq>8</NumVoq>
</SystemPort>
<SystemPort>
<Name>Ethernet1/6</Name>
<Hostname>linecard-2</Hostname>
<AsicName>Asic0</AsicName>
<Speed>40000</Speed>
<SystemPortId>258</SystemPortId>
<SwitchId>2</SwitchId>
<CoreId>1</CoreId>
<CorePortId>2</CorePortId>
<NumVoq>8</NumVoq>
</SystemPort>
<SystemPort>
<Name>Cpu0</Name>
<Hostname>linecard-2</Hostname>
<AsicName>Asic1</AsicName>
<Speed>1000</Speed>
<AttachTo>Cpu0</AttachTo>
<SystemPortId>259</SystemPortId>
<SwitchId>4</SwitchId>
<CoreId>0</CoreId>
<CorePortId>0</CorePortId>
<NumVoq>8</NumVoq>
</SystemPort>
<SystemPort>
<Name>Ethernet1/7</Name>
<Hostname>linecard-2</Hostname>
<AsicName>Asic1</AsicName>
<Speed>40000</Speed>
<SystemPortId>260</SystemPortId>
<SwitchId>4</SwitchId>
<CoreId>0</CoreId>
<CorePortId>1</CorePortId>
<NumVoq>8</NumVoq>
</SystemPort>
<SystemPort>
<Name>Ethernet1/8</Name>
<Hostname>linecard-2</Hostname>
<AsicName>Asic1</AsicName>
<Speed>40000</Speed>
<SystemPortId>261</SystemPortId>
<SwitchId>4</SwitchId>
<CoreId>1</CoreId>
<CorePortId>2</CorePortId>
<NumVoq>8</NumVoq>
</SystemPort>
</SystemPorts>
</DeviceInfo>
</DeviceInfos>
<Hostname>linecard-1</Hostname>
<HwSku>Force10-S6000</HwSku>
</DeviceMiniGraph>

View File

@ -21,6 +21,7 @@ class TestCfgGen(TestCase):
self.sample_graph_metadata = os.path.join(self.test_dir, 'simple-sample-graph-metadata.xml')
self.sample_graph_pc_test = os.path.join(self.test_dir, 'pc-test-graph.xml')
self.sample_graph_bgp_speaker = os.path.join(self.test_dir, 't0-sample-bgp-speaker.xml')
self.sample_graph_voq = os.path.join(self.test_dir, 'sample-voq-graph.xml')
self.sample_device_desc = os.path.join(self.test_dir, 'device.xml')
self.port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini')
self.port_config_autoneg = os.path.join(self.test_dir, 't0-sample-autoneg-port-config.ini')
@ -68,6 +69,11 @@ class TestCfgGen(TestCase):
output = self.run_script(argument)
self.assertEqual(output.strip(), "('eth0', '10.0.1.5/28')")
def test_minigraph_hostname(self):
argument = '-v "DEVICE_METADATA[\'localhost\'][\'hostname\']" -m "' + self.sample_graph + '"'
output = self.run_script(argument)
self.assertEqual(output.strip(), 'OCPSCH01040DDLF')
def test_minigraph_sku(self):
argument = '-v "DEVICE_METADATA[\'localhost\'][\'hwsku\']" -m "' + self.sample_graph + '"'
output = self.run_script(argument)
@ -665,3 +671,39 @@ class TestCfgGen(TestCase):
argument = '-a \'{"key1":"value"}\' --var-json INTERFACE'
output = self.run_script(argument)
self.assertEqual(output, '')
def test_minigraph_voq_metadata(self):
argument = "-m {} --var-json DEVICE_METADATA".format(self.sample_graph_voq)
output = json.loads(self.run_script(argument))
self.assertEqual(output['localhost']['asic_name'], 'Asic0')
self.assertEqual(output['localhost']['switch_id'], '0')
self.assertEqual(output['localhost']['switch_type'], 'voq')
self.assertEqual(output['localhost']['max_cores'], '16')
def test_minigraph_voq_system_ports(self):
argument = "-m {} --var-json SYSTEM_PORT".format(self.sample_graph_voq)
self.assertDictEqual(
json.loads(self.run_script(argument)),
{
"linecard-1|Asic0|Cpu0": { "core_port_index": "0", "num_voq": "8", "switch_id": "0", "speed": "1000", "core_index": "0", "system_port_id": "1" },
"linecard-1|Asic0|Ethernet1/1": { "core_port_index": "1", "num_voq": "8", "switch_id": "0", "speed": "40000", "core_index": "0", "system_port_id": "2" },
"linecard-1|Asic0|Ethernet1/2": { "core_port_index": "2", "num_voq": "8", "switch_id": "0", "speed": "40000", "core_index": "0", "system_port_id": "3" },
"linecard-1|Asic0|Ethernet1/3": { "core_port_index": "3", "num_voq": "8", "switch_id": "0", "speed": "40000", "core_index": "1", "system_port_id": "4" },
"linecard-1|Asic0|Ethernet1/4": { "core_port_index": "4", "num_voq": "8", "switch_id": "0", "speed": "40000", "core_index": "1", "system_port_id": "5" },
"linecard-2|Asic0|Cpu0": { "core_port_index": "0", "num_voq": "8", "switch_id": "2", "speed": "1000", "core_index": "0", "system_port_id": "256" },
"linecard-2|Asic0|Ethernet1/5": { "core_port_index": "1", "num_voq": "8", "switch_id": "2", "speed": "40000", "core_index": "0", "system_port_id": "257" },
"linecard-2|Asic0|Ethernet1/6": { "core_port_index": "2", "num_voq": "8", "switch_id": "2", "speed": "40000", "core_index": "1", "system_port_id": "258" },
"linecard-2|Asic1|Cpu0": { "core_port_index": "0", "num_voq": "8", "switch_id": "4", "speed": "1000", "core_index": "0", "system_port_id": "259" },
"linecard-2|Asic1|Ethernet1/7": { "core_port_index": "1", "num_voq": "8", "switch_id": "4", "speed": "40000", "core_index": "0", "system_port_id": "260" },
"linecard-2|Asic1|Ethernet1/8": { "core_port_index": "2", "num_voq": "8", "switch_id": "4", "speed": "40000", "core_index": "1", "system_port_id": "261" }
}
)
def test_minigraph_voq_inband_interface(self):
argument = "-m {} --var-json VOQ_INBAND_INTERFACE".format(self.sample_graph_voq)
self.assertDictEqual(
json.loads(self.run_script(argument)),
{ 'Vlan3094': {'inband_type': 'Vlan'},
'Vlan3094|1.1.1.1/24': {}
}
)