[minigraph] Support FECDisabled in minigraph parser (#4556)
Signed-off-by: Qi Luo <qiluo-msft@users.noreply.github.com>
This commit is contained in:
parent
86627dfd35
commit
d0099ed43e
@ -35,7 +35,7 @@ backend_device_types = ['BackEndToRRouter', 'BackEndLeafRouter']
|
|||||||
VLAN_SUB_INTERFACE_SEPARATOR = '.'
|
VLAN_SUB_INTERFACE_SEPARATOR = '.'
|
||||||
VLAN_SUB_INTERFACE_VLAN_ID = '10'
|
VLAN_SUB_INTERFACE_VLAN_ID = '10'
|
||||||
|
|
||||||
# Default Virtual Network Index (VNI)
|
# Default Virtual Network Index (VNI)
|
||||||
vni_default = 8000
|
vni_default = 8000
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
@ -539,6 +539,39 @@ def parse_meta(meta, hname):
|
|||||||
region = value
|
region = value
|
||||||
return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region
|
return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region
|
||||||
|
|
||||||
|
|
||||||
|
def parse_linkmeta(meta, hname):
|
||||||
|
link = meta.find(str(QName(ns, "Link")))
|
||||||
|
linkmetas = {}
|
||||||
|
for linkmeta in link.findall(str(QName(ns1, "LinkMetadata"))):
|
||||||
|
port = None
|
||||||
|
fec_disabled = None
|
||||||
|
|
||||||
|
# Sample: ARISTA05T1:Ethernet1/33;switch-t0:fortyGigE0/4
|
||||||
|
key = linkmeta.find(str(QName(ns1, "Key"))).text
|
||||||
|
endpoints = key.split(';')
|
||||||
|
for endpoint in endpoints:
|
||||||
|
t = endpoint.split(':')
|
||||||
|
if len(t) == 2 and t[0].lower() == hname.lower():
|
||||||
|
port = t[1]
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# Cannot find a matching hname, something went wrong
|
||||||
|
continue
|
||||||
|
|
||||||
|
properties = linkmeta.find(str(QName(ns1, "Properties")))
|
||||||
|
for device_property in properties.findall(str(QName(ns1, "DeviceProperty"))):
|
||||||
|
name = device_property.find(str(QName(ns1, "Name"))).text
|
||||||
|
value = device_property.find(str(QName(ns1, "Value"))).text
|
||||||
|
if name == "FECDisabled":
|
||||||
|
fec_disabled = value
|
||||||
|
|
||||||
|
linkmetas[port] = {}
|
||||||
|
if fec_disabled:
|
||||||
|
linkmetas[port]["FECDisabled"] = fec_disabled
|
||||||
|
return linkmetas
|
||||||
|
|
||||||
|
|
||||||
def parse_asic_meta(meta, hname):
|
def parse_asic_meta(meta, hname):
|
||||||
sub_role = None
|
sub_role = None
|
||||||
device_metas = meta.find(str(QName(ns, "Devices")))
|
device_metas = meta.find(str(QName(ns, "Devices")))
|
||||||
@ -683,7 +716,6 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None):
|
|||||||
generate asic specific configuration.
|
generate asic specific configuration.
|
||||||
"""
|
"""
|
||||||
root = ET.parse(filename).getroot()
|
root = ET.parse(filename).getroot()
|
||||||
mini_graph_path = filename
|
|
||||||
|
|
||||||
u_neighbors = None
|
u_neighbors = None
|
||||||
u_devices = None
|
u_devices = None
|
||||||
@ -717,8 +749,9 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None):
|
|||||||
deployment_id = None
|
deployment_id = None
|
||||||
region = None
|
region = None
|
||||||
hostname = None
|
hostname = None
|
||||||
|
linkmetas = {}
|
||||||
|
|
||||||
#hostname is the asic_name, get the asic_id from the asic_name
|
# hostname is the asic_name, get the asic_id from the asic_name
|
||||||
if asic_name is not None:
|
if asic_name is not None:
|
||||||
asic_id = get_npu_id_from_name(asic_name)
|
asic_id = get_npu_id_from_name(asic_name)
|
||||||
else:
|
else:
|
||||||
@ -751,6 +784,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None):
|
|||||||
(u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname)
|
(u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname)
|
||||||
elif child.tag == str(QName(ns, "MetadataDeclaration")):
|
elif child.tag == str(QName(ns, "MetadataDeclaration")):
|
||||||
(syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region) = parse_meta(child, hostname)
|
(syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region) = parse_meta(child, hostname)
|
||||||
|
elif child.tag == str(QName(ns, "LinkMetadataDeclaration")):
|
||||||
|
linkmetas = parse_linkmeta(child, hostname)
|
||||||
elif child.tag == str(QName(ns, "DeviceInfos")):
|
elif child.tag == str(QName(ns, "DeviceInfos")):
|
||||||
(port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku)
|
(port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku)
|
||||||
else:
|
else:
|
||||||
@ -762,6 +797,8 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None):
|
|||||||
(neighbors, devices, port_speed_png) = parse_asic_png(child, asic_name, hostname)
|
(neighbors, devices, port_speed_png) = parse_asic_png(child, asic_name, hostname)
|
||||||
elif child.tag == str(QName(ns, "MetadataDeclaration")):
|
elif child.tag == str(QName(ns, "MetadataDeclaration")):
|
||||||
(sub_role) = parse_asic_meta(child, asic_name)
|
(sub_role) = 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")):
|
elif child.tag == str(QName(ns, "DeviceInfos")):
|
||||||
(port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku)
|
(port_speeds_default, port_descriptions) = parse_deviceinfo(child, hwsku)
|
||||||
|
|
||||||
@ -848,7 +885,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None):
|
|||||||
|
|
||||||
for port_name in port_speed_png:
|
for port_name in port_speed_png:
|
||||||
# not consider port not in port_config.ini
|
# not consider port not in port_config.ini
|
||||||
#If no port_config_file is found ports is empty so ignore this error
|
# If no port_config_file is found ports is empty so ignore this error
|
||||||
if port_config_file is not None:
|
if port_config_file is not None:
|
||||||
if port_name not in ports:
|
if port_name not in ports:
|
||||||
print >> sys.stderr, "Warning: ignore interface '%s' as it is not in the port_config.ini" % port_name
|
print >> sys.stderr, "Warning: ignore interface '%s' as it is not in the port_config.ini" % port_name
|
||||||
@ -857,7 +894,14 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None):
|
|||||||
ports.setdefault(port_name, {})['speed'] = port_speed_png[port_name]
|
ports.setdefault(port_name, {})['speed'] = port_speed_png[port_name]
|
||||||
|
|
||||||
for port_name, port in ports.items():
|
for port_name, port in ports.items():
|
||||||
if port.get('speed') == '100000':
|
# get port alias from port_config.ini
|
||||||
|
if port_config_file:
|
||||||
|
alias = port.get('alias')
|
||||||
|
else:
|
||||||
|
alias = port_name
|
||||||
|
# generate default 100G FEC
|
||||||
|
# Note: FECDisabled only be effective on 100G port right now
|
||||||
|
if port.get('speed') == '100000' and linkmetas.get(alias, {}).get('FECDisabled', '').lower() != 'true':
|
||||||
port['fec'] = 'rs'
|
port['fec'] = 'rs'
|
||||||
|
|
||||||
# set port description if parsed from deviceinfo
|
# set port description if parsed from deviceinfo
|
||||||
|
@ -381,13 +381,14 @@
|
|||||||
<EndPort>Ethernet1/1</EndPort>
|
<EndPort>Ethernet1/1</EndPort>
|
||||||
<StartDevice>switch-t0</StartDevice>
|
<StartDevice>switch-t0</StartDevice>
|
||||||
<StartPort>fortyGigE0/124</StartPort>
|
<StartPort>fortyGigE0/124</StartPort>
|
||||||
|
<Bandwidth>100000</Bandwidth>
|
||||||
</DeviceLinkBase>
|
</DeviceLinkBase>
|
||||||
<DeviceLinkBase>
|
<DeviceLinkBase>
|
||||||
<ElementType>DeviceInterfaceLink</ElementType>
|
<ElementType>DeviceInterfaceLink</ElementType>
|
||||||
<AutoNegotiation>true</AutoNegotiation>
|
<AutoNegotiation>true</AutoNegotiation>
|
||||||
<Bandwidth>10000</Bandwidth>
|
<Bandwidth>100000</Bandwidth>
|
||||||
<EndDevice>switch-t0</EndDevice>
|
<EndDevice>switch-t0</EndDevice>
|
||||||
<EndPort>fortyGigE0/2</EndPort>
|
<EndPort>fortyGigE0/4</EndPort>
|
||||||
<FlowControl>true</FlowControl>
|
<FlowControl>true</FlowControl>
|
||||||
<StartDevice>ARISTA05T1</StartDevice>
|
<StartDevice>ARISTA05T1</StartDevice>
|
||||||
<StartPort>Ethernet1/33</StartPort>
|
<StartPort>Ethernet1/33</StartPort>
|
||||||
@ -439,6 +440,32 @@
|
|||||||
</Devices>
|
</Devices>
|
||||||
<Properties xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
|
<Properties xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
|
||||||
</MetadataDeclaration>
|
</MetadataDeclaration>
|
||||||
|
<LinkMetadataDeclaration>
|
||||||
|
<Link xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
|
||||||
|
<a:LinkMetadata>
|
||||||
|
<a:Name i:nil="true"/>
|
||||||
|
<a:Properties>
|
||||||
|
<a:DeviceProperty>
|
||||||
|
<a:Name>FECDisabled</a:Name>
|
||||||
|
<a:Reference i:nil="true"/>
|
||||||
|
<a:Value>True</a:Value>
|
||||||
|
</a:DeviceProperty>
|
||||||
|
</a:Properties>
|
||||||
|
<a:Key>ARISTA05T1:Ethernet1/33;switch-t0:fortyGigE0/4</a:Key>
|
||||||
|
</a:LinkMetadata>
|
||||||
|
<a:LinkMetadata>
|
||||||
|
<a:Name i:nil="true"/>
|
||||||
|
<a:Properties>
|
||||||
|
<a:DeviceProperty>
|
||||||
|
<a:Name>FECDisabled</a:Name>
|
||||||
|
<a:Reference i:nil="true"/>
|
||||||
|
<a:Value>True</a:Value>
|
||||||
|
</a:DeviceProperty>
|
||||||
|
</a:Properties>
|
||||||
|
<a:Key>ARISTA06T1:Ethernet1/34;switch-t0:fortyGigE0/8</a:Key>
|
||||||
|
</a:LinkMetadata>
|
||||||
|
</Link>
|
||||||
|
</LinkMetadataDeclaration>
|
||||||
<Hostname>switch-t0</Hostname>
|
<Hostname>switch-t0</Hostname>
|
||||||
<HwSku>Force10-S6000</HwSku>
|
<HwSku>Force10-S6000</HwSku>
|
||||||
</DeviceMiniGraph>
|
</DeviceMiniGraph>
|
||||||
|
@ -107,8 +107,6 @@ class TestCfgGen(TestCase):
|
|||||||
argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v ACL_TABLE'
|
argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v ACL_TABLE'
|
||||||
output = self.run_script(argument, True)
|
output = self.run_script(argument, True)
|
||||||
self.assertEqual(output.strip(), "Warning: Ignoring Control Plane ACL NTP_ACL without type\n"
|
self.assertEqual(output.strip(), "Warning: Ignoring Control Plane ACL NTP_ACL without type\n"
|
||||||
"Warning: ignore interface 'fortyGigE0/2' as it is not in the port_config.ini\n"
|
|
||||||
"Warning: ignore interface 'fortyGigE0/2' in DEVICE_NEIGHBOR as it is not in the port_config.ini\n"
|
|
||||||
"{'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'stage': 'ingress'}, "
|
"{'NTP_ACL': {'services': ['NTP'], 'type': 'CTRLPLANE', 'policy_desc': 'NTP_ACL', 'stage': 'ingress'}, "
|
||||||
"'EVERFLOW': {'stage': 'ingress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOW'}, "
|
"'EVERFLOW': {'stage': 'ingress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOW'}, "
|
||||||
"'EVERFLOW_EGRESS': {'stage': 'egress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOW_EGRESS'}, "
|
"'EVERFLOW_EGRESS': {'stage': 'egress', 'type': 'MIRROR', 'ports': ['PortChannel01', 'PortChannel02', 'PortChannel03', 'PortChannel04', 'Ethernet4'], 'policy_desc': 'EVERFLOW_EGRESS'}, "
|
||||||
@ -191,7 +189,18 @@ class TestCfgGen(TestCase):
|
|||||||
def test_minigraph_port_description(self):
|
def test_minigraph_port_description(self):
|
||||||
argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet124\']"'
|
argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet124\']"'
|
||||||
output = self.run_script(argument)
|
output = self.run_script(argument)
|
||||||
self.assertEqual(output.strip(), "{'lanes': '101,102,103,104', 'description': 'ARISTA04T1:Ethernet1/1', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up'}")
|
self.assertEqual(output.strip(), "{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}")
|
||||||
|
|
||||||
|
def test_minigraph_port_fec_disabled(self):
|
||||||
|
# Test for FECDisabled
|
||||||
|
argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet4\']"'
|
||||||
|
output = self.run_script(argument)
|
||||||
|
self.assertEqual(output.strip(), "{'lanes': '25,26,27,28', 'description': 'Servers0:eth0', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/4', 'admin_status': 'up', 'speed': '100000'}")
|
||||||
|
|
||||||
|
def test_minigraph_port_rs(self):
|
||||||
|
argument = '-m "' + self.sample_graph_t0 + '" -p "' + self.port_config + '" -v "PORT[\'Ethernet124\']"'
|
||||||
|
output = self.run_script(argument)
|
||||||
|
self.assertEqual(output.strip(), "{'lanes': '101,102,103,104', 'fec': 'rs', 'pfc_asym': 'off', 'mtu': '9100', 'alias': 'fortyGigE0/124', 'admin_status': 'up', 'speed': '100000', 'description': 'ARISTA04T1:Ethernet1/1'}")
|
||||||
|
|
||||||
def test_minigraph_bgp(self):
|
def test_minigraph_bgp(self):
|
||||||
argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v "BGP_NEIGHBOR[\'10.0.0.59\']"'
|
argument = '-m "' + self.sample_graph_bgp_speaker + '" -p "' + self.port_config + '" -v "BGP_NEIGHBOR[\'10.0.0.59\']"'
|
||||||
|
Reference in New Issue
Block a user