#!/bin/env python
import sys
import pygraph
import re
sys.path.append('..')
sys.path.append('/usr/lib/graphviz/python/')
sys.path.append('/usr/lib64/graphviz/python/')
import gv
###TODO
# * mark enabled/disabled nodes with different colours...
def usage():
print "%s alteonconfig" % sys.argv[0]
sys.exit(1)
def dict_sieve(dict):
"""
returns a list of unique elements from the dict
"""
ret_list = []
for i in dict:
try:
ret_list.index(dict[i])
except ValueError, e:
ret_list.append(dict[i])
return ret_list
def check_state(line):
state = None
info = None
## catch all state
o = re.match("^/c/", line)
if o is not None:
state = "other"
o = re.match("^/c/slb/real ([0-9]+)", line)
if o is not None:
info = o.groups()[0]
state = "real"
o = re.match("^/c/slb/group ([0-9]+)", line)
if o is not None:
info = o.groups()[0]
state = "group"
o = re.match("^/c/slb/virt ([0-9]+)", line)
if o is not None:
info = o.groups()[0]
state = "virt"
o = re.match("^/c/slb/virt ([0-9]+)/service ([^ ]+)$", line)
if o is not None:
info = o.groups()[0] + "_" + o.groups()[1].strip()
state = "service"
return (state, info)
def get_group_name(group, gid):
if 'name' in group[gid]:
return group[gid]['name']
else:
return "group " + gid
def get_hostname(real, id):
hn = ""
if 'name' in real[id]:
hn += real[id]['name']
if 'rip' in real[id]:
hn += "("+real[id]['rip']+")"
return hn
def get_unique_graphs(virt, group, service, real):
gr = pygraph.graph()
for k, v in service.iteritems():
o = re.match("([0-9]+)_(.*)", k)
virtual = o.groups()[0]
virtual_name = "(vip_"+virtual+") " + virt[virtual]['vip']
gr.add_node(virtual_name, attrs=[('color', 'red')])
gr.add_node(k, attrs=[('color', 'green')])
gr.add_edge(virtual_name, k)
group_id = v['group']
group_name = get_group_name(group, v['group'])
gr.add_node(group_name, attrs=[('color', 'blue')])
gr.add_edge(k,group_name)
if 'hosts' in group[group_id]:
for h in group[group_id]['hosts']:
hostname = get_hostname(real, h)
gr.add_node(hostname, attrs=[('color', 'magenta')])
gr.add_edge(group_name, hostname)
return dict_sieve(pygraph.algorithms.accessibility.accessibility(gr))
def get_vips(g):
vips = []
for i in g:
o = re.match("\(vip_[0-9]+\) .*", i)
if o is not None:
vips.append(i)
if len(vips) == 0:
print g
return vips
def main():
in_state = None
cur_info = None
virt = {}
service = {}
group = {}
real = {}
if len(sys.argv) < 2:
usage()
try:
f = file(sys.argv[1], "r")
except IOError, e:
print "can't open file %s" % sys.argv[1]
sys.exit(1)
## very ugly way of doing things... :)
for line in f:
##possible states: real, group, virt, service
if in_state == "real":
o = re.match("\s+rip (.*)", line)
if o is not None:
real[cur_info]['rip'] = o.groups()[0]
o = re.match('\s+name "(.*)"', line)
if o is not None:
real[cur_info]['name'] = o.groups()[0]
if in_state == "group":
o = re.match('\s+name "(.*)"', line)
if o is not None:
group[cur_info]['name'] = o.groups()[0]
o = re.match("\s+add ([0-9]+)", line)
if o is not None:
if 'hosts' not in group[cur_info]:
group[cur_info]['hosts'] = []
group[cur_info]['hosts'].append(o.groups()[0])
if in_state == "virt":
o = re.match("\s+vip (.+)", line)
if o is not None:
virt[cur_info]['vip'] = o.groups()[0]
if in_state == "service":
o = re.match("\s+group ([0-9]+)", line)
if o is not None:
service[cur_info]['group'] = o.groups()[0]
############# in_state checks
(state,info) = check_state(line)
if state is not None:
in_state = state
cur_info = info
if in_state == "real":
if cur_info not in real:
real[cur_info] = {}
if in_state == "group":
if cur_info not in group:
group[cur_info] = {}
if in_state == "virt":
if cur_info not in virt:
virt[cur_info] = {}
if in_state == "service":
if cur_info not in service:
service[cur_info] = {}
## goes through services, and connects virts and groups to them
## then it connects reals to groups
unique_graphs = get_unique_graphs(virt, group, service, real)
f = file("index.html", "w+")
img_nr = 1
for g in unique_graphs:
gr = pygraph.digraph()
vips = get_vips(g)
for virtual_name in vips:
o = re.match("\(vip_([0-9]+)\)", virtual_name)
vid = o.groups()[0]
gr.add_node(virtual_name, attrs=[('color', 'red'), ('layer', 'virt'), ('fontsize', '8')])
# now iterate through all services to find those belonging to the
# current virt
for service_key, service_value in service.iteritems():
# get virt id
o = re.match("([0-9]+)_(.*)", service_key)
virt = o.groups()[0]
service_name = o.groups()[1]
if virt == vid:
gr.add_node(service_key, attrs=[('color', 'blue'), ('layer', 'service'), ('fontsize', '8')])
gr.add_edge(virtual_name, service_key)
# now connect all groups
group_id = service_value['group']
group_name = get_group_name(group, service_value['group'])
gr.add_node(group_name, attrs=[('color', 'green'), ('layer', 'group'), ('fontsize', '8')])
gr.add_edge(service_key,group_name)
# and all hosts to them
if 'hosts' in group[group_id]:
for h in group[group_id]['hosts']:
hostname = get_hostname(real, h)
gr.add_node(hostname, attrs=[('color', 'magenta'), ('layer', 'host'), ('fontsize', '8')])
gr.add_edge(group_name, hostname)
dot = pygraph.readwrite.dot.write(gr)
gvv = gv.readstring(dot)
gv.layout(gvv, 'dot')
gv.render(gvv, 'png', str(img_nr)+'.png')
f.write('
' % (img_nr, img_nr))
f.write("
\n")
img_nr += 1
f.close()
if __name__ == "__main__":
main()