Skip to content

Instantly share code, notes, and snippets.

@mjbnz
Created February 2, 2019 07:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjbnz/eb0df7484dba9bc46db2b6e7032598d8 to your computer and use it in GitHub Desktop.
Save mjbnz/eb0df7484dba9bc46db2b6e7032598d8 to your computer and use it in GitHub Desktop.
pretty print ip sets
#!/usr/bin/env python
import sys
import subprocess
import json
def range_string(start, end):
if start != end:
return '%s-%s' % (start, end)
else:
return str(start)
ipsets = {}
in_set = False
in_members = False
set_name = ""
in_range = False
port_start = 0
port_end = 0
p = subprocess.Popen(['ipset', 'list'],stdout=subprocess.PIPE)
while True:
line = p.stdout.readline()
if line != b'':
line = line.strip()
if line == '':
if in_members and in_range:
ipsets[set_name]['Members'].append(range_string(port_start, port_end))
in_set = False
in_members = False
in_range = False
continue
if not in_set:
k,v = line.split(":", 1)
if k == 'Name':
in_set = True
set_name = v.strip()
ipsets[set_name] = {}
else:
if not in_members:
k,v = line.split(":", 1)
if k == 'Members':
in_members = True
ipsets[set_name]['Members'] = []
else:
ipsets[set_name][k.strip()] = v.strip()
else:
v = line.strip()
try:
v = int(v)
if not in_range:
in_range = True
port_start = port_end = v
elif v == (port_end + 1):
port_end = v
else:
ipsets[set_name]['Members'].append(range_string(port_start, port_end))
port_start = port_end = v
except ValueError:
if in_range:
in_range = False
ipsets[set_name]['Members'].append(range_string(port_start, port_end))
ipsets[set_name]['Members'].append(v)
else:
if in_members and in_range:
ipsets[set_name]['Members'].append(range_string(port_start, port_end))
break
name_width = max(30, 3 + len(max(ipsets, key=len)))
type_width = max(15, 3 + len(max([ipsets[s]['Type'] for s in ipsets], key=len)))
member_width = max(30, 3 + len(max((x for y in [ipsets[s]['Members'] for s in ipsets] for x in y), key=len)))
def print_set_line(n, t, m):
print '{name:<{name_w}}{type:<{type_w}}{members:<{member_w:}}'.format(
name=n, name_w=name_width,
type=t, type_w=type_width,
members=m, member_w=member_width
)
print_set_line("Name", "Type", "Members")
print '_' * (name_width + type_width + member_width)
for name in sorted(ipsets):
type = ipsets[name]['Type']
members = ipsets[name]['Members']
print_set_line(name, type, (members[0] if members else ''))
if len(members) > 1:
for member in members[1:]:
print_set_line('', '', member)
@mjbnz
Copy link
Author

mjbnz commented Feb 2, 2019

... I'm not a seasoned python programmer, this can probably be simpler/better...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment