diff options
author | Jan Pokorný <jpokorny@redhat.com> | 2013-04-03 18:34:07 +0200 |
---|---|---|
committer | Jan Pokorný <jpokorny@redhat.com> | 2013-04-03 18:34:07 +0200 |
commit | 422bad775ba43250974c6ef2fbd2bc98357b46c5 (patch) | |
tree | 0863b5ad9b7211cde207600f41aad7db3dc78cb5 | |
download | cluster-overview-422bad775ba43250974c6ef2fbd2bc98357b46c5.tar.gz cluster-overview-422bad775ba43250974c6ef2fbd2bc98357b46c5.tar.xz cluster-overview-422bad775ba43250974c6ef2fbd2bc98357b46c5.zip |
Let's start
Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
-rwxr-xr-x | overview.py | 329 |
1 files changed, 329 insertions, 0 deletions
diff --git a/overview.py b/overview.py new file mode 100755 index 0000000..5a6c6d0 --- /dev/null +++ b/overview.py @@ -0,0 +1,329 @@ +#!/usr/bin/env python +# vim: set fileencoding=UTF-8: +# Copyright 2013 Red Hat, Inc. +# Author: Jan Pokorný <jpokorny at redhat dot com> +# Distributed under GPLv2+; generated content under CC-BY-SA 3.0 +# (to view a copy, visit http://creativecommons.org/licenses/by-sa/3.0/) +"""Model of cman-based cluster capturing deployment, communication, etc. + +By default, output is a PDF file named as per this script modulo extension. +Generally, you can specify arbitrary format/extension supported by graphviz +as a first parameter and you'll get what you ask for, including original +'.dot' file for further utilization. +""" + +from pydot import Dot, Edge, Node, Subgraph +from sys import argv +from os.path import extsep, splitext + + +FONT = 'Inconsolata' +FONTDEF = map(lambda switch: '-' + switch + 'fontname=' + FONT, "GNE") +OUTPUT = splitext(__file__)[0] + + +# +# Subgraph inheritance +# + + +class GraphNode(Subgraph): + def __init__(self, *args, **kwargs): + kwargs.setdefault('style', 'bold') + super(GraphNode, self).__init__(*args, **kwargs) + + +class GraphSubnode(Subgraph): + def __init__(self, *args, **kwargs): + kwargs.setdefault('fillcolor', 'azure') + kwargs.setdefault('style', 'filled') + super(GraphSubnode, self).__init__(*args, **kwargs) + + +# +# Node inheritance +# + + +class Program(Node): + def __init__(self, *args, **kwargs): + kwargs.setdefault('shape', 'box') + super(Program, self).__init__(*args, **kwargs) + + +class Agent(Program): + def __init__(self, *args, **kwargs): + kwargs.setdefault('fillcolor', 'lavenderblush') + kwargs.setdefault('style', 'filled') + super(Agent, self).__init__(*args, **kwargs) + + +class Executable(Program): + pass + + +class Daemon(Executable): + def __init__(self, *args, **kwargs): + kwargs.setdefault('fillcolor', 'cornsilk') + kwargs.setdefault('style', 'filled') + super(Daemon, self).__init__(*args, **kwargs) + + +class Artefact(Node): + def __init__(self, *args, **kwargs): + kwargs.setdefault('shape', 'box3d') + kwargs.setdefault('fillcolor', 'wheat') + kwargs.setdefault('style', 'filled') + super(Artefact, self).__init__(*args, **kwargs) + + +# +# Edge inheritance +# + + +class DBUS(Edge): + def __init__(self, *args, **kwargs): + kwargs.setdefault('style', 'dotted') + super(DBUS, self).__init__(*args, **kwargs) + + +class OddjobExec(DBUS): + def __init__(self, *args, **kwargs): + kwargs.setdefault('label', 'oddjob exec') + super(OddjobExec, self).__init__(*args, **kwargs) + + +class HTTPS(Edge): + def __init__(self, *args, **kwargs): + kwargs.setdefault('style', 'bold') + super(HTTPS, self).__init__(*args, **kwargs) + + +class LuciHTTPS(HTTPS): + def __init__(self, *args, **kwargs): + kwargs.setdefault('label', 'port 8084') + super(LuciHTTPS, self).__init__(*args, **kwargs) + + +class ApplicationSpecificProtocol(Edge): + def __init__(self, *args, **kwargs): + kwargs.setdefault('style', 'dashed') + super(ApplicationSpecificProtocol, self).__init__(*args, **kwargs) + + +class RICCIRPC(ApplicationSpecificProtocol): + def __init__(self, *args, **kwargs): + kwargs.setdefault('label', 'port 11111') + super(RICCIRPC, self).__init__(*args, **kwargs) + + +class SNMP(ApplicationSpecificProtocol): + def __init__(self, *args, **kwargs): + kwargs.setdefault('label', 'port 161') + super(SNMP, self).__init__(*args, **kwargs) + + +class CIM(ApplicationSpecificProtocol): + def __init__(self, *args, **kwargs): + kwargs.setdefault('label', 'port 898[89]') + super(CIM, self).__init__(*args, **kwargs) + + +class Consume(Edge): + def __init__(self, *args, **kwargs): + kwargs.setdefault('color', 'darkgreen') + kwargs.setdefault('fontcolor', 'darkgreen') + super(Consume, self).__init__(*args, **kwargs) + + +class ConsumeReversed(Consume): + def __init__(self, *args, **kwargs): + kwargs.setdefault('dir', 'back') + super(ConsumeReversed, self).__init__(*reversed(args), **kwargs) + + +class Produce(Edge): + def __init__(self, *args, **kwargs): + kwargs.setdefault('color', 'orangered') + kwargs.setdefault('fontcolor', 'orangered') + super(Produce, self).__init__(*args, **kwargs) + + +class Delegate(Edge): + def __init__(self, *args, **kwargs): + kwargs.setdefault('color', 'navy') + kwargs.setdefault('fontcolor', 'navy') + kwargs.setdefault('dir', 'both') + super(Delegate, self).__init__(*args, **kwargs) + + +# peer-to-peer +class Exchange(Edge): + def __init__(self, *args, **kwargs): + kwargs.setdefault('color', 'saddlebrown') + kwargs.setdefault('fontcolor', 'saddlebrown') + kwargs.setdefault('dir', 'both') + super(Exchange, self).__init__(*args, **kwargs) + + +# mixing + +class DelegateOddjobExec(Delegate, OddjobExec): + pass + + +class DelegateRICCIRPC(Delegate, RICCIRPC): + pass + + +class DelegateLuciHTTPS(Delegate, LuciHTTPS): + pass + + +class DelegateSNMP(Delegate, SNMP): + pass + + +class DelegateCIM(Delegate, CIM): + pass + + +# +# Here we go +# + + +# management client + +node_mgmt = Subgraph('cluster-climgmt', label='management client') + +node_mgmt.add_node(Program('luci')) +node_mgmt.add_node(Program('ccs')) + + +# other monitoring + +node_mon = Subgraph('cluster-monitor', label='other monitoring') + +node_mon.add_node(Program('snmpwalk')) +node_mon.add_node(Program('wbemcli')) + + +# node b - management + +node_b_conga = GraphSubnode('cluster-node_b-conga', label='management') + +node_b_conga.add_node(Agent('node_b-libClusterMonitorSnmp.so', label='libClusterMonitorSnmp.so')) +node_b_conga.add_node(Agent('node_b-libRedHatClusterProvider.so', label='libRedHatClusterProvider.so')) +node_b_conga.add_node(Artefact('node_b-clumond.sock', label='/var/run/clumond.sock')) +node_b_conga.add_node(Daemon('node_b-ricci', label='ricci')) +node_b_conga.add_node(Daemon('node_b-modclusterd', label='modclusterd')) +node_b_conga.add_node(Program('node_b-modcluster', label='modcluster')) + +node_b_conga.add_edge(Consume('node_b-libClusterMonitorSnmp.so', 'node_b-clumond.sock')) +node_b_conga.add_edge(Consume('node_b-libRedHatClusterProvider.so', 'node_b-clumond.sock')) +node_b_conga.add_edge(Consume('node_b-modcluster', 'node_b-clumond.sock')) +node_b_conga.add_edge(Produce('node_b-modclusterd', 'node_b-clumond.sock')) + + +# node b - core + +node_b_core = GraphSubnode('cluster-node_b-core', label='core') + +node_b_core.add_node(Node('node_b-libccsconfdb', label='libccsconfdb')) +node_b_core.add_node(Daemon('node_b-rgmanager', label='rgmanager')) +node_b_core.add_node(Program('node_b-clustat', label='clustat')) +node_b_core.add_node(Artefact('node_b-rgmanager.sk', label='/var/run/cluster/rgmanager.sk')) + +node_b_core.add_edge(Consume('node_b-clustat', 'node_b-rgmanager.sk')) +node_b_core.add_edge(Consume('node_b-rgmanager', 'node_b-libccsconfdb')) +node_b_core.add_edge(Produce('node_b-rgmanager', 'node_b-rgmanager.sk')) + + +# node b - general + +node_b = GraphNode('cluster-node_b', label='NODE B') +node_b.add_subgraph(node_b_conga) +node_b.add_subgraph(node_b_core) + +node_b.add_node(Artefact('node_b-cluster.conf', label='/etc/cluster/cluster.conf')) +node_b.add_node(Daemon('node_b-snmpd', label='snmpd')) +node_b.add_node(Daemon('node_b-cimserver', label='cimserver')) + +node_b.add_edge(Consume('node_b-modcluster', 'node_b-cluster.conf', label='version?')) +node_b.add_edge(Consume('node_b-modclusterd', 'node_b-cluster.conf', label='version?')) +node_b.add_edge(Consume('node_b-libccsconfdb', 'node_b-cluster.conf', label='version?')) +node_b.add_edge(Consume('node_b-ricci', 'node_b-cluster.conf', label='clustername\nclusteralias')) +node_b.add_edge(Consume('node_b-snmpd', 'node_b-libClusterMonitorSnmp.so')) +node_b.add_edge(Consume('node_b-cimserver', 'node_b-libRedHatClusterProvider.so')) +node_b.add_edge(DelegateOddjobExec('node_b-ricci', 'node_b-modcluster')) + + +# node a - management + +node_a_conga = GraphSubnode('cluster-node_a-conga', label='management (incomplete)') + +node_a_conga.add_node(Daemon('node_a-ricci', label='ricci')) +node_a_conga.add_node(Daemon('node_a-modclusterd', label='modclusterd')) + + +# node a - general + +node_a = GraphNode('cluster-node_a', label='NODE A') +node_a.add_subgraph(node_a_conga) + + +# node c - management + +node_c_conga = GraphSubnode('cluster-node_c-conga', label='management (incomplete)') + +node_c_conga.add_node(Daemon('node_c-ricci', label='ricci')) +node_c_conga.add_node(Daemon('node_c-modclusterd', label='modclusterd')) + + +# node c - general + +node_c = GraphNode('cluster-node_c', label='NODE C') +node_c.add_subgraph(node_c_conga) + + +# nodes + +nodes = Subgraph('cluster-nodes', style='invis') +nodes.add_subgraph(node_b) +nodes.add_subgraph(node_c) +nodes.add_subgraph(node_a) + + +# global environment + +graph = Dot('Cluster.conf-related tools', graph_type='digraph', overlap='scalexy', compound='true', splines='yes') # , ranksep='1.2' +graph.add_subgraph(node_mgmt) +graph.add_subgraph(node_mon) +#graph.add_subgraph(node_a) +#graph.add_subgraph(node_b) +graph.add_subgraph(nodes) + +graph.add_node(Program('firefox')) + +graph.add_edge(DelegateRICCIRPC('luci', 'node_a-ricci', ltail='cluster-climgmt', constraint='false')) +graph.add_edge(DelegateRICCIRPC('luci', 'node_b-ricci', ltail='cluster-climgmt')) +graph.add_edge(DelegateRICCIRPC('luci', 'node_c-ricci', ltail='cluster-climgmt', constraint='false')) +graph.add_edge(DelegateLuciHTTPS('firefox', 'luci')) + +graph.add_edge(DelegateSNMP('snmpwalk', 'node_b-snmpd')) +graph.add_edge(DelegateCIM('wbemcli', 'node_b-cimserver')) + +graph.add_edge(Exchange('node_a-modclusterd', 'node_b-modclusterd', label='port 16851 (either direction)', constraint='false')) +graph.add_edge(Exchange('node_a-modclusterd', 'node_c-modclusterd', label='port 16851 (either direction)', constraint='false')) +graph.add_edge(Exchange('node_b-modclusterd', 'node_c-modclusterd', label='port 16851 (either direction)', constraint='false')) + + +### + + +if __name__ == '__main__': + ext = argv[1] if len(argv) > 1 else 'pdf' + fmt = {'dot': 'raw'}.get(ext, ext) + graph.write(OUTPUT + extsep + ext, format=fmt, prog=['dot'] + FONTDEF) |