Python函数返回ACL检查结果格式异常问题求助
实现ACL流量检查结果的可读格式化输出
我在编写ACL流量检查的Python代码时,调用l.link()函数返回的是字典结构,无法生成带分隔线、规则详情的可读格式化文本。目前函数return的是字典数据,需要修改代码让return返回符合预期格式的文本。
相关代码
import link as l # 用于检查ACL流量的Python代码 def t2e(src,dst,port,protocol): """ acl output :param src : source ip :param dst : destination ip :param port : port :param protocol : protocol filed :args : source port :return : output """ aclname = "t2e.jcl" dc = "abc" rpmName = "man-acl" ar.downloadlatestartifact(rpmName, aclDirName, dc) aclPath = "".join([aclDirName, f"/opt/manual-acl/acls/{aclname}"]) print(f"output for {aclname.upper()}: {output(src, dst, port, protocol, aclPath)}") def output(src,dst,port,protocol,aclPath,*args): """ ACL output :param src : source ip :param dst : destination ip :param port : port :param protocol : protocol filed :param acl_path : acl path where it is stored :args : source port :return : hunter output """ logger.info("flow is running against required acl") option = {'dport': port, 'proto': protocol, 'showallmatches': True} return l.link(src, dst, files=[aclPath], opts=option)
预期输出格式
############ CHECKING FLOW ############ 8.8.8.8 -> 101.11.24.56 Dest Port: 443 Source Port: 0 Protocol: tcp ############## ACL CHECK ############## Processing file: /var/folders/z6/1h1wt5x92rl9y4fsvh2j8y1c0000gp/T/tmpihe16vau/opt/m-acl/acls/t2e.jcl- HIT!! Link Rule number: 11 Rule name: term web Source Address: 0.0.0.0/0.0.0.0 Destination Address: 0.0.0.0/0.0.0.0 Destination Port: 25,8443,9443 Source Port: 0 Protocol: tcp Application: Wildcard: False Action: PERMIT
当前return返回格式
{ 'Hunter output for TRANSIT2EDGE.JCL': { '/var/folders/z6/1h1wt5x92rl9y4fsvh2j8y1c0000gp/T/tmpihe16vau/opt/m-acl/acls/t2e.jcl': [ ['term web-axm', '0.0.0.0/0.0.0.0', '0.0.0.0/0.0.0.0', '25,53,80,81,443,4309,8443,9443', '0', 'tcp', True, False, '', '', False, False, '', '', '', None, 'cde01edef036a4182afec9a6b8c72d63f0f1a6cb2e7d66f7e36bb3918f0dd106'] ] } }
解决思路
解析l.link()返回的字典数据,提取关键字段后按照预期格式拼接成字符串,修改output函数的return逻辑返回格式化后的文本。
修改后的代码
import link as l # 用于检查ACL流量的Python代码 def t2e(src,dst,port,protocol): """ acl output :param src : source ip :param dst : destination ip :param port : port :param protocol : protocol filed :args : source port :return : output """ aclname = "t2e.jcl" dc = "abc" rpmName = "man-acl" ar.downloadlatestartifact(rpmName, aclDirName, dc) aclPath = "".join([aclDirName, f"/opt/manual-acl/acls/{aclname}"]) # 直接打印格式化后的结果 print(output(src, dst, port, protocol, aclPath)) def output(src,dst,port,protocol,aclPath,*args): """ ACL output :param src : source ip :param dst : destination ip :param port : port :param protocol : protocol filed :param acl_path : acl path where it is stored :args : source port :return : hunter output """ logger.info("flow is running against required acl") option = {'dport': port, 'proto': protocol, 'showallmatches': True} # 获取字典结果 result_dict = l.link(src, dst, files=[aclPath], opts=option) # 解析字典数据 top_key = next(iter(result_dict.keys())) file_path = next(iter(result_dict[top_key].keys())) rules = result_dict[top_key][file_path] # 拼接格式化文本 output_lines = [] # 流量检查头部 output_lines.append("############ CHECKING FLOW ############") # 流量信息 source_port = args[0] if args else 0 output_lines.append(f"{src} -> {dst} Dest Port: {port} Source Port: {source_port} Protocol: {protocol}") # ACL检查头部 output_lines.append("############## ACL CHECK ##############") # 文件处理行 output_lines.append(f"Processing file: {file_path}- HIT!!") # 遍历规则(支持多条规则) for idx, rule in enumerate(rules, 1): # 按返回列表顺序映射字段 rule_name, src_addr, dst_addr, dst_ports, src_port, proto, _, wildcard, _, _, _, _, _, _, _, _, _ = rule output_lines.append(f"Link Rule number: {idx}") output_lines.append(f"Rule name: {rule_name}") output_lines.append(f"Source Address: {src_addr}") output_lines.append(f"Destination Address: {dst_addr}") output_lines.append(f"Destination Port: {dst_ports}") output_lines.append(f"Source Port: {src_port}") output_lines.append(f"Protocol: {proto}") output_lines.append("Application: ") output_lines.append(f"Wildcard: {wildcard}") output_lines.append("Action: PERMIT") # 若有对应字段可替换为动态值 # 拼接所有行并返回 formatted_output = "\n".join(output_lines) return formatted_output
关键说明
- 字典解析:通过
next(iter(...))快速提取字典中的动态键值,避免硬编码键名。 - 字段映射:根据当前
l.link()返回的规则列表顺序,对应到预期输出的各个字段,若字段顺序变化需同步调整。 - 文本拼接:逐行构建格式化内容,最后用换行符连接成完整字符串返回。
- 源端口处理:通过
*args接收可选的源端口参数,默认值设为0。
内容的提问来源于stack exchange,提问作者shivram
相关产品推荐
相关产品推荐

