commit version 22.12.12447

This commit is contained in:
2023-01-01 22:36:12 -05:00
parent af1b03d79f
commit b948283a96
744 changed files with 620715 additions and 27381 deletions

View File

@ -0,0 +1,4 @@
Order deny,allow
Deny from all

View File

@ -0,0 +1,70 @@
suite-1.conf
suite-2.conf
============
These are my test map config files that exercise a fair bit of the
functionality of Weathermap, in a couple of files. The first one
is mostly NODE stuff, and the second is mostly LINK stuff. As such,
they make quite useful demo maps, I guess. suite-1.png and suite-2.png
show what these maps *should* look like. They use quite a few fonts
that I can't supply, but mostly they use Bitstream Vera, which is in
the docs/example directory.
map-split.php
=============
Reads in a map, then writes out 'submaps' of a certain size. Edit the
top of the script to specify the source map, and the required size of
the new maps, and it will chop up your map for you. It doesn't do
anything clever with things like KEYPOS or TITLEPOS, but it will do
NODEs OK. It'll delete any links where only one end is in the final
map, so cross-sheet links will need to be put back in. It also removes
the BACKGROUND image if there is one, since it will (by definition) be
the wrong size for the new maps.
auto-overlib.pl
===============
A small but useful script that takes a weathermap config file with
references to Cacti RRD targets and automatically adds in all the
INFOURL and OVERLIBGRAPH lines it can, where they don't exist.
You'll need to edit the script to allow it to log in to your Cacti
database. Requires the Perl DBI and DBD::mysql modules.
Should work with both PHP and perl versions, but not tested with PHP
one.
cacti-integrate.php
===================
A script that reads in a weathermap config file, looks for special SET
variables and uses them to populate as much as it can of TARGET, INFOURL,
OVERLIBGRAPH, and BANDWIDTH. Requires a correct editor-config.php to access
the Cacti database.
You need SET one of 'cacti_id', 'hostname' or 'address' in each NODE so that
it can find the Cacti Host ID for each node.
You need to SET one of 'in_interface' or 'out_interface' to the interface name
so that it can figure out which data sources are relevant. The interface name should
match one of ifAlias, ifName or ifDescr from your router.
More info here: http://forums.cacti.net/about26544.html
cacti-mapper.php
================
A script that reads interface IPs from Cacti, and then uses Cacti's SNMP data
to fetch a netmask for each interface. It then uses all this info to work out
which interfaces are in the same address range as each other, and produces a
map. The map positions are random, but the connections should be right. You need
to run the results through cacti-integrate.php, to fill in the TARGET lines.
Requires a correct editor-config.php to access the Cacti database.
bristle.php
============
Generates a section of Weathermap config useful for showing traffic for all switch
ports in a small space. Intended to work with cacti-integrate.php
More info here: http://forums.cacti.net/post-152500.html#152500

View File

