[cherry-pick][201811][minigraph] Support parse IPv6 in device_desc.xml (#11332)
Signed-off-by: Jing Kan jika@microsoft.com
This commit is contained in:
parent
beb9eac1c7
commit
da636794af
@ -44,6 +44,7 @@ class minigraph_encoder(json.JSONEncoder):
|
|||||||
def parse_device(device):
|
def parse_device(device):
|
||||||
lo_prefix = None
|
lo_prefix = None
|
||||||
mgmt_prefix = None
|
mgmt_prefix = None
|
||||||
|
mgmt_prefix_v6 = None
|
||||||
d_type = None # don't shadow type()
|
d_type = None # don't shadow type()
|
||||||
hwsku = None
|
hwsku = None
|
||||||
name = None
|
name = None
|
||||||
@ -56,13 +57,15 @@ def parse_device(device):
|
|||||||
lo_prefix = node.find(str(QName(ns2, "IPPrefix"))).text
|
lo_prefix = node.find(str(QName(ns2, "IPPrefix"))).text
|
||||||
elif node.tag == str(QName(ns, "ManagementAddress")):
|
elif node.tag == str(QName(ns, "ManagementAddress")):
|
||||||
mgmt_prefix = node.find(str(QName(ns2, "IPPrefix"))).text
|
mgmt_prefix = node.find(str(QName(ns2, "IPPrefix"))).text
|
||||||
|
elif node.tag == str(QName(ns, "ManagementAddressV6")):
|
||||||
|
mgmt_prefix_v6 = node.find(str(QName(ns2, "IPPrefix"))).text
|
||||||
elif node.tag == str(QName(ns, "Hostname")):
|
elif node.tag == str(QName(ns, "Hostname")):
|
||||||
name = node.text
|
name = node.text
|
||||||
elif node.tag == str(QName(ns, "HwSku")):
|
elif node.tag == str(QName(ns, "HwSku")):
|
||||||
hwsku = node.text
|
hwsku = node.text
|
||||||
elif node.tag == str(QName(ns, "DeploymentId")):
|
elif node.tag == str(QName(ns, "DeploymentId")):
|
||||||
deployment_id = node.text
|
deployment_id = node.text
|
||||||
return (lo_prefix, mgmt_prefix, name, hwsku, d_type, deployment_id)
|
return (lo_prefix, mgmt_prefix, mgmt_prefix_v6, name, hwsku, d_type, deployment_id)
|
||||||
|
|
||||||
def parse_png(png, hname):
|
def parse_png(png, hname):
|
||||||
neighbors = {}
|
neighbors = {}
|
||||||
@ -125,7 +128,7 @@ def parse_png(png, hname):
|
|||||||
|
|
||||||
if child.tag == str(QName(ns, "Devices")):
|
if child.tag == str(QName(ns, "Devices")):
|
||||||
for device in child.findall(str(QName(ns, "Device"))):
|
for device in child.findall(str(QName(ns, "Device"))):
|
||||||
(lo_prefix, mgmt_prefix, name, hwsku, d_type, deployment_id) = parse_device(device)
|
(lo_prefix, mgmt_prefix, mgmt_prefix_v6, name, hwsku, d_type, deployment_id) = parse_device(device)
|
||||||
device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku }
|
device_data = {'lo_addr': lo_prefix, 'type': d_type, 'mgmt_addr': mgmt_prefix, 'hwsku': hwsku }
|
||||||
if deployment_id:
|
if deployment_id:
|
||||||
device_data['deployment_id'] = deployment_id
|
device_data['deployment_id'] = deployment_id
|
||||||
@ -805,7 +808,7 @@ def parse_xml(filename, platform=None, port_config_file=None):
|
|||||||
|
|
||||||
def parse_device_desc_xml(filename):
|
def parse_device_desc_xml(filename):
|
||||||
root = ET.parse(filename).getroot()
|
root = ET.parse(filename).getroot()
|
||||||
(lo_prefix, mgmt_prefix, hostname, hwsku, d_type, _) = parse_device(root)
|
(lo_prefix, mgmt_prefix, mgmt_prefix_v6, hostname, hwsku, d_type, _) = parse_device(root)
|
||||||
|
|
||||||
results = {}
|
results = {}
|
||||||
results['DEVICE_METADATA'] = {'localhost': {
|
results['DEVICE_METADATA'] = {'localhost': {
|
||||||
@ -815,10 +818,18 @@ def parse_device_desc_xml(filename):
|
|||||||
|
|
||||||
results['LOOPBACK_INTERFACE'] = {('lo', lo_prefix): {}}
|
results['LOOPBACK_INTERFACE'] = {('lo', lo_prefix): {}}
|
||||||
|
|
||||||
mgmt_intf = {}
|
results['MGMT_INTERFACE'] = {}
|
||||||
mgmtipn = ipaddress.IPNetwork(mgmt_prefix)
|
if mgmt_prefix:
|
||||||
gwaddr = ipaddress.IPAddress(int(mgmtipn.network) + 1)
|
mgmtipn = ipaddress.IPNetwork(mgmt_prefix)
|
||||||
results['MGMT_INTERFACE'] = {('eth0', mgmt_prefix): {'gwaddr': gwaddr}}
|
if mgmtipn != ipaddress.IPNetwork('0.0.0.0/0'):
|
||||||
|
gwaddr = ipaddress.IPAddress(int(mgmtipn.network) + 1)
|
||||||
|
results['MGMT_INTERFACE'].update({('eth0', mgmt_prefix): {'gwaddr': gwaddr}})
|
||||||
|
|
||||||
|
if mgmt_prefix_v6:
|
||||||
|
mgmtipn_v6 = ipaddress.IPNetwork(mgmt_prefix_v6)
|
||||||
|
if mgmtipn != ipaddress.IPNetwork('::/0'):
|
||||||
|
gwaddr_v6 = ipaddress.IPAddress(int(mgmtipn_v6.network) + 1)
|
||||||
|
results['MGMT_INTERFACE'].update({('eth0', mgmt_prefix_v6): {'gwaddr': gwaddr_v6}})
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
<Device i:type="ToRRouter" xmlns="Microsoft.Search.Autopilot.Evolution" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<Hostname>switch-t0</Hostname>
|
||||||
|
<HwSku>Force10-S6000</HwSku>
|
||||||
|
<ClusterName>AAA00PrdStr00</ClusterName>
|
||||||
|
<ManagementAddress xmlns:a="Microsoft.Search.Autopilot.NetMux">
|
||||||
|
<a:IPPrefix>0.0.0.0/0</a:IPPrefix>
|
||||||
|
</ManagementAddress>
|
||||||
|
<ManagementAddressV6 xmlns:a="Microsoft.Search.Autopilot.NetMux">
|
||||||
|
<a:IPPrefix>FC00:1::32/64</a:IPPrefix>
|
||||||
|
</ManagementAddressV6>
|
||||||
|
</Device>
|
11
src/sonic-config-engine/tests/simple-sample-device-desc.xml
Normal file
11
src/sonic-config-engine/tests/simple-sample-device-desc.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<Device i:type="ToRRouter" xmlns="Microsoft.Search.Autopilot.Evolution" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<Hostname>switch-t0</Hostname>
|
||||||
|
<HwSku>Force10-S6000</HwSku>
|
||||||
|
<ClusterName>AAA00PrdStr00</ClusterName>
|
||||||
|
<ManagementAddress xmlns:a="Microsoft.Search.Autopilot.NetMux">
|
||||||
|
<a:IPPrefix>10.0.0.100/24</a:IPPrefix>
|
||||||
|
</ManagementAddress>
|
||||||
|
<ManagementAddressV6 xmlns:a="Microsoft.Search.Autopilot.NetMux">
|
||||||
|
<a:IPPrefix>FC00:1::32/64</a:IPPrefix>
|
||||||
|
</ManagementAddressV6>
|
||||||
|
</Device>
|
@ -1,13 +1,17 @@
|
|||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
import subprocess
|
import subprocess
|
||||||
import os
|
import os
|
||||||
|
import ipaddr as ipaddress
|
||||||
import minigraph
|
import minigraph
|
||||||
|
|
||||||
class TestCfgGenCaseInsensitive(TestCase):
|
class TestCfgGenCaseInsensitive(TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.test_dir = os.path.dirname(os.path.realpath(__file__))
|
self.test_dir = os.path.dirname(os.path.realpath(__file__))
|
||||||
self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen')
|
self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen')
|
||||||
self.sample_graph = os.path.join(self.test_dir, 'simple-sample-graph-case.xml')
|
self.sample_graph = os.path.join(self.test_dir, 'simple-sample-graph-case.xml')
|
||||||
|
self.sample_simple_device_desc = os.path.join(self.test_dir, 'simple-sample-device-desc.xml')
|
||||||
|
self.sample_simple_device_desc_ipv6_only = os.path.join(self.test_dir, 'simple-sample-device-desc-ipv6-only.xml')
|
||||||
self.port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini')
|
self.port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini')
|
||||||
|
|
||||||
def run_script(self, argument, check_stderr=False):
|
def run_script(self, argument, check_stderr=False):
|
||||||
@ -146,5 +150,20 @@ class TestCfgGenCaseInsensitive(TestCase):
|
|||||||
output.strip(),
|
output.strip(),
|
||||||
"{'Vlan1000': {'dhcpv6_servers': ['fc02:2000::1', 'fc02:2000::2']}}"
|
"{'Vlan1000': {'dhcpv6_servers': ['fc02:2000::1', 'fc02:2000::2']}}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_parse_device_desc_xml_mgmt_interface(self):
|
||||||
|
# Regular device_desc.xml with both IPv4 and IPv6 mgmt address
|
||||||
|
result = minigraph.parse_device_desc_xml(self.sample_simple_device_desc)
|
||||||
|
mgmt_intf = result['MGMT_INTERFACE']
|
||||||
|
self.assertEqual(len(mgmt_intf.keys()), 2)
|
||||||
|
self.assertTrue(('eth0', '10.0.0.100/24') in mgmt_intf.keys())
|
||||||
|
self.assertTrue(('eth0', 'FC00:1::32/64') in mgmt_intf.keys())
|
||||||
|
self.assertTrue(ipaddress.IPAddress('10.0.0.1') == mgmt_intf[('eth0', '10.0.0.100/24')]['gwaddr'])
|
||||||
|
self.assertTrue(ipaddress.IPAddress('fc00:1::1') == mgmt_intf[('eth0', 'FC00:1::32/64')]['gwaddr'])
|
||||||
|
|
||||||
|
# Special device_desc.xml with IPv6 mgmt address only
|
||||||
|
result = minigraph.parse_device_desc_xml(self.sample_simple_device_desc_ipv6_only)
|
||||||
|
mgmt_intf = result['MGMT_INTERFACE']
|
||||||
|
self.assertEqual(len(mgmt_intf.keys()), 1)
|
||||||
|
self.assertTrue(('eth0', 'FC00:1::32/64') in mgmt_intf.keys())
|
||||||
|
self.assertTrue(ipaddress.IPAddress('fc00:1::1') == mgmt_intf[('eth0', 'FC00:1::32/64')]['gwaddr'])
|
||||||
|
Reference in New Issue
Block a user