#!/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()