dottr.pl
changeset 1 26fed0d59d7c
child 2 b78794f00e34
equal deleted inserted replaced
0:624a9ab34425 1:26fed0d59d7c
       
     1 #!/usr/bin/perl
       
     2 ##$Id: dottr.pl,v ac49839c1b85 2014/10/03 12:46:32 grin $
       
     3 #
       
     4 # (c) Peter 'grin' Gervai, 2012
       
     5 # Released under CreativeCommons-Attribution-ShareAlike-3.0-Unported
       
     6 #
       
     7 # create .dot from racktables links
       
     8 #
       
     9 
       
    10 use DBI;
       
    11 use Encode;
       
    12 
       
    13 # if 1 we do not list reserved port descriptions
       
    14 my $SKIP_RESERVATION_LABELS = 1;
       
    15 
       
    16 $|=1;
       
    17 
       
    18 use DatabaseLoginData; # $db_user; $db_pw; $db_host
       
    19 
       
    20 my ($db_name, $db_port) = ("racktables_db", 3306);
       
    21 
       
    22 &d("connect db dbi:mysql:database=$db_name;host=$DatabaseLoginData::db_host;port=$db_port");
       
    23 my $dbh = DBI->connect( "dbi:mysql:database=$db_name;host=$DatabaseLoginData::db_host;port=$db_port",
       
    24                            $DatabaseLoginData::db_user, $DatabaseLoginData::db_pw, 
       
    25                            { RaiseError =>1, AutoCommit => 1 } );
       
    26 $dbh->do('set names utf8');	# from Alexandr Alakin
       
    27 &d("db ok");
       
    28 #########################################################################
       
    29 
       
    30 my $sth_links = $dbh->prepare("
       
    31 SELECT ro1.name AS obj1, p1.name AS port1, Link.cable, p2.name AS port2, ro2.name AS obj2, d.dict_value AS obj1type
       
    32  FROM RackObject AS ro1 
       
    33    JOIN Port AS p1 ON(ro1.id=p1.object_id)
       
    34    JOIN Link       ON(p1.id=Link.porta)
       
    35    JOIN Port AS p2 ON(Link.portb=p2.id)
       
    36    JOIN RackObject AS ro2 ON(p2.object_id=ro2.id)
       
    37    LEFT JOIN Dictionary AS d ON(ro1.objtype_id=d.dict_key)
       
    38  ORDER BY obj1, port1");
       
    39 
       
    40 my $sth_reservations = $dbh->prepare("
       
    41 SELECT ro.name AS obj1, p.name AS port1, 'RESERVE' AS cable, '' AS port2, 
       
    42  CONCAT(reservation_comment,' #',ROUND(RAND()*1000))  AS obj2,  d.dict_value AS obj1type
       
    43  FROM RackObject AS ro
       
    44    JOIN Port AS p  ON(ro.id=p.object_id)
       
    45    LEFT JOIN Dictionary AS d ON(ro.objtype_id=d.dict_key)
       
    46      WHERE p.reservation_comment IS NOT NULL
       
    47  ORDER BY obj1, port1");
       
    48 
       
    49 &d("Start query.");
       
    50 my $res = $sth_links->execute;
       
    51 
       
    52 &d("Fetch query.");
       
    53 my $a = $sth_links->fetchall_arrayref;
       
    54 my @data = @$a;
       
    55 
       
    56 if( !$SKIP_RESERVATION_LABELS ) {
       
    57       $res = $sth_reservations->execute;
       
    58       $a = $sth_reservations->fetchall_arrayref;
       
    59       @data = (@data, @$a);
       
    60 } else {
       
    61       print STDERR "Skipping reservation label mapping.\n";
       
    62 }
       
    63 
       
    64 # header
       
    65 print '
       
    66 graph rackspace_topo {
       
    67 
       
    68 label = "Tarr Racktables topo";
       
    69 rankdir = LR;
       
    70 
       
    71        edge [ color="#0000a0", decorate=true, fontsize=9, headclip=false ];
       
    72        node [ shape=box, headport=n, tailport=n ];
       
    73        
       
    74 ';
       
    75 
       
    76 
       
    77 # generate edges
       
    78 foreach $a (@data) {
       
    79   # node+interface 1
       
    80   $node{$a->[0]} = $a->[1];
       
    81   $nodetype{$a->[0]} = $a->[5];
       
    82   # node+interface 2
       
    83   $node{$a->[4]} = $a->[3];
       
    84   # 
       
    85   push @link, $a;
       
    86 }
       
    87 
       
    88 # output the nods first
       
    89 foreach my $n (keys %node) {
       
    90   # nodes with empty or "space" names
       
    91   next if $n =~ /^\s*$/;
       
    92 
       
    93   $ntyp = $nodetype{$n};
       
    94 
       
    95   # color/style depends on node type
       
    96   my $color="";
       
    97   if( $ntyp eq "Server" ) {
       
    98     $color='color="black"';
       
    99     
       
   100   } elsif( $ntyp eq "Network switch" ) {
       
   101     $color='color="red" style="bold"';
       
   102     
       
   103   } elsif( $ntyp eq "Server chassis" ) {
       
   104     $color='color="blue" style="dotted"';
       
   105     
       
   106   } elsif( $ntyp eq "Network chassis" ) {
       
   107     $color='color="lightblue"';
       
   108     
       
   109   } elsif( $ntyp eq "MediaConverter" ) {
       
   110     $color='color="gold"';
       
   111     
       
   112   } elsif( $ntyp eq "Router" ) {
       
   113     $color='color="darkgreen"';
       
   114     
       
   115   } else {
       
   116     #$color='color="pink"';			# Barbie syndrome FTW
       
   117     
       
   118   }
       
   119   
       
   120   print '"' . $n . "\" [ $color ];\n";
       
   121   if( !defined($node_color{$n}) ) { $node_color{ $n } = &gen_color; }
       
   122 }
       
   123 
       
   124 # and print the edges
       
   125 foreach my $i (0 .. $#link) {
       
   126   my $l = $link[$i];
       
   127   # skip empty...
       
   128   next if $l->[0] =~ /^\s*$/;
       
   129 
       
   130   if( defined( $link{ $l->[0] }{ $l->[4] } ) && $link{ $l->[0] }{ $l->[4] } == $l->[2] ) {
       
   131     # skip duplicate
       
   132     # if you need warnings... here you can.
       
   133   } else {
       
   134 #    print '"', $l->[0], '" -- "', $l->[4], '" [ label="', $l->[2], "\" color=\"grey\"];\n";
       
   135     my $color = $node_color{ $l->[0] } or 'grey';
       
   136     print '"', $l->[0], '" -- "', $l->[4], '" [ label="', $l->[2], "\" color=\"$color\"];\n";
       
   137     $link{ $l->[0] }{ $l->[4] } = $l->[2];
       
   138   }
       
   139 }
       
   140 
       
   141 print "\n};\n\n";
       
   142 
       
   143 
       
   144 # generate random html colors
       
   145 sub gen_color {
       
   146   my $c = "#";
       
   147   for (1..3) {
       
   148     $c .= sprintf "%02x", rand(256);
       
   149   }
       
   150   return $c;
       
   151 }
       
   152 
       
   153 
       
   154 sub d {
       
   155   print STDERR scalar(localtime), ' [$$] ', (shift), "\n";
       
   156 }