[sonic-cfggen]: Read ACL interfaces information from minigrap (#419)
* Enable translate_acl to read acl attaching from minigraph * Add AclInterfaces into test t0 graph * Expose minigraph_ports according
This commit is contained in:
parent
6a6bc88dcb
commit
bd77f9a38a
@ -124,6 +124,7 @@ def parse_dpg(dpg, hname):
|
||||
|
||||
ipintfs = child.find(str(QName(ns, "IPInterfaces")))
|
||||
intfs = []
|
||||
intfnames = {}
|
||||
vlan_map = {}
|
||||
pc_map = {}
|
||||
for ipintf in ipintfs.findall(str(QName(ns, "IPInterface"))):
|
||||
@ -177,6 +178,7 @@ def parse_dpg(dpg, hname):
|
||||
if peer_addr_val is not None:
|
||||
intf['peer_addr'] = ipaddress.IPAddress(peer_addr_val)
|
||||
intfs.append(intf)
|
||||
intfnames[intf['alias']] = { 'alias': intf['name'] }
|
||||
|
||||
pcintfs = child.find(str(QName(ns, "PortChannelInterfaces")))
|
||||
pc_intfs = []
|
||||
@ -237,10 +239,27 @@ def parse_dpg(dpg, hname):
|
||||
vlan_attributes.update(addrtuple)
|
||||
vlan_intfs.append(copy.deepcopy(vlan_attributes))
|
||||
vlans[vintfname] = vlan_attributes
|
||||
aclintfs = child.find(str(QName(ns, "AclInterfaces")))
|
||||
acls = {}
|
||||
for aclintf in aclintfs.findall(str(QName(ns, "AclInterface"))):
|
||||
aclname = aclintf.find(str(QName(ns, "InAcl"))).text
|
||||
aclattach = aclintf.find(str(QName(ns, "AttachTo"))).text.split(';')
|
||||
acl_intfs = []
|
||||
for member in aclattach:
|
||||
member = member.strip()
|
||||
if port_alias_map.has_key(member):
|
||||
member = port_alias_map[member]
|
||||
if pcs.has_key(member):
|
||||
acl_intfs.extend(pcs[member]['members']) # For ACL attaching to port channels, we break them into port channel members
|
||||
elif vlans.has_key(member):
|
||||
print >> sys.stderr, "Warning: ACL "+aclname+" is attached to a Vlan interface, which is currently not supported"
|
||||
elif intfnames.has_key(member):
|
||||
acl_intfs.append(member)
|
||||
if acl_intfs:
|
||||
acls[aclname] = acl_intfs
|
||||
|
||||
|
||||
return intfs, lo_intfs, mgmt_intf, vlan_intfs, pc_intfs, vlans, pcs
|
||||
return None, None, None, None, None
|
||||
return intfs, lo_intfs, mgmt_intf, vlan_intfs, pc_intfs, intfnames, vlans, pcs, acls
|
||||
return None, None, None, None, None, None, None, None
|
||||
|
||||
def parse_cpg(cpg, hname):
|
||||
bgp_sessions = []
|
||||
@ -394,7 +413,7 @@ def parse_xml(filename, platform=None, port_config_file=None):
|
||||
|
||||
for child in root:
|
||||
if child.tag == str(QName(ns, "DpgDec")):
|
||||
(intfs, lo_intfs, mgmt_intf, vlan_intfs, pc_intfs, vlans, pcs) = parse_dpg(child, hostname)
|
||||
(intfs, lo_intfs, mgmt_intf, vlan_intfs, pc_intfs, ports, vlans, pcs, acls) = parse_dpg(child, hostname)
|
||||
elif child.tag == str(QName(ns, "CpgDec")):
|
||||
(bgp_sessions, bgp_asn) = parse_cpg(child, hostname)
|
||||
elif child.tag == str(QName(ns, "PngDec")):
|
||||
@ -418,9 +437,11 @@ def parse_xml(filename, platform=None, port_config_file=None):
|
||||
results['minigraph_vlan_interfaces'] = vlan_intfs
|
||||
results['minigraph_portchannel_interfaces'] = pc_intfs
|
||||
results['minigraph_vlans'] = vlans
|
||||
results['minigraph_ports'] = ports
|
||||
results['minigraph_portchannels'] = pcs
|
||||
results['minigraph_mgmt_interface'] = mgmt_intf
|
||||
results['minigraph_lo_interfaces'] = lo_intfs
|
||||
results['minigraph_acls'] = acls
|
||||
results['minigraph_neighbors'] = neighbors
|
||||
results['minigraph_devices'] = devices
|
||||
results['minigraph_underlay_neighbors'] = u_neighbors
|
||||
|
@ -251,7 +251,14 @@
|
||||
</IPInterface>
|
||||
</IPInterfaces>
|
||||
<DataAcls/>
|
||||
<AclInterfaces/>
|
||||
<AclInterfaces>
|
||||
<AclInterface>
|
||||
<AttachTo>
|
||||
PortChannel01;PortChannel02;PortChannel03;PortChannel04
|
||||
</AttachTo>
|
||||
<InAcl>DataAcl</InAcl>
|
||||
</AclInterface>
|
||||
</AclInterfaces>
|
||||
<DownstreamSummaries/>
|
||||
<DownstreamSummarySet xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
|
||||
</DeviceDataPlaneInfo>
|
||||
|
@ -8,6 +8,7 @@ class TestCfgGen(TestCase):
|
||||
self.test_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen')
|
||||
self.sample_graph = os.path.join(self.test_dir, 'sample_graph.xml')
|
||||
self.sample_graph_t0 = os.path.join(self.test_dir, 't0-sample-graph.xml')
|
||||
|
||||
def run_script(self, argument):
|
||||
print '\n Running sonic-cfggen ' + argument
|
||||
@ -59,3 +60,8 @@ class TestCfgGen(TestCase):
|
||||
output = self.run_script(argument)
|
||||
self.assertEqual(output.strip(), 'value1\nvalue2')
|
||||
|
||||
def test_minigraph_acl(self):
|
||||
argument = '-m "' + self.sample_graph_t0 + '" -v minigraph_acls'
|
||||
output = self.run_script(argument)
|
||||
self.assertEqual(output.strip(), "{'DataAcl': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124']}")
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import openconfig_acl
|
||||
import pyangbind.lib.pybindJSON as pybindJSON
|
||||
|
||||
import sys
|
||||
import os.path
|
||||
import json
|
||||
import argparse
|
||||
|
||||
import openconfig_acl
|
||||
import pyangbind.lib.pybindJSON as pybindJSON
|
||||
from minigraph import parse_xml
|
||||
|
||||
def dump_json(filename, data):
|
||||
with open(filename, 'w') as outfile:
|
||||
json.dump(data, outfile, indent=4, sort_keys=True, separators=(',', ':'))
|
||||
@ -97,7 +98,7 @@ def generate_rule_json(table_name, rule, max_priority):
|
||||
return rule_data
|
||||
|
||||
def generate_table_json(aclset, aclname, port, max_priority, output_path='.'):
|
||||
table_name = aclname.replace(" ", "_")
|
||||
table_name = aclname.replace(" ", "_").replace("-", "_")
|
||||
#table_name = generate_random_table_name()
|
||||
|
||||
table_props = {}
|
||||
@ -119,21 +120,38 @@ def generate_table_json(aclset, aclname, port, max_priority, output_path='.'):
|
||||
|
||||
dump_json(os.path.join(output_path, "rules_for_"+table_name+".json"), rule_data)
|
||||
|
||||
def translate_acl(filename, output_path, port, max_priority):
|
||||
def translate_acl_fixed_port(filename, output_path, port, max_priority):
|
||||
yang_acl = pybindJSON.load(filename, openconfig_acl, "openconfig_acl")
|
||||
for aclsetname in yang_acl.acl.acl_sets.acl_set:
|
||||
aclset = yang_acl.acl.acl_sets.acl_set[aclsetname]
|
||||
generate_table_json(aclset, aclsetname, port, max_priority, output_path)
|
||||
aclset = yang_acl.acl.acl_sets.acl_set[aclsetname]
|
||||
generate_table_json(aclset, aclsetname, port, max_priority, output_path)
|
||||
return
|
||||
|
||||
def translate_acl(filename, output_path, attach_to, max_priority):
|
||||
yang_acl = pybindJSON.load(filename, openconfig_acl, "openconfig_acl")
|
||||
print attach_to.keys()
|
||||
for aclsetname in yang_acl.acl.acl_sets.acl_set:
|
||||
tablename = aclsetname.replace(" ", "_").replace("-", "_")
|
||||
if attach_to.has_key(tablename):
|
||||
port = ','.join(attach_to[tablename])
|
||||
aclset = yang_acl.acl.acl_sets.acl_set[aclsetname]
|
||||
generate_table_json(aclset, aclsetname, port, max_priority, output_path)
|
||||
return
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Translate openconfig ACL json into SONiC ACL jsons")
|
||||
parser.add_argument('input', metavar='INPUT', help='input json file in openconfig format')
|
||||
parser.add_argument('-p', '--port', default='Ethernet0', help='the port(s) that this ACL is binding to')
|
||||
parser.add_argument('-m', '--max-priority', type=int, default=10000, help='the priority number of the first rule in ACL entries')
|
||||
group = parser.add_mutually_exclusive_group(required=True)
|
||||
group.add_argument('-p', '--port', help='the port(s) that this ACL is attached to')
|
||||
group.add_argument('-m', '--minigraph', help='read ACL attaching information from minigraph')
|
||||
parser.add_argument('-n', '--max-priority', type=int, default=10000, help='the priority number of the first rule in ACL entries')
|
||||
parser.add_argument('-o', '--output-path', default='.', help='output directory where SONiC ACL jsons will be generated')
|
||||
args = parser.parse_args()
|
||||
translate_acl(args.input, args.output_path, args.port, args.max_priority)
|
||||
if args.port:
|
||||
translate_acl_fixed_port(args.input, args.output_path, args.port, args.max_priority)
|
||||
elif args.minigraph:
|
||||
mini_data = parse_xml(args.minigraph)
|
||||
translate_acl(args.input, args.output_path, mini_data['minigraph_acls'], args.max_priority)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
Reference in New Issue
Block a user