@ -0,0 +1,119 @@
#!/usr/bin/perl
use DBI;
# This should be the URL for the base of your cacti install (no trailing slash)
$cacti_base = "http://www.mynet.net/cacti";
# How we should access your Cacti database....
$db_name = "cacti";
$db_username = "cactiuser";
$db_password = "somepassword";
$db_host = "localhost";
#
# You shouldn't need to change anything below here
#
$cacti_graph = "$cacti_base/graph_image.php?local_graph_id=%d&rra_id=0&graph_nolegend=true&graph_height=100&graph_width=300";
$cacti_graphpage = "$cacti_base/graph.php?rra_id=all&local_graph_id=%d";
$DSN = "DBI:mysql:database=$db_name:host=$db_host";
$dbh = DBI->connect( $DSN, $db_username, $db_password );
$inputfile = $ARGV[0];
$outputfile = $inputfile . ".new";
open( INPUT, $inputfile ) || die($!);
open( OUTPUT, ">$outputfile" );
while (<INPUT>) {
if (m/^\s*LINK\s+(\S+)/i) {
if ( $overlibcount == 0 && $target ne "" ) {
find_graph_urls($target);
}
$overlibcount = 0;
$target = "";
}
if (m/^\s*TARGET\s+(\S+\.rrd)/i) {
$target = $1;
}
if (m/^\s*OVERLIBGRAPH\s+(\S+)/i) {
$overlibcount++;
}
print OUTPUT $_;
}
# for the last LINK
if ( $overlibcount == 0 && $target ne "" ) {
find_graph_urls($target);
}
close(OUTPUT);
close(INPUT);
print "\nNew config file is saved in $outputfile\n";
sub find_graph_urls {
my ($target) = shift;
# $dbh is global
my ( @bits, $SQL, $sth, $data );
my ( $data_template_id, $local_data_id, $count, $output );
my ( $local_graph_id, $title, $graph_url, $graphpage_url );
# we've reached the next link entry, and there's work to be done
@bits = split( /\//, $target );
$target = $bits[-1];
print "Find a graph for $target\n";
$SQL = "select local_data_id from data_template_data where data_source_path like '%".$target."' LIMIT 1";
$sth = $dbh->prepare($SQL);
$sth->execute();
$data = $sth->fetchrow_hashref();
$local_data_id = $$data{local_data_id};
$sth->finish();
$SQL =
"SELECT id FROM data_template_rrd WHERE local_data_id=$local_data_id LIMIT 1";
$sth = $dbh->prepare($SQL);
$sth->execute();
$data = $sth->fetchrow_hashref();
$data_template_rrd_id = $$data{id};
$sth->finish();
$SQL =
"SELECT DISTINCT graph_templates_item.local_graph_id,title_cache FROM graph_templates_item,graph_templates_graph WHERE task_item_id=$data_template_rrd_id and graph_templates_graph.local_graph_id = graph_templates_item.local_graph_id";
$sth = $dbh->prepare($SQL);
$sth->execute();
$count = 0;
$output = "";
while ( $data = $sth->fetchrow_hashref() ) {
$local_graph_id = $$data{local_graph_id};
$title = $$data{title_cache};
$graph_url = sprintf( $cacti_graph, $local_graph_id );
$graphpage_url = sprintf( $cacti_graphpage, $local_graph_id );
$output .= "\t# POSSIBLE OVERLIBGRAPH ($title) \n";
$output .= "\t# OVERLIBGRAPH $graph_url\n";
$output .= "\t# INFOURL $graphpage_url\n";
$count++;
}
$sth->finish();
if ( $count == 1 ) {
print " Single option. Adding it.\n";
print OUTPUT
"\t#Automatically made. Graph is ID $local_graph_id: $title\n";
print OUTPUT "\tOVERLIBGRAPH $graph_url\n";
print OUTPUT "\tINFOURL $graphpage_url\n";
}
else {
print " Multiple options. Adding them as comments.\n";
print OUTPUT $output;
}
print OUTPUT "\n\n";
}

View File

@ -0,0 +1,67 @@
<?php
$cacti_root = "/var/www/docs/cacti";
@include_once($cacti_root."/include/global.php");
@include_once($cacti_root."/include/config.php");
$target_format = "";
$infourl_format = "";
$overlib_format = "";
#
# change these three and then run this.
# run the result through cacti-integrate to fill in the TARGETS etc.
# Change the
$switchname = "sw1";
$nports = 48;
$cacti_host_id = 17;
$interfacepattern = "Gi0/%d";
printf("# generated by bristle.php - %d ports\n# First, the actual switch node. Give this an ICON\nNODE %s\n\tPOSITION 400 400\n\n",$nports, $switchname);
for($n=1; $n<=$nports; $n++)
{
$nodename = sprintf("%s_p%d",$switchname,$n);
$linkname = sprintf("%s_%s",$switchname,$nodename);
$halfway = $nports/2; // the midpoint of a side
$quarter = $halfway/2; // the midpoint of a side
$voffset = 40; // the length of the bristle
$voffset2 = 13; // the inside offset of the bristle
if($n > $halfway)
{
$offset = ($n - 24 - 1 - $quarter)*8;
}
else
{
// The first 24 ports grow up instead of down
$offset = ($n - 1 - $quarter)*8;
$voffset = -$voffset;
$voffset2 = -$voffset2;
}
$target = "tgt?";
$infourl = "info?";
$overliburl = "over?";
printf("NODE %s\n\tPOSITION %s %d %d\n\tSET cacti_id %d\n\n",
$nodename,$switchname,$offset,$voffset, $cacti_host_id);
printf("LINK %s\n\tNODES %s:%d:%d %s\n\tBWLABEL none\n\tWIDTH 2\n\tARROWSTYLE compact\n\tOUTLINECOLOR none\n", $linkname, $switchname, $offset, $voffset2, $nodename
);
$interfacename = sprintf($interfacepattern,$n);
print "\tSET out_interface $interfacename";
# printf("\tINFOURL %s\n\tOVERLIBGRAPH %s\n\tTARGET %s\n", $infourl, $overliburl, $target );
print "\n\n";
}
print "# Now run this output through cacti-integrate.php to add all the INFOURL and TARGET lines";

View File

@ -0,0 +1,436 @@
<?php
/** cacti-integrate.php
*
* Auto-fill a basic map file with as much information as possible from the
* Cacti database, using interface names and node ip/names as clues.
*
* See http://forums.cacti.net/about26544.html for more info
*
*/
$cacti_root = '/var/www/html/cacti/';
if (!file_exists($cacti_root . "/include/config.php")) {
$cacti_root = "../../..";
if (!file_exists($cacti_root . "/include/config.php")) {
print "Couldn't figure out where Cacti is. Edit the top line of the script.\n";
exit();
}
}
ini_set('include_path',
ini_get('include_path') . PATH_SEPARATOR . $cacti_root . PATH_SEPARATOR . $cacti_root . '/plugins/weathermap'
. PATH_SEPARATOR . $cacti_root . '/plugins/weathermap/random-bits');
require_once 'lib/Weathermap.class.php';
require_once 'lib/database.php';
require_once 'Console/Getopt.php';
include_once 'include/global.php';
include_once 'include/config.php';
$cacti_base = $cacti_root;
$cacti_url = $config['url_path'];
include_once 'editor-config.php';
// adjust width of link based on bandwidth.
// NOTE: These are bands - the value has to be up to or including the value in the list to match
$width_map = array (
'1000000' => '1', // up to 1meg
'9999999' => '1', // 1-10meg
'10000000' => '2', // 10meg
'99999999' => '2', // 10-100meg
'100000000' => '4', // 100meg
'999999999' => '4', // 100meg-1gig
'1000000000' => '6', // 1gig
'9999999999' => '6', // 1gig-10gig
'10000000000' => '8', // 10gig
'99999999999' => '8' // 10gig-100gig
);
// check if the goalposts have moved
if (is_dir($cacti_base) && file_exists($cacti_base . "/include/global.php")) {
// include the cacti-config, so we know about the database
include_once($cacti_base . "/include/global.php");
$config['base_url'] = (isset($config['url_path']) ? $config['url_path'] : $cacti_url);
$cacti_found = true;
} elseif (is_dir($cacti_base) && file_exists($cacti_base . "/include/config.php")) {
// include the cacti-config, so we know about the database
include_once($cacti_base . "/include/config.php");
$config['base_url'] = (isset($config['url_path']) ? $config['url_path'] : $cacti_url);
$cacti_found = true;
} else {
print "You need to fix your editor-config.php\n";
exit();
}
$pdo = weathermap_get_pdo();
// the following are defaults. You can change those from the command-line
// options now.
// set this to true to adjust the width of links according to speed
$map_widths = false;
// set this to true to use DSStats targets instead of RRD file targets
$use_dsstats = false;
$overwrite_targets = false;
$outputmapfile = "";
$inputmapfile = "";
// initialize object
$cg = new Console_Getopt();
$short_opts = '';
$long_opts = array (
"help",
"input=",
"output=",
"debug",
"target-dsstats",
"target-rrdtool",
"overwrite-targets",
"speed-width-map"
);
$args = $cg->readPHPArgv();
$ret = $cg->getopt($args, $short_opts, $long_opts);
if (PEAR::isError($ret)) {
die("Error in command line: " . $ret->getMessage() . "\n (try --help)\n");
}
$gopts = $ret[0];
$options_output = array ();
if (sizeof($gopts) > 0) {
foreach ($gopts as $o) {
switch ($o[0]) {
case '--debug':
$weathermap_debugging = true;
break;
case '--overwrite-targets':
$overwrite_targets = true;
break;
case '--speed-width-map':
$map_widths = true;
break;
case '--target-dsstats':
$use_dsstats = true;
break;
case '--target-rrdtool':
$use_dsstats = false;
break;
case '--output':
$outputmapfile = $o[1];
break;
case '--input':
$inputmapfile = $o[1];
break;
case '--help':
print "cacti-integrate.php\n";
print
"Copyright Howard Jones, 2008-2019 howie@thingy.com\nReleased under the MIT License\nhttp://www.network-weathermap.com/\n\n";
print "Usage: php cacti-integrate.php [options]\n\n";
print " --input {filename} - read config from this file\n";
print " --output {filename} - write new config to this file\n";
print " --target-rrdtool - generate rrd file targets (default)\n";
print " --target-dsstats - generate DSStats targets\n";
print " --debug - enable debugging\n";
print " --help - show this help\n";
exit();
break;
}
}
}
if ($inputmapfile == '' || $outputmapfile == '') {
print "You MUST specify an input and output file. See --help\n";
exit();
}
// figure out which template has interface traffic. This might be wrong for you.
$data_template = "Interface - Traffic";
$stmt = $pdo->prepare("select id from data_template where name=?");
$stmt->execute( array($data_template));
$data_template_id = $stmt->fetchColumn();
//$data_template_id =
// db_fetch_cell("select id from data_template where name='" . mysql_real_escape_string($data_template) . "'");
$map = new WeatherMap;
$map->ReadConfig($inputmapfile);
$fmt_cacti_graph =
$cacti_url . "graph_image.php?local_graph_id=%d&rra_id=0&graph_nolegend=true&graph_height=100&graph_width=300";
$fmt_cacti_graphpage = $cacti_url . "graph.php?rra_id=all&local_graph_id=%d";
//
// Try and populate all three SET vars for each NODE
// cacti_id (host.id)
// hostname (host.description)
// address (host.hostname) (sorry about that)
//
foreach ($map->nodes as $node) {
$name = $node->name;
print "NODE $name\n";
$host_id = $node->get_hint("cacti_id");
$hostname = $node->get_hint("hostname");
$address = $node->get_hint("address");
if ($host_id != '') {
$stmt = $pdo->prepare("select hostname,description from host where id=?");
$stmt->execute(array(intval($host_id)));
$res1 = $stmt->fetch(PDO::FETCH_ASSOC);
// $res1 = db_fetch_row("select hostname,description from host where id=" . intval($host_id));
if ($res1) {
if ($hostname == '') {
$hostname = $res1['description'];
$map->nodes[$node->name]->add_hint("hostname", $hostname);
}
if ($address == '') {
$address = $res1['hostname'];
$map->nodes[$node->name]->add_hint("address", $address);
}
}
}
// by now, if there was a host_id, all 3 are populated. If not, then we should try one of the others to get a host_id
else {
if ($address != '') {
$stmt = $pdo->prepare("select id,description from host where hostname=?");
$stmt->execute(array($address));
$res2 = $stmt->fetch(PDO::FETCH_ASSOC);
// $res2 = db_fetch_row("select id,description from host where hostname='" . mysql_real_escape_string($address)
// . "'");
if ($res2) {
$host_id = $res2['id'];
$map->nodes[$node->name]->add_hint("cacti_id", $host_id);
if ($hostname == '') {
$hostname = $res2['description'];
$map->nodes[$node->name]->add_hint("hostname", $hostname);
}
}
} elseif ($hostname != '') {
$stmt = $pdo->prepare("select id,description from host where description=?");
$stmt->execute(array($hostname));
$res3 = $stmt->fetch(PDO::FETCH_ASSOC);
// $res3 =
// db_fetch_row("select id,hostname from host where description='" . mysql_real_escape_string($hostname)
// . "'");
if ($res3) {
$host_id = $res3['id'];
$map->nodes[$node->name]->add_hint("cacti_id", $host_id);
if ($address == '') {
$address = $res3['hostname'];
$map->nodes[$node->name]->add_hint("address", $address);
}
}
}
}
if ($host_id != '') {
$info = $config['base_url'] . "host.php?id=" . $host_id;
$tgt = "cactimonitor:$host_id";
$map->nodes[$node->name]->targets = array (array (
$tgt,
'',
'',
0,
$tgt
));
$map->nodes[$node->name]->infourl[IN] = $info;
}
print " $host_id $hostname $address\n";
}
// Now lets go through the links
// we want links where at least one of the nodes has a cacti_id, and where either interface_in or interface_out is set
foreach ($map->links as $link) {
if (isset($link->a)) {
$name = $link->name;
$a = $link->a->name;
$b = $link->b->name;
$int_in = $link->get_hint("in_interface");
$int_out = $link->get_hint("out_interface");
$a_id = intval($map->nodes[$a]->get_hint("cacti_id"));
$b_id = intval($map->nodes[$b]->get_hint("cacti_id"));
print "LINK $name\n";
if (count($link->targets) == 0 || $overwrite_targets ) {
if ((($a_id + $b_id) > 0) && ($int_out . $int_in == '')) {
print " (could do if there were interfaces)\n";
}
if ((($a_id + $b_id) == 0) && ($int_out . $int_in != '')) {
print " (could do if there were host_ids)\n";
}
$tgt_interface = "";
$tgt_host = "";
if ($a_id > 0 && $int_out != '') {
print " We'll use the A end.\n";
$tgt_interface = $int_out;
$tgt_host = $a_id;
$ds_names = ":traffic_in:traffic_out";
} elseif ($b_id > 0 && $int_in != '') {
print " We'll use the B end and reverse it.\n";
$tgt_interface = $int_in;
$tgt_host = $b_id;
$ds_names = ":traffic_out:traffic_in";
} else {
print " No useful ends on this link - fill in more detail (host id, IP) on either NODE $a or $b\n";
}
if ($tgt_host != "") {
$int_list = explode(":::", $tgt_interface);
$total_speed = 0;
$total_target = array ();
foreach ($int_list as $interface) {
print " Interface: $interface\n";
foreach (array ('ifName', 'ifDescr', 'ifAlias') as $field) {
$stmt = $pdo->prepare("select data_local.id, data_source_path, host_snmp_cache.snmp_index from data_template_data, data_local,snmp_query, host_snmp_cache where data_template_data.local_data_id=data_local.id and host_snmp_cache.snmp_query_id = snmp_query.id and data_local.host_id=host_snmp_cache.host_id and data_local.snmp_query_id=host_snmp_cache.snmp_query_id and data_local.snmp_index=host_snmp_cache.snmp_index and host_snmp_cache.host_id=? and host_snmp_cache.field_name=? and host_snmp_cache.field_value=? and data_local.data_template_id=? order by data_template_data.id desc limit 1;");
$stmt->execute(array($tgt_host, $field, $interface, $data_template_id));
$res4 = $stmt->fetch(PDO::FETCH_ASSOC);
// $SQL =
// sprintf(
// "select data_local.id, data_source_path, host_snmp_cache.snmp_index from data_template_data, data_local,snmp_query, host_snmp_cache where data_template_data.local_data_id=data_local.id and host_snmp_cache.snmp_query_id = snmp_query.id and data_local.host_id=host_snmp_cache.host_id and data_local.snmp_query_id=host_snmp_cache.snmp_query_id and data_local.snmp_index=host_snmp_cache.snmp_index and host_snmp_cache.host_id=%d and host_snmp_cache.field_name='%s' and host_snmp_cache.field_value='%s' and data_local.data_template_id=%d order by data_template_data.id desc limit 1;",
// $tgt_host, $field, mysql_real_escape_string($interface), $data_template_id);
// $res4 = db_fetch_row($SQL);
if ($res4)
break;
}
// if we found one, add the interface to the targets for this link
if ($res4) {
$target = $res4['data_source_path'];
$local_data_id = $res4['id'];
$snmp_index = $res4['snmp_index'];
$tgt = str_replace("<path_rra>", $config["rra_path"], $target);
$tgt = $tgt . $ds_names;
if ($use_dsstats) {
$map->links[$link->name]->targets[] = array (
$tgt,
'',
'',
0,
$tgt
);
} else {
$tgt = "8*dsstats:$local_data_id" . $ds_names;
$map->links[$link->name]->targets[] = array (
$tgt,
'',
'',
0,
$tgt
);
}
$stmt_speed = $pdo->prepare("select field_value from host_snmp_cache where field_name='ifSpeed' and host_id=? and snmp_index=?");
$stmt_speed->execute(array($tgt_host, $snmp_index));
$speed = $stmt_speed->fetchColumn();
$stmt_hspeed = $pdo->prepare("select field_value from host_snmp_cache where field_name='ifHighSpeed' and host_id=? and snmp_index=?");
$stmt_hspeed->execute(array($tgt_host, $snmp_index));
$hspeed = $stmt_hspeed->fetchColumn();
// $SQL_speed =
// "select field_value from host_snmp_cache where field_name='ifSpeed' and host_id=$tgt_host and snmp_index=$snmp_index";
// $speed = db_fetch_cell($SQL_speed);
// $SQL_hspeed =
// "select field_value from host_snmp_cache where field_name='ifHighSpeed' and host_id=$tgt_host and snmp_index=$snmp_index";
// $hspeed = db_fetch_cell($SQL_hspeed);
if ($hspeed && intval($hspeed) > 20)
$total_speed += ($hspeed * 1000000);
else if ($speed)
$total_speed += intval($speed);
$stmt_graph = $pdo->prepare("select graph_templates_item.local_graph_id FROM graph_templates_item,graph_templates_graph,data_template_rrd where graph_templates_graph.local_graph_id = graph_templates_item.local_graph_id and task_item_id=data_template_rrd.id and local_data_id=? LIMIT 1;");
$stmt_graph->execute(array($local_data_id));
$graph_id = $stmt_graph->fetchColumn();
// $SQL_graphid =
// "select graph_templates_item.local_graph_id FROM graph_templates_item,graph_templates_graph,data_template_rrd where graph_templates_graph.local_graph_id = graph_templates_item.local_graph_id and task_item_id=data_template_rrd.id and local_data_id=$local_data_id LIMIT 1;";
// $graph_id = db_fetch_cell($SQL_graphid);
if ($graph_id) {
$overlib = sprintf($fmt_cacti_graph, $graph_id);
$infourl = sprintf($fmt_cacti_graphpage, $graph_id);
print " INFO $infourl\n";
print " OVER $overlib\n";
$map->links[$name]->overliburl[IN][] = $overlib;
$map->links[$name]->overliburl[OUT][] = $overlib;
$map->links[$name]->infourl[IN] = $infourl;
$map->links[$name]->infourl[OUT] = $infourl;
} else {
print " Couldn't find a graph that uses this rrd??\n";
}
} else {
print " Failed to find RRD file for $tgt_host/$interface\n";
}
}
print " SPEED $total_speed\n";
$map->links[$name]->max_bandwidth_in = $total_speed;
$map->links[$name]->max_bandwidth_out = $total_speed;
$map->links[$name]->max_bandwidth_in_cfg = nice_bandwidth($total_speed);
$map->links[$name]->max_bandwidth_out_cfg = nice_bandwidth($total_speed);
if ($map_widths) {
foreach ($width_map as $map_speed => $map_width) {
if ($total_speed <= $map_speed) {
$map->links[$name]->width = $width_map{$map_speed};
print " WIDTH " . $width_map{$map_speed}. "\n";
continue 2;
}
}
}
}
} else {
print "Skipping link with targets\n";
}
}
}
$map->WriteConfig($outputmapfile);
print "Wrote config to $outputmapfile\n";

View File

@ -0,0 +1,348 @@
<?php
# defaults. Should be overwritten by the cacti config.
$cacti_base = '../../';
$cacti_url = '/';
$width = 4000;
$height = 3000;
require_once 'editor-config.php';
// check if the goalposts have moved
if( is_dir($cacti_base) && file_exists($cacti_base."/include/global.php") )
{
// include the cacti-config, so we know about the database
include_once($cacti_base."/include/global.php");
$config['base_url'] = (isset($config['url_path'])? $config['url_path'] : $cacti_url);
$cacti_found = TRUE;
}
elseif( is_dir($cacti_base) && file_exists($cacti_base."/include/config.php") )
{
// include the cacti-config, so we know about the database
include_once($cacti_base."/include/config.php");
$config['base_url'] = (isset($config['url_path'])? $config['url_path'] : $cacti_url);
$cacti_found = TRUE;
}
else
{
print "You need to fix your editor-config.php\n";
exit();
}
include_once($cacti_base."/lib/snmp.php");
if(!function_exists("cacti_snmp_get"))
{
die("Cacti SNMP functions are not available");
}
# figure out which template has interface traffic. This might be wrong for you.
$data_template = "Interface - Traffic";
$data_template_id = db_fetch_cell("select id from data_template where name='".mysql_real_escape_string($data_template)."'");
$Interfaces_SQL = "select host.snmp_version,host.snmp_community,host.snmp_username,host.snmp_password,host.snmp_auth_protocol,host.snmp_priv_passphrase,host.snmp_priv_protocol,host.snmp_context,host.snmp_port,host.snmp_timeout,host.description, host.hostname, host.disabled, host_snmp_cache.* from host_snmp_cache,host where host_snmp_cache.host_id=host.id and (field_name='ifDescr' or field_name='ifName' or field_name='ifIP' or field_name='ifAlias') and host.disabled<>'on' and field_value<>'127.0.0.1' and field_value<>'0.0.0.0' and host.status=3 and host.snmp_version>0;";
$queryrows = db_fetch_assoc($Interfaces_SQL);
if( is_array($queryrows) && sizeof($queryrows) > 0 )
{
foreach ($queryrows as $line)
{
$key =sprintf( "%06d-%010d",$line['host_id'],$line['snmp_index']);
$hosts[$line['host_id']]['description'] = $line['description'];
$hosts[$line['host_id']]['hostname'] = $line['hostname'];
$hosts[$line['host_id']]['snmp_version'] = $line['snmp_version'];
$hosts[$line['host_id']]['snmp_username'] = $line['snmp_username'];
$hosts[$line['host_id']]['snmp_password'] = $line['snmp_password'];
$hosts[$line['host_id']]['snmp_auth_protocol'] = $line['snmp_auth_protocol'];
$hosts[$line['host_id']]['snmp_context'] = $line['snmp_context'];
$hosts[$line['host_id']]['snmp_port'] = $line['snmp_port'];
$hosts[$line['host_id']]['snmp_timeout'] = $line['snmp_timeout'];
$hosts[$line['host_id']]['snmp_priv_protocol'] = $line['snmp_priv_protocol'];
$hosts[$line['host_id']]['snmp_priv_passphrase'] = $line['snmp_priv_passphrase'];
$hosts[$line['host_id']]['snmp_community'] = $line['snmp_community'];
$interfaces[$key]['index'] = $line['snmp_index'];
$interfaces[$key]['host'] = $line['host_id'];
if($line['field_name'] == 'ifIP') $interfaces[$key]['ip'] = $line['field_value'];
if($line['field_name'] == 'ifName') $interfaces[$key]['name'] = $line['field_value'];
if($line['field_name'] == 'ifDescr') $interfaces[$key]['descr'] = $line['field_value'];
if($line['field_name'] == 'ifAlias') $interfaces[$key]['alias'] = $line['field_value'];
}
}
$count=0;
if(file_exists("mapper-cache.txt"))
{
print "Reading Netmask cache...\n";
$fd = fopen("mapper-cache.txt","r");
while(!feof($fd))
{
$str = fgets($fd,4096);
$str=str_replace("\r", "", $str);
trim($str);
list($key,$mask) = explode("\t",$str);
if(preg_match("/^(\d+\.\d+\.\d+\.\d+)$/",$mask,$m) && $mask != '0.0.0.0')
{ $interfaces[$key]['netmask'] = $m[1]; $count++; }
}
fclose($fd);
}
print "$count netmasks in the cache.\n";
print "Collected information on ".sizeof($interfaces)." interfaces and ".sizeof($hosts)." hosts.\n";
$cleaned=0;
foreach($interfaces as $key=>$int)
{
if(!isset($int['ip']))
{
unset($interfaces[$key]);
$cleaned++;
}
else
{
$interfaces[$key]['nicename'] = ( isset($int['name'])?$int['name']:( isset($int['descr'])?$int['descr']: (isset($int['alias'])?$int['alias']:"Interface #".$int['index']) ) );
}
}
print "Removed $cleaned interfaces from search, which have no IP address.\n";
$count=0;
foreach($interfaces as $key=>$int)
{
if(!isset($int['netmask']))
{
$oid = ".1.3.6.1.2.1.4.20.1.3.".$int['ip'];
$hostid = $int['host'];
if($count<100)
{
print "Fetching Netmask via SNMP for Host ".$int['host']."//".$int['ip']." from $oid\n";
$result = cacti_snmp_get(
$hosts[$hostid]["hostname"],
$hosts[$hostid]["snmp_community"],
$oid,
$hosts[$hostid]["snmp_version"],
$hosts[$hostid]["snmp_username"],
$hosts[$hostid]["snmp_password"],
$hosts[$hostid]["snmp_auth_protocol"],
$hosts[$hostid]["snmp_priv_passphrase"],
$hosts[$hostid]["snmp_priv_protocol"],
$hosts[$hostid]["snmp_context"],
$hosts[$hostid]["snmp_port"],
$hosts[$hostid]["snmp_timeout"],
SNMP_WEBUI);
if($result != FALSE && preg_match("/^\d+.\d+.\d+.\d+$/",$result))
{
print "$result|\n";
$interfaces[$key]['netmask'] = $result;
}
else
{
print "No useful result.\n";
unset($interfaces[$key]);
}
$count++;
}
}
}
$count = 0;
print "Writing Netmask cache...\n";
$fd = fopen("mapper-cache.txt","w");
foreach($interfaces as $key=>$int)
{
if(isset($int['netmask']))
{
fputs($fd,$key."\t".$int['netmask']."\n");
$count++;
}
}
fclose($fd);
print "Wrote $count cache entries.\n";
# SNMP netmask => .1.3.6.1.2.1.4.20.1.3.10.1.1.254
# SNMP interface index => .1.3.6.1.2.1.4.20.1.2.10.1.1.254
$count=0;
foreach($interfaces as $key=>$int)
{
if(isset($int['netmask']))
{
$network = get_network($int['ip'],$int['netmask'])."/".get_cidr($int['netmask']);
$interfaces[$key]['network'] = $network;
$networks[$network] []= $key;
$count++;
}
else
{
print $int['ip']."\n";
}
}
print "Assembled $count different network/netmask pairs\n";
$link_config = "";
$node_config = "";
$nodes_seen = array();
$count=0;
$linkid = 0;
$lannodeid = 0;
foreach ($networks as $network=>$members)
{
if(sizeof($members)<2)
{
unset($networks[$network]);
$count++;
}
if(sizeof($members)==2)
{
print "Create LINK between\n";
foreach($members as $int)
{
$h = $interfaces[$int]['host'];
print " ".$interfaces[$int]['nicename'];
print " on ".$hosts[$h]['description'];
print " (".$hosts[$h]['hostname'].")\n";
$nodes_seen[$h]=1;
}
$linkid++;
$link_config .= "LINK link_$linkid\nWIDTH 4\n";
$link_config .= "\tNODES node_".$interfaces[$members[0]]['host']." node_".$interfaces[$members[1]]['host']."\n";
$link_config .= "\tSET in_interface ".$interfaces[$members[1]]['nicename']."\n";
$link_config .= "\tSET out_interface ".$interfaces[$members[0]]['nicename']."\n";
$link_config .= "\n";
}
if(sizeof($members)>2)
{
print "Create LAN NODE called $network and add LINKs from these NODEs to it:\n";
$x = rand(0,$width); $y = rand(0,$height);
$lan_key = preg_replace("/[.\/]/","_",$network);
$node_config .= "NODE LAN_$lan_key\nLABELBGCOLOR 255 240 240 \n\tPOSITION $x $y\n\tLABEL $network\n\tICON 96 24 rbox\n\tLABELOFFSET C\n\tLABELOUTLINECOLOR none\nUSESCALE none in\n\n";
foreach($members as $int)
{
$h = $interfaces[$int]['host'];
print " $int:: ".$interfaces[$int]['nicename'];
print " on ".$hosts[$h]['description'];
print " (".$hosts[$h]['hostname'].")\n";
$nodes_seen[$h]=1;
$linkid++;
$link_config .= "LINK link_$linkid\n";
$link_config .= "SET out_interface ".$interfaces[$int]['nicename']."\n";
$link_config .= "\tNODES node_$h LAN_$lan_key\n\tWIDTH 2\n\tOUTCOMMENT {link:this:out_interface}\n";
}
print "\n";
}
}
print "Trimmed $count networks with only one member interface\n";
foreach ($nodes_seen as $h=>$c)
{
$x = rand(0,$width); $y = rand(0,$height);
$node_config .= "NODE node_$h\n\tSET cacti_id $h\n";
$node_config .= "\tLABEL ".$hosts[$h]['description']."\n";
$node_config .= "\tPOSITION $x $y\n";
$node_config .= "\tUSESCALE cactiupdown in \n";
$node_config .= "\tLABELFONTCOLOR contrast\n";
$node_config .= "\n\n";
}
$fd = fopen("automap.cfg","w");
fputs($fd,"HTMLSTYLE overlib\nBGCOLOR 92 92 92\nWIDTH $width\nHEIGHT $height\nFONTDEFINE 30 GillSans 8\n");
fputs($fd,"FONTDEFINE 20 GillSans 10\nFONTDEFINE 10 GillSans 9\n");
fputs($fd,"SCALE DEFAULT 0 0 255 0 0\nSCALE DEFAULT 0 10 32 32 32 0 0 255\nSCALE DEFAULT 10 40 0 0 255 0 255 0\nSCALE DEFAULT 40 55 0 255 0 255 255 0\nSCALE DEFAULT 55 100 240 240 0 255 0 0\n");
fputs($fd,"\nSCALE cactiupdown 0 0.5 192 192 192 \nSCALE cactiupdown 0.5 1.5 255 0 0 \nSCALE cactiupdown 1.5 2.5 0 0 255 \nSCALE cactiupdown 2.5 3.5 0 255 0 \nSCALE cactiupdown 3.5 4.5 255 255 0 \n");
fputs($fd,"\nLINK DEFAULT\nBWSTYLE angled\nBWLABEL bits\nBWFONT 30\nCOMMENTFONT 30\n\n");
fputs($fd,"\nNODE DEFAULT\nLABELFONT 10\n\n");
fputs($fd,$node_config);
fputs($fd,$link_config);
fclose($fd);
///////////////////////////////////////////////////////////////
function ip_to_int($_ip)
{
if(preg_match("/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/",$_ip,$matches))
{
$_output=0;
for($i=1;$i<5;$i++)
{
$_output<<=8;
$_output+=$matches[$i];
}
return($_output);
}
else
{
print "Something funny: $_ip\n";
return(-1);
}
}
function int_to_ip($_int)
{
$tmp=$_int;
for ($i=0; $i < 4; $i++)
{
$IPBit[]=($tmp & 255);
$tmp>>=8;
}
$_output=sprintf("%d.%d.%d.%d", $IPBit[3], $IPBit[2], $IPBit[1], $IPBit[0]);
return ($_output);
}
function get_network($_ip, $_mask)
{
$_int1=ip_to_int($_ip);
$_mask1=ip_to_int($_mask);
$_network=$_int1 & ($_mask1);
return (int_to_ip($_network));
}
function get_cidr($mask)
{
$lookup = array(
"255.255.255.255"=>"32",
"255.255.255.254"=>"31",
"255.255.255.252"=>"30",
"255.255.255.248"=>"29",
"255.255.255.240"=>"28",
"255.255.255.224"=>"27",
"255.255.255.192"=>"26",
"255.255.255.128"=>"25",
"255.255.255.0"=>"24",
"255.255.254.0"=>"23",
"255.255.252.0"=>"22",
"255.255.248.0"=>"21",
"255.255.240.0"=>"20",
"255.255.224.0"=>"19",
"255.255.192.0"=>"18",
"255.255.128.0"=>"17",
"255.255.0.0"=>"16",
"255.254.0.0"=>"15",
"255.252.0.0"=>"14",
"0.0.0.0.0"=>"0"
);
if($lookup[$mask]) return ($lookup[$mask]);
print "HUH: $mask\n";
return("-1");
}

View File

@ -0,0 +1,303 @@
<?php
#
# Change the uncommented line to point to your Cacti installation
#
$cacti_base = dirname(__FILE__)."/../../";
# $cacti_base = "C:/xampp/htdocs/cacti/";
# $cacti_base = "/var/www/html/cacti/";
# $cacti_base = "/Applications/XAMPP/htdocs/cacti/";
// check if the goalposts have moved
if( is_dir($cacti_base) && file_exists($cacti_base."/include/global.php") )
{
// include the cacti-config, so we know about the database
require_once($cacti_base."/include/global.php");
}
elseif( is_dir($cacti_base) && file_exists($cacti_base."/include/config.php") )
{
// include the cacti-config, so we know about the database
require_once($cacti_base."/include/config.php");
}
else
{
die("Couldn't find a usable Cacti config - check the first few lines of ".__FILE__."\n");
}
require_once '../lib/Weathermap.class.php';
require_once 'Console/Getopt.php';
$reverse = 0;
$inputfile = "";
$outputfile = "";
$converted = 0;
$candidates = 0;
$totaltargets = 0;
$cg=new Console_Getopt();
$short_opts='';
$long_opts=array
(
"help",
"input=",
"output=",
"debug",
"reverse",
);
$args=$cg->readPHPArgv();
$ret=$cg->getopt($args, $short_opts, $long_opts);
if (PEAR::isError($ret)) { die ("Error in command line: " . $ret->getMessage() . "\n (try --help)\n"); }
$gopts=$ret[0];
if (sizeof($gopts) > 0)
{
foreach ($gopts as $o)
{
switch ($o[0])
{
case '--debug':
$weathermap_debugging=TRUE;
break;
case '--input':
$inputfile=$o[1];
break;
case '--output':
$outputfile=$o[1];
break;
case '--reverse':
$reverse = 1;
break;
case 'help':
default:
print "Weathermap DSStats converter. Converts rrd targets to DSStats\n";
print "-------------------------------------------------------------\n";
print "Usage: php convert-to-dstats.php [options]\n\n";
print " --input {filename} - File to read from\n";
print " --output {filename} - File to write to\n";
# print " --reverse - Convert from DSStats to RRDtool instead\n";
print " --debug - Enable debugging output\n";
print " --help - Show this message\n";
exit();
}
}
}
if($inputfile == "" || $outputfile == "")
{
print "You must specify an input and output file. See --help.\n";
exit();
}
$map = new WeatherMap;
$map->context = 'cacti';
$map->rrdtool = read_config_option("path_rrdtool");
print "Reading config from $inputfile\n";
$map->ReadConfig($inputfile);
$map->DatasourceInit();
$map->ProcessTargets();
$allitems = $map->buildAllItemsList();
foreach ($allitems as $myobj)
{
$type = $myobj->my_type();
$name=$myobj->name;
wm_debug ("ReadData for $type $name: \n");
if( ($type=='LINK' && isset($myobj->a)) || ($type=='NODE' && !is_null($myobj->x) ) )
{
if (count($myobj->targets)>0)
{
$totaltargets++;
$tindex = 0;
foreach ($myobj->targets as $target)
{
wm_debug ("ReadData: New Target: $target[4]\n");
$targetstring = $target[0];
$multiply = $target[1];
if($reverse == 0 && $target[5] == "WeatherMapDataSource_rrd")
{
$candidates++;
# list($in,$out,$datatime) = $map->plugins['data'][ $target[5] ]->ReadData($targetstring, $map, $myobj);
wm_debug("ConvertDS: $targetstring is a candidate for conversion.");
$rrdfile = $targetstring;
$multiplier = 8;
$dsnames[IN] = "traffic_in";
$dsnames[OUT] = "traffic_out";
if(preg_match("/^(.*\.rrd):([\-a-zA-Z0-9_]+):([\-a-zA-Z0-9_]+)$/",$targetstring,$matches))
{
$rrdfile = $matches[1];
$dsnames[IN] = $matches[2];
$dsnames[OUT] = $matches[3];
wm_debug("ConvertDS: Special DS names seen (".$dsnames[IN]." and ".$dsnames[OUT].").\n");
}
if(preg_match("/^rrd:(.*)/",$rrdfile,$matches))
{
$rrdfile = $matches[1];
}
if(preg_match("/^gauge:(.*)/",$rrdfile,$matches))
{
$rrdfile = $matches[1];
$multiplier = 1;
}
if(preg_match("/^scale:([+-]?\d*\.?\d*):(.*)/",$rrdfile,$matches))
{
$rrdfile = $matches[2];
$multiplier = $matches[1];
}
$path_rra = $config["rra_path"];
$db_rrdname = $rrdfile;
$db_rrdname = str_replace($path_rra,"<path_rra>",$db_rrdname);
# special case for relative paths
$db_rrdname = str_replace("../../rra","<path_rra>",$db_rrdname);
if($db_rrdname != $rrdfile)
{
wm_debug("ConvertDS: Looking for $db_rrdname in the database.");
$SQLcheck = "select data_template_data.local_data_id from data_template_data,data_template_rrd where data_template_data.local_data_id=data_template_rrd.local_data_id and data_template_data.data_source_path='".mysql_real_escape_string($db_rrdname)."'";
wm_debug("ConvertDS: ".$SQLcheck);
$results = db_fetch_assoc($SQLcheck);
if( (sizeof($results) > 0) && (isset($results[0]['local_data_id']) ) )
{
$new_target = sprintf("dsstats:%d:%s:%s", $results[0]['local_data_id'], $dsnames[IN], $dsnames[OUT]);
$m = $multiply * $multiplier;
if( $m != 1)
{
if($m == -1) $new_target = "-".$new_target;
if($m == intval($m))
{
$new_target = sprintf("%d*%s",$m,$new_target);
}
else
{
$new_target = sprintf("%f*%s",$m,$new_target);
}
}
wm_debug("ConvertDS: Converting to $new_target");
$converted++;
if($type == 'NODE')
{
$map->nodes[$name]->targets[$tindex][4] = $new_target;
}
if($type == 'LINK')
{
$map->links[$name]->targets[$tindex][4] = $new_target;
}
}
else
{
wm_warn("ConvertDS: Failed to find a match for $db_rrdname - can't convert to DSStats.");
}
}
else
{
wm_warn("ConvertDS: $rrdfile doesn't match with $path_rra - not bothering to look in the database.");
}
}
// XXX - not implemented yet!
if($reverse == 1 && $target[5] == "WeatherMapDataSource_dsstats" && 1==0)
{
$candidates++;
# list($in,$out,$datatime) = $map->plugins['data'][ $target[5] ]->ReadData($targetstring, $map, $myobj);
wm_debug("ConvertDS: $targetstring is a candidate for conversion.");
$multiplier = 1;
$dsnames[IN] = "traffic_in";
$dsnames[OUT] = "traffic_out";
$path_rra = $config["rra_path"];
$db_rrdname = $rrdfile;
$db_rrdname = str_replace($path_rra,"<path_rra>",$db_rrdname);
# special case for relative paths
$db_rrdname = str_replace("../../rra","<path_rra>",$db_rrdname);
wm_debug("ConvertDS: Looking for $db_rrdname in the database.");
$SQLcheck = "select data_template_data.local_data_id from data_template_data,data_template_rrd where data_template_data.local_data_id=data_template_rrd.local_data_id and data_template_data.data_source_path='".mysql_real_escape_string($db_rrdname)."'";
wm_debug("ConvertDS: ".$SQLcheck);
$results = db_fetch_assoc($SQLcheck);
if( (sizeof($results) > 0) && (isset($results[0]['local_data_id']) ) )
{
$new_target = sprintf("dsstats:%d:%s:%s", $results[0]['local_data_id'], $dsnames[IN], $dsnames[OUT]);
$m = $multiply * $multiplier;
if( $m != 1)
{
if($m == -1) $new_target = "-".$new_target;
if($m == intval($m))
{
$new_target = sprintf("%d*%s",$m,$new_target);
}
else
{
$new_target = sprintf("%f*%s",$m,$new_target);
}
}
wm_debug("ConvertDS: Converting to $new_target");
$converted++;
if($type == 'NODE')
{
$map->nodes[$name]->targets[$tindex][4] = $new_target;
}
if($type == 'LINK')
{
$map->links[$name]->targets[$tindex][4] = $new_target;
}
}
else
{
wm_warn("ConvertDS: Failed to find a match for $db_rrdname - can't convert back to rrdfile.");
}
}
$tindex++;
}
wm_debug ("ReadData complete for $type $name\n");
}
else
{
wm_debug("ReadData: No targets for $type $name\n");
}
}
else
{
wm_debug("ReadData: Skipping $type $name that looks like a template\n.");
}
}
$map->WriteConfig($outputfile);
print "Wrote new config to $outputfile\n";
print "$totaltargets targets, $candidates rrd-based targets, $converted were actually converted.\n";
// vim:ts=4:sw=4:

View File

@ -0,0 +1,5 @@
<?php
header("Location:../index.php");
// vim:ts=4:sw=4:

View File

@ -0,0 +1,83 @@
<?php
require_once 'Weathermap.class.php';
// EDIT THESE!
// Which file to read in (the big map)
$input_mapfile = "configs/09-test.conf";
// how big do you want your new maps to be?
$desired_width = 640;
$desired_height = 480;
$map = new WeatherMap;
$map->ReadConfig($input_mapfile);
print "Size of source is ".$map->width."x".$map->height."\n";
$rows = intval($map->height/$desired_height)+1;
$cols = intval($map->width/$desired_width)+1;
$num = $rows * $cols;
if($num == 1)
{
print "This map is already within your constraints.\n";
}
else
{
print "We'll need to make $num ($cols x $rows) smaller maps\n";
for($row=0;$row < $rows; $row++)
{
for($col=0;$col<$cols; $col++)
{
print "=====================================\nMaking the submap $col,$row\n";
$min_x = $col*$desired_width;
$min_y = $row*$desired_height;
$max_x = ($col+1)*$desired_width;
$max_y = ($row+1)*$desired_height;
print "We'll read the map, and throw out everything not inside ($min_x,$min_y)->($max_x,$max_y)\n";
$map = new WeatherMap;
$map->ReadConfig($input_mapfile);
foreach ($map->nodes as $node)
{
$target = $node->name;
if( ($node->x < $min_x) || ($node->x >= $max_x) ||
($node->y < $min_y) || ($node->y >= $max_y) )
{
print "$target falls outside of this map. Deleting it and links that use it.\n";
foreach ($map->links as $link)
{
if( ($target == $link->a->name) || ($target == $link->b->name) )
{
print "link $link->name uses it. Deleted.\n";
unset($map->links[$link->name]);
}
}
unset($map->nodes[$target]);
}
else
{
print "$target is OK, but will be moved for the new map from ".$node->x.",".$node->y." to ";
$x = $node->x;
$y = $node->y;
$x = $node->x - $min_x;
$y = $node->y - $min_y;
$map->nodes[$target]->x = $x;
$map->nodes[$target]->y = $y;
print "$x,$y\n";
}
}
$output_mapfile = $input_mapfile."-".$row."-".$col.".conf";
$map->width = $desired_width;
$map->height = $desired_height;
$map->background="";
$map->WriteConfig($output_mapfile);
}
}
}

View File

@ -0,0 +1,105 @@
<?php
//
// Change the uncommented line to point to your Cacti installation
//
$cacti_base = dirname(__FILE__) . '/../../';
// $cacti_base = 'C:/xampp/htdocs/cacti/';
// $cacti_base = '/var/www/html/cacti/';
// $cacti_base = '/Applications/XAMPP/htdocs/cacti/';
// check if the goalposts have moved
if (is_dir($cacti_base) && file_exists($cacti_base . '/include/global.php')) {
// include the cacti-config, so we know about the database
require_once $cacti_base . '/include/global.php';
} elseif (is_dir($cacti_base) && file_exists($cacti_base . '/include/config.php')) {
// include the cacti-config, so we know about the database
require_once $cacti_base . '/include/config.php';
} else {
die("Couldn't find a usable Cacti config - check the first few lines of " . __FILE__
. "\n");
}
require_once 'Weathermap.class.php';
require_once 'Console/Getopt.php';
$reverse = 0;
$inputfile = '';
$outputfile = '';
$converted = 0;
$candidates = 0;
$totaltargets = 0;
$cg = new Console_Getopt();
$short_opts = '';
$long_opts = array (
'help',
'input=',
'output=',
'debug'
);
$args = $cg->readPHPArgv();
$ret = $cg->getopt($args, $short_opts, $long_opts);
if (PEAR::isError($ret)) {
die('Error in command line: ' . $ret->getMessage() . "\n (try --help)\n");
}
$gopts = $ret[0];
if (count($gopts) > 0) {
foreach ($gopts as $o) {
switch ($o[0]) {
case '--debug':
$weathermap_debugging = true;
break;
case '--input':
$inputfile = $o[1];
break;
case '--output':
$outputfile = $o[1];
break;
case 'help':
default:
print "Weathermap DSStats converter. Converts rrd targets to DSStats\n";
print "-------------------------------------------------------------\n";
print "Usage: php convert-to-dstats.php [options]\n\n";
print " --input {filename} - File to read from\n";
print " --output {filename} - File to write to\n";
print " --debug - Enable debugging output\n";
print " --help - Show this message\n";
exit();
}
}
}
if ($inputfile === '' || $outputfile === '') {
print "You must specify an input and output file. See --help.\n";
exit();
}
$map = new WeatherMap;
$map->context = 'cacti';
$map->rrdtool = read_config_option('path_rrdtool');
print 'Reading config from '.$inputfile."\n";
$map->ReadConfig($inputfile);
// 'Draw' the map, so that we get dimensions for all the nodes
// and offsets for links are calculated.
$map->DrawMap(null);
// loop through all links
// adjust node offsets so that links come from correct side of nodes, and ideally still
// from underneath them (e.g. NE80 not NE)
$map->WriteConfig($outputfile);
print 'Wrote new config to '.$outputfile."\n";

View File

@ -0,0 +1,544 @@
# Automatically generated by php-weathermap v0.95
FONTDEFINE 10 VeraBd 20
FONTDEFINE 20 VeraIt 10
FONTDEFINE 30 fonts/Flareserif821BT 20
FONTDEFINE 40 fonts/almosnow.gdf
FONTDEFINE 50 fonts/NewsGothicMT 16
FONTDEFINE 60 fonts/GillSans 16
FONTDEFINE 70 fonts/Bedrock 26
FONTDEFINE 170 fonts/GillSans 10
WIDTH 1024
HEIGHT 768
HTMLOUTPUTFILE suite-1.html
IMAGEOUTPUTFILE suite-1.png
SET something_global exists
KEYPOS DEFAULT -1 -1 Traffic Load
KEYTEXTCOLOR 0 0 0
KEYOUTLINECOLOR 0 0 0
KEYBGCOLOR 255 255 255
BGCOLOR 192 192 192
TITLECOLOR 0 0 0
TIMECOLOR 0 0 0
SCALE DEFAULT 1 10 140 0 255
SCALE DEFAULT 10 25 32 32 255
SCALE DEFAULT 25 40 0 192 255
SCALE DEFAULT 40 55 0 240 0
SCALE DEFAULT 55 70 240 240 0
SCALE DEFAULT 70 85 255 192 0
SCALE DEFAULT 85 100 255 0 0
SCALE plain 0 100 255 255 255
SCALE plain_tag 0 0.5 255 255 255 red-ball-64.png
SCALE plain_tag 0.5 1.5 255 255 255 yellow-ball-64.png
SCALE plain_tag 1.5 2.5 255 255 255 green-ball-64.png
SCALE updown 0 0.9 255 0 0
SCALE updown 0.9 1.9 255 255 0
SCALE updown 1.9 2.9 0 255 0
# End of global section
# DEFAULT definitions:
NODE DEFAULT
LABEL {node:this:name}
ICON images/my_router.png
MAXVALUE 100
SET something_nodey exists
LINK DEFAULT
BANDWIDTH 100M
SET something_linky exists
# End of DEFAULTS section
# Node definitions:
NODE node1
POSITION 100 100
NODE node2
LABELOFFSET N
POSITION 200 100
SET something_nodey changes
NODE node3
LABELOFFSET S
POSITION 300 100
NODE node4
LABELOFFSET E
POSITION 350 100
NODE node5
LABELOFFSET W
POSITION 500 100
NODE node6
LABELOFFSET 20 20
POSITION 550 100
NODE node11
LABELOUTLINECOLOR none
LABELBGCOLOR none
LABELFONTCOLOR 255 255 255
POSITION 100 200
NODE node12
LABELOFFSET N
LABELOUTLINECOLOR 0 255 0
LABELBGCOLOR 255 0 0
LABELFONTCOLOR 255 255 0
POSITION 200 200
NODE node13
LABELOFFSET S
LABELOUTLINECOLOR 0 0 255
POSITION 300 200
NODE node14
LABELOFFSET E
LABELFONT 4
POSITION 350 200
NODE node15
LABELOFFSET W
LABELFONT 1
POSITION 500 200
NODE node16
LABELBGCOLOR none
LABELOFFSET 20 20
POSITION 550 200
NODE node20
LABELOFFSET W
LABELFONT 20
POSITION 100 420
LABELANGLE 90
NODE node21
LABELOFFSET E
LABELBGCOLOR none
LABELOUTLINECOLOR none
LABELFONT 20
POSITION node20 70 0
LABELANGLE 270
NODE node22
LABELOFFSET S
LABELBGCOLOR none
LABELOUTLINECOLOR none
LABELFONT 20
POSITION node21 70 0
LABELANGLE 180
NODE node23
LABELOFFSET S
LABELBGCOLOR none
LABELOUTLINECOLOR none
LABELFONT 20
POSITION node22 70 0
LABELANGLE 90
NODE font1
LABELFONT 1
ICON none
POSITION 650 50
NODE font2
LABELFONT 2
ICON none
POSITION font1 0 30
NODE font3
ICON none
POSITION font2 0 30
NODE font4
LABELFONT 4
ICON none
POSITION font3 0 30
NODE font5
LABELFONT 5
ICON none
POSITION font4 0 30
NODE tfont1
LABEL VeraBold
LABELFONT 10
ICON none
POSITION 850 50
NODE tfont2
LABEL VeraItalic
LABELFONT 20
ICON none
POSITION tfont1 0 30
NODE tfont3
LABEL FlareSerif821
LABELFONT 30
ICON none
POSITION tfont2 0 30
NODE tfont4
LABEL Almost Snow
LABELFONT 40
ICON none
POSITION tfont3 0 50
NODE tfont5
LABEL NewsGothicMT
LABELFONT 50
ICON none
POSITION tfont4 0 40
NODE tfont6
LABEL GillSans
LABELFONT 60
ICON none
POSITION tfont5 0 30
NODE tfont7
LABEL Bedrock
LABELFONT 70
ICON none
POSITION tfont6 0 30
NODE aicon1
LABEL box
LABELOFFSET C
AICONFILLCOLOR 255 255 255
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON 32 32 box
POSITION 350 300
NODE aicon2
LABEL round
LABELOFFSET C
AICONFILLCOLOR 255 255 255
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON 48 48 round
POSITION aicon1 70 0
NODE aicon3
LABEL rbox
LABELOFFSET C
AICONFILLCOLOR 255 255 255
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON 50 25 rbox
POSITION aicon2 70 0
NODE aicon_explain
LABEL These nodes have 'artifical icons'
LABELFONT 170
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON none
POSITION aicon2 0 50
NODE scaleup
INFOURL A
ICON 100 100 images/my_router.png
POSITION 650 500
NODE scaledown
ICON 100 100 images/bw_gradient_1024.png
POSITION 650 600
NODE scaledown2
LABELOFFSET N
LABELFONT 170
LABELOUTLINECOLOR none
LABELBGCOLOR none
INFOURL suite-2.html
ICON 100 100 tests/configs_suite-2.png
POSITION 650 400
NODE scalenote
LABEL The icons for these three nodes were scaled to fit
LABELFONT 170
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON none
POSITION scaledown 0 50
NODE node311
TARGET static:10:22
USESCALE plain in
POSITION 150 300
NODE node311a
LABEL subnode of node311 ({node:this:x},{node:this:y})
LABELFONT 2
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON none
POSITION node311 0 30
NODE node311aa
LABEL subnode of node311a ({node:this:x},{node:this:y})
LABELFONT 2
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON none
POSITION node311a 0 14
NODE node311aaa
LABEL Can be any font, and contain data - {node:node311:bandwidth_in} leases
LABELFONT 170
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON none
POSITION node311aa 0 14
NODE node311aaaa
LABEL also {node:node311:bandwidth_out} maximum (in another subnode)
LABELFONT 170
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON none
POSITION node311aaa 0 14
NODE node311b
LABEL subnode2
LABELFONT 1
ICON none
POSITION node311 -60 0
NODE node311c
LABEL subnode3
LABELFONT 1
ICON none
POSITION node311 60 0
NODE node311d
LABEL subnode4
LABELFONT 1
ICON none
POSITION node311 0 -30
NODE node411
ICON none
TARGET static:0:0
USESCALE updown in
POSITION 180 520
NODE node412
ICON none
TARGET static:1:1
USESCALE updown in
POSITION 250 520
NODE node413
ICON none
TARGET static:2:2
USESCALE updown in
POSITION 320 520
NODE note412
LABEL These nodes are using a special SCALE and TARGET to show up/down status
LABELFONT 170
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON none
POSITION node412 0 30
NODE node511
LABELOFFSET S
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON images/updown_{node:this:bandwidth_in}.png
TARGET static:0:0
USESCALE plain in
POSITION 180 600
NODE node512
LABELOFFSET S
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON images/updown_{node:this:bandwidth_in}.png
TARGET static:1:1
USESCALE plain in
POSITION 250 600
NODE node513
LABELOFFSET S
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON images/updown_{node:this:bandwidth_in}.png
TARGET static:2:2
USESCALE plain in
POSITION 320 600
NODE note512
LABEL These nodes are using a special TARGET and ICON to calculate an icon filename
LABELFONT 170
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON none
POSITION node512 0 50
NODE node521
LABELOFFSET S
LABELOUTLINECOLOR none
LABELBGCOLOR none
INFOURL A
ICON 32 32 images/{node:this:inscaletag}
TARGET static:0:0
USESCALE plain_tag in
POSITION 180 700
NODE node522
LABELOFFSET S
LABELOUTLINECOLOR none
LABELBGCOLOR none
INFOURL A
ICON 32 32 images/{node:this:inscaletag}
TARGET static:1:1
USESCALE plain_tag in
POSITION 250 700
NODE node523
LABELOFFSET S
LABELOUTLINECOLOR none
LABELBGCOLOR none
INFOURL A
ICON 32 32 images/{node:this:inscaletag}
TARGET static:2:2
USESCALE plain_tag in
POSITION 320 700
NODE note522
LABEL These nodes are using a special 'SCALE tag' and ICON to calculate an icon filename
LABELFONT 170
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON none
POSITION node522 0 50
NODE scale0
ICON none
TARGET static:0:0
POSITION 850 450
NODE scale1
ICON none
TARGET static:10:10
POSITION scale0 0 25
NODE scale2
ICON none
TARGET static:20:20
POSITION scale1 0 25
NODE scale3
ICON none
TARGET static:30:30
POSITION scale2 0 25
NODE scale4
ICON none
TARGET static:40:40
POSITION scale3 0 25
NODE scale5
ICON none
TARGET static:50:50
POSITION scale4 0 25
NODE scale6
ICON none
TARGET static:60:60
POSITION scale5 0 25
NODE scale7
ICON none
TARGET static:70:70
POSITION scale6 0 25
NODE scale8
ICON none
TARGET static:80:80
POSITION scale7 0 25
NODE scale9
ICON none
TARGET static:90:90
POSITION scale8 0 25
NODE scale10
ICON none
TARGET static:100:100
POSITION scale9 0 25
NODE notescale
LABEL These nodes are using a different SCALE again
LABELFONT 170
LABELANGLE 90
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON none
POSITION scale5 35 0
NODE node601
LABELOFFSET S
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON 32 32 images/grey-ball-64.png
TARGET static:2:2
USESCALE plain_tag in
# USEICONSCALE updown in
POSITION 950 450
NODE node602
LABELOFFSET S
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON 32 32 images/grey-ball-64.png
TARGET static:0:0
USESCALE plain_tag in
USEICONSCALE updown in
POSITION node601 0 60
NODE node603
LABELOFFSET S
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON 32 32 images/grey-ball-64.png
TARGET static:1:1
USESCALE plain_tag in
USEICONSCALE updown in
POSITION node602 0 60
NODE node604
LABELOFFSET S
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON 32 32 images/grey-ball-64.png
TARGET static:2:2
USESCALE plain_tag in
USEICONSCALE updown in
POSITION node603 0 60
NODE noteiconscale
LABEL These nodes are using the same ICON, but with USEICONSCALE
LABELANGLE 90
LABELFONT 170
LABELOUTLINECOLOR none
LABELBGCOLOR none
ICON none
POSITION node602 35 30

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -0,0 +1,206 @@
# Automatically generated by php-weathermap v0.91
BACKGROUND images/uk1024.png
FONTDEFINE 92 VeraIt 7
FONTDEFINE 102 Vera 8
TITLE Test Suite 2 - Nodes
HTMLOUTPUTFILE suite-2.html
IMAGEOUTPUTFILE suite-2.png
TIMEPOS 5 15 Created: %b %d %Y %H:%M:%S
KEYPOS DEFAULT -1 -1 Traffic Load
KEYTEXTCOLOR 0 0 0
KEYBGCOLOR 255 255 255
BGCOLOR 192 192 192
TITLECOLOR 0 0 0
TIMECOLOR 255 255 255
SCALE DEFAULT 1 10 140 0 255
SCALE DEFAULT 10 25 32 32 255
SCALE DEFAULT 25 40 0 192 255
SCALE DEFAULT 40 55 0 240 0
SCALE DEFAULT 55 70 240 240 0
SCALE DEFAULT 70 85 255 192 0
SCALE DEFAULT 85 100 255 0 0
# End of global section
# DEFAULT definitions:
NODE DEFAULT
LABEL {node:this:name}
ICON 64 64 images/hollow32.png
LABELOFFSET S
OVERLIBWIDTH 400
OVERLIBHEIGHT 200
LABELBGCOLOR none
LABELFONTCOLOR 255 255 255
LABELOUTLINECOLOR none
LABELFONTSHADOWCOLOR 0 0 0
MAXVALUE 100
SET sigdigits 1
LINK DEFAULT
OVERLIBWIDTH 400
OVERLIBHEIGHT 200
BWLABEL bits
BWFONT 102
COMMENTFONT 92
WIDTH 5
BANDWIDTH 100M
# End of DEFAULTS section
# Node definitions:
NODE Centre
POSITION 500 400
NODE NorthEast
POSITION 700 200
NODE NorthEast_telnet
LABEL
INFOURL telnet://northeast/
ICON 16 16 images/application_xp_terminal.png
POSITION NorthEast 44 -25
NODE NorthEast_www
LABEL
INFOURL http://northeast/
ICON 16 16 images/application_side_list.png
POSITION NorthEast 44 -5
NODE North
LABEL {node:this:sigdigits}
POSITION 500 200
NODE South
POSITION 500 600
NODE West
POSITION 300 400
NODE East
POSITION 700 400
NODE SouthEast
POSITION 749 720
NODE SouthWest
POSITION 300 600
NODE NorthWest
POSITION 300 200
NODE node20
POSITION 100 200
MAXVALUE 50
NODE node30
POSITION 100 400
MAXVALUE 30 60
NODE node100
LABELOFFSET C
POSITION 900 200
NODE node101
LABELOFFSET C
POSITION 695 305
NODE node102
LABELBGCOLOR 32 32 32
LABELOUTLINECOLOR 255 255 255
POSITION 900 600
# End of NODE section
# Link definitions:
LINK Link1
ARROWSTYLE compact
NODES Centre:N North:S
LINK Link2
ARROWSTYLE compact
NODES Centre:E East:W
LINK Link3
ARROWSTYLE 2 1
NODES Centre:S South:N
LINK Link4
ARROWSTYLE 3 2
NODES Centre:W West:E
LINK Link5
ARROWSTYLE 6 2
NODES Centre:NW NorthWest:SE
LINK Link6
ARROWSTYLE compact
BWOUTLINECOLOR none
BWBOXCOLOR none
NODES Centre:NE NorthEast:SW
LINK Link7
NODES Centre:SE SouthEast:NW
LINK Link8
NODES Centre:SW SouthWest:NE
LINK Link9
NODES NorthWest:N NorthEast:N
VIA 500 100
LINK Link9a
NODES NorthWest:NE NorthEast:NW
VIA 500 130
LINK middles
NODES NorthWest node20
LINK numeric
NODES node20:10:10 node30:-10:-10
LINK loop1
NODES East:N East:S
VIA 750 300
VIA 800 400
VIA 750 500
LINK parallel_1
NODES SouthWest:32:-12 South:-32:-12
LINK parallel_2
BWLABELPOS 20 80
NODES SouthWest:32:12 South:-32:12
LINK longloop
INCOMMENT This is a comment for the in-side of the link.
OUTCOMMENT MXUK1122
NODES South:SW West:SW
VIA 300 740
VIA 200 740
VIA 200 600
LINK nooutline
OUTLINECOLOR none
NODES node100:W node101:W
VIA 840 300
LINK withoutline
OUTLINECOLOR 255 0 0
NODES node100:E node101:E
VIA 960 300
LINK uni
NODES node100:S node101:N
SET bwlabel_padding 5
# End of LINK section
# That's All Folks!

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 KiB