Skip to content

Commit bd77f9a

Browse files
taoyl-msShuotian Cheng
authored and
Shuotian Cheng
committed
[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
1 parent 6a6bc88 commit bd77f9a

File tree

4 files changed

+68
-16
lines changed

4 files changed

+68
-16
lines changed

src/sonic-config-engine/minigraph.py

+26-5
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ def parse_dpg(dpg, hname):
124124

125125
ipintfs = child.find(str(QName(ns, "IPInterfaces")))
126126
intfs = []
127+
intfnames = {}
127128
vlan_map = {}
128129
pc_map = {}
129130
for ipintf in ipintfs.findall(str(QName(ns, "IPInterface"))):
@@ -177,6 +178,7 @@ def parse_dpg(dpg, hname):
177178
if peer_addr_val is not None:
178179
intf['peer_addr'] = ipaddress.IPAddress(peer_addr_val)
179180
intfs.append(intf)
181+
intfnames[intf['alias']] = { 'alias': intf['name'] }
180182

181183
pcintfs = child.find(str(QName(ns, "PortChannelInterfaces")))
182184
pc_intfs = []
@@ -237,10 +239,27 @@ def parse_dpg(dpg, hname):
237239
vlan_attributes.update(addrtuple)
238240
vlan_intfs.append(copy.deepcopy(vlan_attributes))
239241
vlans[vintfname] = vlan_attributes
240-
241-
242-
return intfs, lo_intfs, mgmt_intf, vlan_intfs, pc_intfs, vlans, pcs
243-
return None, None, None, None, None
242+
aclintfs = child.find(str(QName(ns, "AclInterfaces")))
243+
acls = {}
244+
for aclintf in aclintfs.findall(str(QName(ns, "AclInterface"))):
245+
aclname = aclintf.find(str(QName(ns, "InAcl"))).text
246+
aclattach = aclintf.find(str(QName(ns, "AttachTo"))).text.split(';')
247+
acl_intfs = []
248+
for member in aclattach:
249+
member = member.strip()
250+
if port_alias_map.has_key(member):
251+
member = port_alias_map[member]
252+
if pcs.has_key(member):
253+
acl_intfs.extend(pcs[member]['members']) # For ACL attaching to port channels, we break them into port channel members
254+
elif vlans.has_key(member):
255+
print >> sys.stderr, "Warning: ACL "+aclname+" is attached to a Vlan interface, which is currently not supported"
256+
elif intfnames.has_key(member):
257+
acl_intfs.append(member)
258+
if acl_intfs:
259+
acls[aclname] = acl_intfs
260+
261+
return intfs, lo_intfs, mgmt_intf, vlan_intfs, pc_intfs, intfnames, vlans, pcs, acls
262+
return None, None, None, None, None, None, None, None
244263

245264
def parse_cpg(cpg, hname):
246265
bgp_sessions = []
@@ -394,7 +413,7 @@ def parse_xml(filename, platform=None, port_config_file=None):
394413

395414
for child in root:
396415
if child.tag == str(QName(ns, "DpgDec")):
397-
(intfs, lo_intfs, mgmt_intf, vlan_intfs, pc_intfs, vlans, pcs) = parse_dpg(child, hostname)
416+
(intfs, lo_intfs, mgmt_intf, vlan_intfs, pc_intfs, ports, vlans, pcs, acls) = parse_dpg(child, hostname)
398417
elif child.tag == str(QName(ns, "CpgDec")):
399418
(bgp_sessions, bgp_asn) = parse_cpg(child, hostname)
400419
elif child.tag == str(QName(ns, "PngDec")):
@@ -418,9 +437,11 @@ def parse_xml(filename, platform=None, port_config_file=None):
418437
results['minigraph_vlan_interfaces'] = vlan_intfs
419438
results['minigraph_portchannel_interfaces'] = pc_intfs
420439
results['minigraph_vlans'] = vlans
440+
results['minigraph_ports'] = ports
421441
results['minigraph_portchannels'] = pcs
422442
results['minigraph_mgmt_interface'] = mgmt_intf
423443
results['minigraph_lo_interfaces'] = lo_intfs
444+
results['minigraph_acls'] = acls
424445
results['minigraph_neighbors'] = neighbors
425446
results['minigraph_devices'] = devices
426447
results['minigraph_underlay_neighbors'] = u_neighbors

src/sonic-config-engine/tests/t0-sample-graph.xml

+8-1
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,14 @@
251251
</IPInterface>
252252
</IPInterfaces>
253253
<DataAcls/>
254-
<AclInterfaces/>
254+
<AclInterfaces>
255+
<AclInterface>
256+
<AttachTo>
257+
PortChannel01;PortChannel02;PortChannel03;PortChannel04
258+
</AttachTo>
259+
<InAcl>DataAcl</InAcl>
260+
</AclInterface>
261+
</AclInterfaces>
255262
<DownstreamSummaries/>
256263
<DownstreamSummarySet xmlns:a="http://schemas.datacontract.org/2004/07/Microsoft.Search.Autopilot.Evolution"/>
257264
</DeviceDataPlaneInfo>

src/sonic-config-engine/tests/test_cfggen.py

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ def setUp(self):
88
self.test_dir = os.path.dirname(os.path.realpath(__file__))
99
self.script_file = os.path.join(self.test_dir, '..', 'sonic-cfggen')
1010
self.sample_graph = os.path.join(self.test_dir, 'sample_graph.xml')
11+
self.sample_graph_t0 = os.path.join(self.test_dir, 't0-sample-graph.xml')
1112

1213
def run_script(self, argument):
1314
print '\n Running sonic-cfggen ' + argument
@@ -59,3 +60,8 @@ def test_render_template(self):
5960
output = self.run_script(argument)
6061
self.assertEqual(output.strip(), 'value1\nvalue2')
6162

63+
def test_minigraph_acl(self):
64+
argument = '-m "' + self.sample_graph_t0 + '" -v minigraph_acls'
65+
output = self.run_script(argument)
66+
self.assertEqual(output.strip(), "{'DataAcl': ['Ethernet112', 'Ethernet116', 'Ethernet120', 'Ethernet124']}")
67+

src/sonic-config-engine/translate_acl

+28-10
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
#!/usr/bin/env python
22

3-
import openconfig_acl
4-
import pyangbind.lib.pybindJSON as pybindJSON
5-
63
import sys
74
import os.path
85
import json
96
import argparse
107

8+
import openconfig_acl
9+
import pyangbind.lib.pybindJSON as pybindJSON
10+
from minigraph import parse_xml
11+
1112
def dump_json(filename, data):
1213
with open(filename, 'w') as outfile:
1314
json.dump(data, outfile, indent=4, sort_keys=True, separators=(',', ':'))
@@ -97,7 +98,7 @@ def generate_rule_json(table_name, rule, max_priority):
9798
return rule_data
9899

99100
def generate_table_json(aclset, aclname, port, max_priority, output_path='.'):
100-
table_name = aclname.replace(" ", "_")
101+
table_name = aclname.replace(" ", "_").replace("-", "_")
101102
#table_name = generate_random_table_name()
102103

103104
table_props = {}
@@ -119,21 +120,38 @@ def generate_table_json(aclset, aclname, port, max_priority, output_path='.'):
119120

120121
dump_json(os.path.join(output_path, "rules_for_"+table_name+".json"), rule_data)
121122

122-
def translate_acl(filename, output_path, port, max_priority):
123+
def translate_acl_fixed_port(filename, output_path, port, max_priority):
124+
yang_acl = pybindJSON.load(filename, openconfig_acl, "openconfig_acl")
125+
for aclsetname in yang_acl.acl.acl_sets.acl_set:
126+
aclset = yang_acl.acl.acl_sets.acl_set[aclsetname]
127+
generate_table_json(aclset, aclsetname, port, max_priority, output_path)
128+
return
129+
130+
def translate_acl(filename, output_path, attach_to, max_priority):
123131
yang_acl = pybindJSON.load(filename, openconfig_acl, "openconfig_acl")
132+
print attach_to.keys()
124133
for aclsetname in yang_acl.acl.acl_sets.acl_set:
125-
aclset = yang_acl.acl.acl_sets.acl_set[aclsetname]
126-
generate_table_json(aclset, aclsetname, port, max_priority, output_path)
134+
tablename = aclsetname.replace(" ", "_").replace("-", "_")
135+
if attach_to.has_key(tablename):
136+
port = ','.join(attach_to[tablename])
137+
aclset = yang_acl.acl.acl_sets.acl_set[aclsetname]
138+
generate_table_json(aclset, aclsetname, port, max_priority, output_path)
127139
return
128140

129141
def main():
130142
parser = argparse.ArgumentParser(description="Translate openconfig ACL json into SONiC ACL jsons")
131143
parser.add_argument('input', metavar='INPUT', help='input json file in openconfig format')
132-
parser.add_argument('-p', '--port', default='Ethernet0', help='the port(s) that this ACL is binding to')
133-
parser.add_argument('-m', '--max-priority', type=int, default=10000, help='the priority number of the first rule in ACL entries')
144+
group = parser.add_mutually_exclusive_group(required=True)
145+
group.add_argument('-p', '--port', help='the port(s) that this ACL is attached to')
146+
group.add_argument('-m', '--minigraph', help='read ACL attaching information from minigraph')
147+
parser.add_argument('-n', '--max-priority', type=int, default=10000, help='the priority number of the first rule in ACL entries')
134148
parser.add_argument('-o', '--output-path', default='.', help='output directory where SONiC ACL jsons will be generated')
135149
args = parser.parse_args()
136-
translate_acl(args.input, args.output_path, args.port, args.max_priority)
150+
if args.port:
151+
translate_acl_fixed_port(args.input, args.output_path, args.port, args.max_priority)
152+
elif args.minigraph:
153+
mini_data = parse_xml(args.minigraph)
154+
translate_acl(args.input, args.output_path, mini_data['minigraph_acls'], args.max_priority)
137155

138156
if __name__ == "__main__":
139157
main()

0 commit comments

Comments
 (0)