[minigraph][dualtor] Support parsing soc_ip
out of dpg (#11207)
Why I did it To further support parse out soc_ipv4 and soc_ipv6 out of Dpg: <DeviceDataPlaneInfo> <IPSecTunnels /> <LoopbackIPInterfaces xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"> <a:LoopbackIPInterface> <ElementType>LoopbackInterface</ElementType> <Name>HostIP</Name> <AttachTo>Loopback0</AttachTo> <a:Prefix xmlns:b="Microsoft.Search.Autopilot.NetMux"> <b:IPPrefix>10.10.10.2/32</b:IPPrefix> </a:Prefix> <a:PrefixStr>10.10.10.2/32</a:PrefixStr> </a:LoopbackIPInterface> <a:LoopbackIPInterface> <ElementType>LoopbackInterface</ElementType> <Name>HostIP1</Name> <AttachTo>Loopback0</AttachTo> <a:Prefix xmlns:b="Microsoft.Search.Autopilot.NetMux"> <b:IPPrefix>fe80::0002/128</b:IPPrefix> </a:Prefix> <a:PrefixStr>fe80::0002/128</a:PrefixStr> </a:LoopbackIPInterface> <a:LoopbackIPInterface> <ElementType>LoopbackInterface</ElementType> <Name>SoCHostIP0</Name> <AttachTo>server2SOC</AttachTo> <a:Prefix xmlns:b="Microsoft.Search.Autopilot.NetMux"> <b:IPPrefix>10.10.10.3/32</b:IPPrefix> </a:Prefix> <a:PrefixStr>10.10.10.3/32</a:PrefixStr> </a:LoopbackIPInterface> <a:LoopbackIPInterface> <ElementType>LoopbackInterface</ElementType> <Name>SoCHostIP1</Name> <AttachTo>server2SOC</AttachTo> <a:Prefix xmlns:b="Microsoft.Search.Autopilot.NetMux"> <b:IPPrefix>fe80::0003/128</b:IPPrefix> </a:Prefix> <a:PrefixStr>fe80::0003/128</a:PrefixStr> </a:LoopbackIPInterface> </LoopbackIPInterfaces> </DeviceDataPlaneInfo> Signed-off-by: Longxiang Lyu lolv@microsoft.com How I did it For servers loopback definitions in Dpg, if they contain LoopbackIPInterface with tags AttachTo, which has value of format like <server_name>SOC, the address will be regarded as a SoC IP, and sonic-cfggen now will treat the port connected to the server as active-active if the redundancy_type is either Libra or Mixed. How to verify it Pass the unittest. Signed-off-by: Longxiang Lyu <lolv@microsoft.com>
This commit is contained in:
parent
ebe4a84eee
commit
b9a7665662
@ -185,6 +185,7 @@ def formulate_fine_grained_ecmp(version, dpg_ecmp_content, port_device_map, port
|
|||||||
fine_grained_content = {"FG_NHG_MEMBER": FG_NHG_MEMBER, "FG_NHG": FG_NHG, "NEIGH": NEIGH}
|
fine_grained_content = {"FG_NHG_MEMBER": FG_NHG_MEMBER, "FG_NHG": FG_NHG, "NEIGH": NEIGH}
|
||||||
return fine_grained_content
|
return fine_grained_content
|
||||||
|
|
||||||
|
|
||||||
def parse_png(png, hname, dpg_ecmp_content = None):
|
def parse_png(png, hname, dpg_ecmp_content = None):
|
||||||
neighbors = {}
|
neighbors = {}
|
||||||
devices = {}
|
devices = {}
|
||||||
@ -400,9 +401,9 @@ def parse_asic_png(png, asic_name, hostname):
|
|||||||
device_data['lo_addr_v6']= lo_prefix_v6
|
device_data['lo_addr_v6']= lo_prefix_v6
|
||||||
devices[name] = device_data
|
devices[name] = device_data
|
||||||
|
|
||||||
|
|
||||||
return (neighbors, devices, port_speeds)
|
return (neighbors, devices, port_speeds)
|
||||||
|
|
||||||
|
|
||||||
def parse_loopback_intf(child):
|
def parse_loopback_intf(child):
|
||||||
lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces")))
|
lointfs = child.find(str(QName(ns, "LoopbackIPInterfaces")))
|
||||||
lo_intfs = {}
|
lo_intfs = {}
|
||||||
@ -412,6 +413,7 @@ def parse_loopback_intf(child):
|
|||||||
lo_intfs[(intfname, ipprefix)] = {}
|
lo_intfs[(intfname, ipprefix)] = {}
|
||||||
return lo_intfs
|
return lo_intfs
|
||||||
|
|
||||||
|
|
||||||
def parse_dpg(dpg, hname):
|
def parse_dpg(dpg, hname):
|
||||||
aclintfs = None
|
aclintfs = None
|
||||||
mgmtintfs = None
|
mgmtintfs = None
|
||||||
@ -455,7 +457,7 @@ def parse_dpg(dpg, hname):
|
|||||||
ipprefix = ipintf.find(str(QName(ns, "Prefix"))).text
|
ipprefix = ipintf.find(str(QName(ns, "Prefix"))).text
|
||||||
intfs[(intfname, ipprefix)] = {}
|
intfs[(intfname, ipprefix)] = {}
|
||||||
ip_intfs_map[ipprefix] = intfalias
|
ip_intfs_map[ipprefix] = intfalias
|
||||||
lo_intfs = parse_loopback_intf(child)
|
lo_intfs = parse_loopback_intf(child)
|
||||||
|
|
||||||
subintfs = child.find(str(QName(ns, "SubInterfaces")))
|
subintfs = child.find(str(QName(ns, "SubInterfaces")))
|
||||||
if subintfs is not None:
|
if subintfs is not None:
|
||||||
@ -757,7 +759,6 @@ def parse_dpg(dpg, hname):
|
|||||||
return None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None
|
return None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def parse_host_loopback(dpg, hname):
|
def parse_host_loopback(dpg, hname):
|
||||||
for child in dpg:
|
for child in dpg:
|
||||||
hostname = child.find(str(QName(ns, "Hostname")))
|
hostname = child.find(str(QName(ns, "Hostname")))
|
||||||
@ -766,6 +767,7 @@ def parse_host_loopback(dpg, hname):
|
|||||||
lo_intfs = parse_loopback_intf(child)
|
lo_intfs = parse_loopback_intf(child)
|
||||||
return lo_intfs
|
return lo_intfs
|
||||||
|
|
||||||
|
|
||||||
def parse_cpg(cpg, hname, local_devices=[]):
|
def parse_cpg(cpg, hname, local_devices=[]):
|
||||||
bgp_sessions = {}
|
bgp_sessions = {}
|
||||||
bgp_internal_sessions = {}
|
bgp_internal_sessions = {}
|
||||||
@ -891,6 +893,7 @@ def parse_meta(meta, hname):
|
|||||||
max_cores = None
|
max_cores = None
|
||||||
kube_data = {}
|
kube_data = {}
|
||||||
macsec_profile = {}
|
macsec_profile = {}
|
||||||
|
redundancy_type = None
|
||||||
device_metas = meta.find(str(QName(ns, "Devices")))
|
device_metas = meta.find(str(QName(ns, "Devices")))
|
||||||
for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))):
|
for device in device_metas.findall(str(QName(ns1, "DeviceMetadata"))):
|
||||||
if device.find(str(QName(ns1, "Name"))).text.lower() == hname.lower():
|
if device.find(str(QName(ns1, "Name"))).text.lower() == hname.lower():
|
||||||
@ -933,7 +936,9 @@ def parse_meta(meta, hname):
|
|||||||
kube_data["ip"] = value
|
kube_data["ip"] = value
|
||||||
elif name == 'MacSecProfile':
|
elif name == 'MacSecProfile':
|
||||||
macsec_profile = parse_macsec_profile(value)
|
macsec_profile = parse_macsec_profile(value)
|
||||||
return syslog_servers, dhcp_servers, dhcpv6_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, macsec_profile
|
elif name == "RedundancyType":
|
||||||
|
redundancy_type = value
|
||||||
|
return syslog_servers, dhcp_servers, dhcpv6_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, macsec_profile, redundancy_type
|
||||||
|
|
||||||
|
|
||||||
def parse_system_defaults(meta):
|
def parse_system_defaults(meta):
|
||||||
@ -1313,6 +1318,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
|
|||||||
static_routes = {}
|
static_routes = {}
|
||||||
system_defaults = {}
|
system_defaults = {}
|
||||||
macsec_profile = {}
|
macsec_profile = {}
|
||||||
|
redundancy_type = None
|
||||||
|
|
||||||
hwsku_qn = QName(ns, "HwSku")
|
hwsku_qn = QName(ns, "HwSku")
|
||||||
hostname_qn = QName(ns, "Hostname")
|
hostname_qn = QName(ns, "Hostname")
|
||||||
@ -1343,7 +1349,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
|
|||||||
elif child.tag == str(QName(ns, "UngDec")):
|
elif child.tag == str(QName(ns, "UngDec")):
|
||||||
(u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname, None)
|
(u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname, None)
|
||||||
elif child.tag == str(QName(ns, "MetadataDeclaration")):
|
elif child.tag == str(QName(ns, "MetadataDeclaration")):
|
||||||
(syslog_servers, dhcp_servers, dhcpv6_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, macsec_profile) = parse_meta(child, hostname)
|
(syslog_servers, dhcp_servers, dhcpv6_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, macsec_profile, redundancy_type) = parse_meta(child, hostname)
|
||||||
elif child.tag == str(QName(ns, "LinkMetadataDeclaration")):
|
elif child.tag == str(QName(ns, "LinkMetadataDeclaration")):
|
||||||
linkmetas = parse_linkmeta(child, hostname)
|
linkmetas = parse_linkmeta(child, hostname)
|
||||||
elif child.tag == str(QName(ns, "DeviceInfos")):
|
elif child.tag == str(QName(ns, "DeviceInfos")):
|
||||||
@ -1567,11 +1573,6 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
|
|||||||
if macsec_enabled and 'PrimaryKey' in macsec_profile:
|
if macsec_enabled and 'PrimaryKey' in macsec_profile:
|
||||||
port['macsec'] = macsec_profile['PrimaryKey']
|
port['macsec'] = macsec_profile['PrimaryKey']
|
||||||
|
|
||||||
# If connected to a smart cable, get the connection position
|
|
||||||
for port_name, port in ports.items():
|
|
||||||
if port_name in mux_cable_ports:
|
|
||||||
port['mux_cable'] = "true"
|
|
||||||
|
|
||||||
# set port description if parsed from deviceinfo
|
# set port description if parsed from deviceinfo
|
||||||
for port_name in port_descriptions:
|
for port_name in port_descriptions:
|
||||||
# ignore port not in port_config.ini
|
# ignore port not in port_config.ini
|
||||||
@ -1713,7 +1714,13 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
|
|||||||
# Add src_ip and qos remapping config into TUNNEL table if tunnel_qos_remap is enabled
|
# Add src_ip and qos remapping config into TUNNEL table if tunnel_qos_remap is enabled
|
||||||
results['TUNNEL'] = get_tunnel_entries(tunnel_intfs, tunnel_intfs_qos_remap_config, lo_intfs, system_defaults.get('tunnel_qos_remap', {}), mux_tunnel_name, peer_switch_ip)
|
results['TUNNEL'] = get_tunnel_entries(tunnel_intfs, tunnel_intfs_qos_remap_config, lo_intfs, system_defaults.get('tunnel_qos_remap', {}), mux_tunnel_name, peer_switch_ip)
|
||||||
|
|
||||||
results['MUX_CABLE'] = get_mux_cable_entries(mux_cable_ports, neighbors, devices)
|
active_active_ports = get_ports_in_active_active(root, devices, neighbors)
|
||||||
|
results['MUX_CABLE'] = get_mux_cable_entries(ports, mux_cable_ports, active_active_ports, neighbors, devices, redundancy_type)
|
||||||
|
|
||||||
|
# If connected to a smart cable, get the connection position
|
||||||
|
for port_name, port in results['PORT'].items():
|
||||||
|
if port_name in results['MUX_CABLE']:
|
||||||
|
port['mux_cable'] = "true"
|
||||||
|
|
||||||
if static_routes:
|
if static_routes:
|
||||||
results['STATIC_ROUTE'] = static_routes
|
results['STATIC_ROUTE'] = static_routes
|
||||||
@ -1826,46 +1833,76 @@ def get_tunnel_entries(tunnel_intfs, tunnel_intfs_qos_remap_config, lo_intfs, tu
|
|||||||
|
|
||||||
return tunnels
|
return tunnels
|
||||||
|
|
||||||
def get_mux_cable_entries(mux_cable_ports, neighbors, devices):
|
|
||||||
mux_cable_table = {}
|
|
||||||
|
|
||||||
for intf, cable_name in mux_cable_ports.items():
|
def get_ports_in_active_active(root, devices, neighbors):
|
||||||
if intf in neighbors:
|
"""Parse out ports in active-active cable type."""
|
||||||
entry = {}
|
servers = {hostname.lower(): device_data for hostname, device_data in devices.items() if device_data["type"] == "Server"}
|
||||||
neighbor = neighbors[intf]['name']
|
ports_in_active_active = {}
|
||||||
entry['state'] = 'auto'
|
dpg_section = root.find(str(QName(ns, "DpgDec")))
|
||||||
|
neighbor_to_port_mapping = {neighbor["name"].lower(): port for port, neighbor in neighbors.items()}
|
||||||
if devices[neighbor]['lo_addr'] is not None:
|
if dpg_section is not None:
|
||||||
# Always force a /32 prefix for server IPv4 loopbacks
|
for child in dpg_section:
|
||||||
server_ipv4_lo_addr = devices[neighbor]['lo_addr'].split("/")[0]
|
hostname = child.find(str(QName(ns, "Hostname")))
|
||||||
server_ipv4_lo_prefix = ipaddress.ip_network(UNICODE_TYPE(server_ipv4_lo_addr))
|
if hostname is None:
|
||||||
entry['server_ipv4'] = str(server_ipv4_lo_prefix)
|
|
||||||
|
|
||||||
if 'lo_addr_v6' in devices[neighbor] and devices[neighbor]['lo_addr_v6'] is not None:
|
|
||||||
server_ipv6_lo_addr = devices[neighbor]['lo_addr_v6'].split('/')[0]
|
|
||||||
server_ipv6_lo_prefix = ipaddress.ip_network(UNICODE_TYPE(server_ipv6_lo_addr))
|
|
||||||
entry['server_ipv6'] = str(server_ipv6_lo_prefix)
|
|
||||||
mux_cable_table[intf] = entry
|
|
||||||
else:
|
|
||||||
print("Warning: no server IPv4 loopback found for {}, skipping mux cable table entry".format(neighbor), file=sys.stderr)
|
|
||||||
|
|
||||||
if cable_name in devices:
|
|
||||||
cable_type = devices[cable_name].get('subtype')
|
|
||||||
if cable_type is None:
|
|
||||||
continue
|
continue
|
||||||
if cable_type in dualtor_cable_types:
|
hostname = hostname.text.lower()
|
||||||
mux_cable_table[intf]['cable_type'] = cable_type
|
if hostname not in servers:
|
||||||
if cable_type == 'active-active':
|
continue
|
||||||
soc_ipv4 = devices[cable_name]['lo_addr'].split('/')[0]
|
lo_intfs = parse_loopback_intf(child)
|
||||||
soc_ipv4_prefix = ipaddress.ip_network(UNICODE_TYPE(soc_ipv4))
|
soc_intfs = {}
|
||||||
mux_cable_table[intf]['soc_ipv4'] = str(soc_ipv4_prefix)
|
for intfname, ipprefix in lo_intfs.keys():
|
||||||
else:
|
intfname_lower = intfname.lower()
|
||||||
print("Warning: skip parsing device %s for mux cable entry, cable type %s not supported" % (cable_name, cable_type), file=sys.stderr)
|
if hostname + "soc" == intfname_lower:
|
||||||
|
ipprefix = str(ipaddress.ip_network(UNICODE_TYPE(ipprefix.split("/")[0])))
|
||||||
|
if "." in ipprefix:
|
||||||
|
soc_intfs["soc_ipv4"] = ipprefix
|
||||||
|
elif ":" in ipprefix:
|
||||||
|
soc_intfs["soc_ipv6"] = ipprefix
|
||||||
|
if hostname in neighbor_to_port_mapping and soc_intfs:
|
||||||
|
ports_in_active_active[neighbor_to_port_mapping[hostname]] = soc_intfs
|
||||||
|
return ports_in_active_active
|
||||||
|
|
||||||
|
|
||||||
|
def get_mux_cable_entries(ports, mux_cable_ports, active_active_ports, neighbors, devices, redundancy_type):
|
||||||
|
mux_cable_table = {}
|
||||||
|
if redundancy_type:
|
||||||
|
redundancy_type = redundancy_type.lower()
|
||||||
|
|
||||||
|
for port in ports:
|
||||||
|
is_active_active = redundancy_type in ("libra", "mixed") and port in active_active_ports
|
||||||
|
is_active_standby = port in mux_cable_ports
|
||||||
|
if is_active_active and is_active_standby:
|
||||||
|
print("Warning: skip %s as it is defined as active-standby and actie-active" % port, file=sys.stderr)
|
||||||
|
continue
|
||||||
|
if not (is_active_active or is_active_standby):
|
||||||
|
continue
|
||||||
|
|
||||||
|
entry = {}
|
||||||
|
neighbor = neighbors[port]['name']
|
||||||
|
entry['state'] = 'auto'
|
||||||
|
|
||||||
|
if devices[neighbor]['lo_addr'] is not None:
|
||||||
|
# Always force a /32 prefix for server IPv4 loopbacks
|
||||||
|
server_ipv4_lo_addr = devices[neighbor]['lo_addr'].split("/")[0]
|
||||||
|
server_ipv4_lo_prefix = ipaddress.ip_network(UNICODE_TYPE(server_ipv4_lo_addr))
|
||||||
|
entry['server_ipv4'] = str(server_ipv4_lo_prefix)
|
||||||
|
|
||||||
|
if 'lo_addr_v6' in devices[neighbor] and devices[neighbor]['lo_addr_v6'] is not None:
|
||||||
|
server_ipv6_lo_addr = devices[neighbor]['lo_addr_v6'].split('/')[0]
|
||||||
|
server_ipv6_lo_prefix = ipaddress.ip_network(UNICODE_TYPE(server_ipv6_lo_addr))
|
||||||
|
entry['server_ipv6'] = str(server_ipv6_lo_prefix)
|
||||||
|
|
||||||
|
if is_active_active:
|
||||||
|
entry['cable_type'] = 'active-active'
|
||||||
|
entry.update(active_active_ports[port])
|
||||||
|
|
||||||
|
mux_cable_table[port] = entry
|
||||||
else:
|
else:
|
||||||
print("Warning: skip parsing device %s for mux cable entry, device definition not found" % cable_name, file=sys.stderr)
|
print("Warning: no server IPv4 loopback found for {}, skipping mux cable table entry".format(neighbor), file=sys.stderr)
|
||||||
|
|
||||||
return mux_cable_table
|
return mux_cable_table
|
||||||
|
|
||||||
|
|
||||||
def parse_device_desc_xml(filename):
|
def parse_device_desc_xml(filename):
|
||||||
root = ET.parse(filename).getroot()
|
root = ET.parse(filename).getroot()
|
||||||
(lo_prefix, lo_prefix_v6, mgmt_prefix, mgmt_prefix_v6, hostname, hwsku, d_type, _, _, _) = parse_device(root)
|
(lo_prefix, lo_prefix_v6, mgmt_prefix, mgmt_prefix_v6, hostname, hwsku, d_type, _, _, _) = parse_device(root)
|
||||||
|
@ -198,6 +198,62 @@
|
|||||||
<DownstreamSummaries/>
|
<DownstreamSummaries/>
|
||||||
<DownstreamSummarySet xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
|
<DownstreamSummarySet xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
|
||||||
</DeviceDataPlaneInfo>
|
</DeviceDataPlaneInfo>
|
||||||
|
<DeviceDataPlaneInfo>
|
||||||
|
<IPSecTunnels />
|
||||||
|
<LoopbackIPInterfaces xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution">
|
||||||
|
<a:LoopbackIPInterface>
|
||||||
|
<ElementType>LoopbackInterface</ElementType>
|
||||||
|
<Name>HostIP</Name>
|
||||||
|
<AttachTo>Loopback0</AttachTo>
|
||||||
|
<a:Prefix xmlns:b="Microsoft.Search.Autopilot.NetMux">
|
||||||
|
<b:IPPrefix>10.10.10.2/32</b:IPPrefix>
|
||||||
|
</a:Prefix>
|
||||||
|
<a:PrefixStr>10.10.10.2/32</a:PrefixStr>
|
||||||
|
</a:LoopbackIPInterface>
|
||||||
|
<a:LoopbackIPInterface>
|
||||||
|
<ElementType>LoopbackInterface</ElementType>
|
||||||
|
<Name>HostIP1</Name>
|
||||||
|
<AttachTo>Loopback0</AttachTo>
|
||||||
|
<a:Prefix xmlns:b="Microsoft.Search.Autopilot.NetMux">
|
||||||
|
<b:IPPrefix>fe80::0002/128</b:IPPrefix>
|
||||||
|
</a:Prefix>
|
||||||
|
<a:PrefixStr>fe80::0002/128</a:PrefixStr>
|
||||||
|
</a:LoopbackIPInterface>
|
||||||
|
<a:LoopbackIPInterface>
|
||||||
|
<ElementType>LoopbackInterface</ElementType>
|
||||||
|
<Name>SoCHostIP0</Name>
|
||||||
|
<AttachTo>server2SOC</AttachTo>
|
||||||
|
<a:Prefix xmlns:b="Microsoft.Search.Autopilot.NetMux">
|
||||||
|
<b:IPPrefix>10.10.10.3/32</b:IPPrefix>
|
||||||
|
</a:Prefix>
|
||||||
|
<a:PrefixStr>10.10.10.3/32</a:PrefixStr>
|
||||||
|
</a:LoopbackIPInterface>
|
||||||
|
<a:LoopbackIPInterface>
|
||||||
|
<ElementType>LoopbackInterface</ElementType>
|
||||||
|
<Name>SoCHostIP1</Name>
|
||||||
|
<AttachTo>server2SOC</AttachTo>
|
||||||
|
<a:Prefix xmlns:b="Microsoft.Search.Autopilot.NetMux">
|
||||||
|
<b:IPPrefix>fe80::0003/128</b:IPPrefix>
|
||||||
|
</a:Prefix>
|
||||||
|
<a:PrefixStr>fe80::0003/128</a:PrefixStr>
|
||||||
|
</a:LoopbackIPInterface>
|
||||||
|
</LoopbackIPInterfaces>
|
||||||
|
<ManagementIPInterfaces xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution" />
|
||||||
|
<ManagementVIPInterfaces xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution" />
|
||||||
|
<MplsInterfaces />
|
||||||
|
<MplsTeInterfaces />
|
||||||
|
<RsvpInterfaces />
|
||||||
|
<Hostname>server2</Hostname>
|
||||||
|
<PortChannelInterfaces />
|
||||||
|
<SubInterfaces />
|
||||||
|
<VlanInterfaces />
|
||||||
|
<IPInterfaces />
|
||||||
|
<DataAcls />
|
||||||
|
<AclInterfaces />
|
||||||
|
<NatInterfaces xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution" />
|
||||||
|
<DownstreamSummaries />
|
||||||
|
<DownstreamSummarySet xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution" />
|
||||||
|
</DeviceDataPlaneInfo>
|
||||||
</DpgDec>
|
</DpgDec>
|
||||||
<PngDec>
|
<PngDec>
|
||||||
<DeviceInterfaceLinks>
|
<DeviceInterfaceLinks>
|
||||||
@ -262,17 +318,6 @@
|
|||||||
<StartPort>L</StartPort>
|
<StartPort>L</StartPort>
|
||||||
<Validate>true</Validate>
|
<Validate>true</Validate>
|
||||||
</DeviceLinkBase>
|
</DeviceLinkBase>
|
||||||
<DeviceLinkBase i:type="LogicalLink">
|
|
||||||
<ElementType>LogicalLink</ElementType>
|
|
||||||
<Bandwidth>10000</Bandwidth>
|
|
||||||
<ChassisInternal>false</ChassisInternal>
|
|
||||||
<EndDevice>switch-t0</EndDevice>
|
|
||||||
<EndPort>fortyGigE0/8</EndPort>
|
|
||||||
<FlowControl>true</FlowControl>
|
|
||||||
<StartDevice>server2-SC</StartDevice>
|
|
||||||
<StartPort>U</StartPort>
|
|
||||||
<Validate>true</Validate>
|
|
||||||
</DeviceLinkBase>
|
|
||||||
<DeviceLinkBase i:type="LogicalLink">
|
<DeviceLinkBase i:type="LogicalLink">
|
||||||
<ElementType>LogicalLink</ElementType>
|
<ElementType>LogicalLink</ElementType>
|
||||||
<Bandwidth>0</Bandwidth>
|
<Bandwidth>0</Bandwidth>
|
||||||
@ -349,25 +394,6 @@
|
|||||||
<Hostname>server1</Hostname>
|
<Hostname>server1</Hostname>
|
||||||
<HwSku>server-sku</HwSku>
|
<HwSku>server-sku</HwSku>
|
||||||
</Device>
|
</Device>
|
||||||
<Device i:type="SmartCable">
|
|
||||||
<ElementType>SmartCable</ElementType>
|
|
||||||
<SubType>active-active</SubType>
|
|
||||||
<Address xmlns:d5p1="Microsoft.Search.Autopilot.NetMux">
|
|
||||||
<d5p1:IPPrefix>10.10.10.3/32</d5p1:IPPrefix>
|
|
||||||
</Address>
|
|
||||||
<AddressV6 xmlns:d5p1="Microsoft.Search.Autopilot.NetMux">
|
|
||||||
<d5p1:IPPrefix>::/0</d5p1:IPPrefix>
|
|
||||||
</AddressV6>
|
|
||||||
<ManagementAddress xmlns:d5p1="Microsoft.Search.Autopilot.NetMux">
|
|
||||||
<d5p1:IPPrefix>0.0.0.0/0</d5p1:IPPrefix>
|
|
||||||
</ManagementAddress>
|
|
||||||
<ManagementAddressV6 xmlns:d5p1="Microsoft.Search.Autopilot.NetMux">
|
|
||||||
<d5p1:IPPrefix>::/0</d5p1:IPPrefix>
|
|
||||||
</ManagementAddressV6>
|
|
||||||
<SerialNumber i:nil="true" />
|
|
||||||
<Hostname>server2-SC</Hostname>
|
|
||||||
<HwSku>smartcable-sku</HwSku>
|
|
||||||
</Device>
|
|
||||||
<Device i:type="Server">
|
<Device i:type="Server">
|
||||||
<ElementType>Server</ElementType>
|
<ElementType>Server</ElementType>
|
||||||
<Address xmlns:d5p1="Microsoft.Search.Autopilot.NetMux">
|
<Address xmlns:d5p1="Microsoft.Search.Autopilot.NetMux">
|
||||||
@ -506,6 +532,11 @@
|
|||||||
<a:Reference i:nil="true"/>
|
<a:Reference i:nil="true"/>
|
||||||
<a:Value>Storage</a:Value>
|
<a:Value>Storage</a:Value>
|
||||||
</a:DeviceProperty>
|
</a:DeviceProperty>
|
||||||
|
<a:DeviceProperty>
|
||||||
|
<a:Name>RedundancyType</a:Name>
|
||||||
|
<a:Reference i:nil="true"/>
|
||||||
|
<a:Value>Mixed</a:Value>
|
||||||
|
</a:DeviceProperty>
|
||||||
</a:Properties>
|
</a:Properties>
|
||||||
</a:DeviceMetadata>
|
</a:DeviceMetadata>
|
||||||
</Devices>
|
</Devices>
|
||||||
|
@ -236,14 +236,6 @@ class TestCfgGenCaseInsensitive(TestCase):
|
|||||||
'lo_addr_v6': '::/0',
|
'lo_addr_v6': '::/0',
|
||||||
'mgmt_addr': '0.0.0.0/0',
|
'mgmt_addr': '0.0.0.0/0',
|
||||||
'type': 'SmartCable'
|
'type': 'SmartCable'
|
||||||
},
|
|
||||||
'server2-SC': {
|
|
||||||
'hwsku': 'smartcable-sku',
|
|
||||||
'lo_addr': '10.10.10.3/32',
|
|
||||||
'lo_addr_v6': '::/0',
|
|
||||||
'mgmt_addr': '0.0.0.0/0',
|
|
||||||
'type': 'SmartCable',
|
|
||||||
'subtype': 'active-active'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output = self.run_script(argument)
|
output = self.run_script(argument)
|
||||||
@ -421,6 +413,7 @@ class TestCfgGenCaseInsensitive(TestCase):
|
|||||||
'server_ipv4': '10.10.10.2/32',
|
'server_ipv4': '10.10.10.2/32',
|
||||||
'server_ipv6': 'fe80::2/128',
|
'server_ipv6': 'fe80::2/128',
|
||||||
'soc_ipv4': '10.10.10.3/32',
|
'soc_ipv4': '10.10.10.3/32',
|
||||||
|
'soc_ipv6': 'fe80::3/128',
|
||||||
'cable_type': 'active-active'
|
'cable_type': 'active-active'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user