Skip to content

Instantly share code, notes, and snippets.

@sjlongland
Created March 14, 2023 01:02
Show Gist options
  • Save sjlongland/a94d6a3569461e7c83d7df3a7f878937 to your computer and use it in GitHub Desktop.
Save sjlongland/a94d6a3569461e7c83d7df3a7f878937 to your computer and use it in GitHub Desktop.
Re-format the NACL change output from Terraform to make changes easier to spot.
import re
import argparse
PROTOCOLS = {
"1": "icmp",
"6": "tcp",
"17": "udp",
}
ap = argparse.ArgumentParser()
ap.add_argument("--rule-indent", type=int, default=10)
ap.add_argument("--field-indent", type=int, default=14)
ap.add_argument("plan_txt")
args = ap.parse_args()
RULE_RE = re.compile(r"^ {%d}(.) {$" % args.rule_indent)
FIELD_RE = re.compile(r"^ {%d}(.) ([0-9a-z_]+) += (.*)$" % args.field_indent)
# Parse the NACL rule changes. The parser is pretty stupid, so the regexes
# may need fiddling or the file have some 'massaging' in a text editor.
rules = []
for line in open(args.plan_txt, "r"):
m = RULE_RE.match(line)
if m:
rule = {"addremove": m.group(1)}
rules.append(rule)
continue
m = FIELD_RE.match(line)
if m:
(addrem, field, value) = m.groups()
assert (
addrem == rule["addremove"]
), "rule %r does not match field %r" % (rule, line)
rule[field] = value
continue
rule = None
for r in rules:
r["rule_no"] = int(r["rule_no"])
protocol = r["protocol"][1:-1]
if protocol in PROTOCOLS:
protocol = PROTOCOLS[protocol]
r["protocol"] = protocol
for f in ("cidr_block", "ipv6_cidr_block"):
if r[f] in ('""', 'null'):
r[f] = None
rules.sort(
key=lambda r: (
r["rule_no"],
r["cidr_block"],
r["ipv6_cidr_block"],
r["from_port"],
r["to_port"],
r["protocol"],
r["action"],
r["addremove"],
)
)
print(
"\n".join(
[
(
"%(addremove)s %(rule_no)3d %(action)-5s %(cidr_block)-24s "
"%(ipv6_cidr_block)-44s %(protocol)-4s "
"%(from_port)8s %(to_port)8s"
)
% r
for r in rules
]
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment