1 | 85 | simandl | <?php |
2 | | | /** cacti-integrate.php |
3 | | | * |
4 | | | * Auto-fill a basic map file with as much information as possible from the |
5 | | | * Cacti database, using interface names and node ip/names as clues. |
6 | | | * |
7 | | | * See http://forums.cacti.net/about26544.html for more info |
8 | | | * |
9 | | | */ |
10 | | | $cacti_root = '/var/www/html/cacti/'; |
11 | | | |
12 | | | if (!file_exists($cacti_root . "/include/config.php")) { |
13 | | | $cacti_root = "../../.."; |
14 | | | |
15 | | | if (!file_exists($cacti_root . "/include/config.php")) { |
16 | | | print "Couldn't figure out where Cacti is. Edit the top line of the script.\n"; |
17 | | | exit(); |
18 | | | } |
19 | | | } |
20 | | | |
21 | | | ini_set('include_path', |
22 | | | ini_get('include_path') . PATH_SEPARATOR . $cacti_root . PATH_SEPARATOR . $cacti_root . '/plugins/weathermap' |
23 | | | . PATH_SEPARATOR . $cacti_root . '/plugins/weathermap/random-bits'); |
24 | | | |
25 | | | require_once 'Weathermap.class.php'; |
26 | | | require_once 'Console/Getopt.php'; |
27 | | | |
28 | | | include_once 'include/global.php'; |
29 | | | include_once 'include/config.php'; |
30 | | | |
31 | | | $cacti_base = $cacti_root; |
32 | | | $cacti_url = $config['url_path']; |
33 | | | |
34 | | | include_once 'editor-config.php'; |
35 | | | |
36 | | | // adjust width of link based on bandwidth. |
37 | | | // NOTE: These are bands - the value has to be up to or including the value in the list to match |
38 | | | $width_map = array ( |
39 | | | '1000000' => '1', // up to 1meg |
40 | | | '9999999' => '1', // 1-10meg |
41 | | | '10000000' => '2', // 10meg |
42 | | | '99999999' => '2', // 10-100meg |
43 | | | '100000000' => '4', // 100meg |
44 | | | '999999999' => '4', // 100meg-1gig |
45 | | | '1000000000' => '6', // 1gig |
46 | | | '9999999999' => '6', // 1gig-10gig |
47 | | | '10000000000' => '8', // 10gig |
48 | | | '99999999999' => '8' // 10gig-100gig |
49 | | | ); |
50 | | | |
51 | | | // check if the goalposts have moved |
52 | | | if (is_dir($cacti_base) && file_exists($cacti_base . "/include/global.php")) { |
53 | | | // include the cacti-config, so we know about the database |
54 | | | include_once($cacti_base . "/include/global.php"); |
55 | | | $config['base_url'] = (isset($config['url_path']) ? $config['url_path'] : $cacti_url); |
56 | | | $cacti_found = true; |
57 | | | } elseif (is_dir($cacti_base) && file_exists($cacti_base . "/include/config.php")) { |
58 | | | // include the cacti-config, so we know about the database |
59 | | | include_once($cacti_base . "/include/config.php"); |
60 | | | $config['base_url'] = (isset($config['url_path']) ? $config['url_path'] : $cacti_url); |
61 | | | $cacti_found = true; |
62 | | | } else { |
63 | | | print "You need to fix your editor-config.php\n"; |
64 | | | exit(); |
65 | | | } |
66 | | | |
67 | | | // the following are defaults. You can change those from the command-line |
68 | | | // options now. |
69 | | | |
70 | | | // set this to true to adjust the width of links according to speed |
71 | | | $map_widths = false; |
72 | | | |
73 | | | // set this to true to use DSStats targets instead of RRD file targets |
74 | | | $use_dsstats = false; |
75 | | | |
76 | | | $overwrite_targets = false; |
77 | | | |
78 | | | $outputmapfile = ""; |
79 | | | $inputmapfile = ""; |
80 | | | |
81 | | | // initialize object |
82 | | | $cg = new Console_Getopt(); |
83 | | | $short_opts = ''; |
84 | | | $long_opts = array ( |
85 | | | "help", |
86 | | | "input=", |
87 | | | "output=", |
88 | | | "debug", |
89 | | | "target-dsstats", |
90 | | | "target-rrdtool", |
91 | | | "overwrite-targets", |
92 | | | "speed-width-map" |
93 | | | ); |
94 | | | |
95 | | | $args = $cg->readPHPArgv(); |
96 | | | |
97 | | | $ret = $cg->getopt($args, $short_opts, $long_opts); |
98 | | | |
99 | | | if (PEAR::isError($ret)) { |
100 | | | die("Error in command line: " . $ret->getMessage() . "\n (try --help)\n"); |
101 | | | } |
102 | | | |
103 | | | $gopts = $ret[0]; |
104 | | | |
105 | | | $options_output = array (); |
106 | | | |
107 | | | if (sizeof($gopts) > 0) { |
108 | | | foreach ($gopts as $o) { |
109 | | | switch ($o[0]) { |
110 | | | case '--debug': |
111 | | | $weathermap_debugging = true; |
112 | | | break; |
113 | | | |
114 | | | case '--overwrite-targets': |
115 | | | $overwrite_targets = true; |
116 | | | break; |
117 | | | |
118 | | | case '--speed-width-map': |
119 | | | $map_widths = true; |
120 | | | break; |
121 | | | |
122 | | | case '--target-dsstats': |
123 | | | $use_dsstats = true; |
124 | | | break; |
125 | | | |
126 | | | case '--target-rrdtool': |
127 | | | $use_dsstats = false; |
128 | | | break; |
129 | | | |
130 | | | case '--output': |
131 | | | $outputmapfile = $o[1]; |
132 | | | break; |
133 | | | |
134 | | | case '--input': |
135 | | | $inputmapfile = $o[1]; |
136 | | | break; |
137 | | | |
138 | | | case '--help': |
139 | | | print "cacti-integrate.php\n"; |
140 | | | print |
141 | | | "Copyright Howard Jones, 2008-2010 howie@thingy.com\nReleased under the GNU Public License\nhttp://www.network-weathermap.com/\n\n"; |
142 | | | |
143 | | | print "Usage: php cacti-integrate.php [options]\n\n"; |
144 | | | |
145 | | | print " --input {filename} - read config from this file\n"; |
146 | | | print " --output {filename} - write new config to this file\n"; |
147 | | | print " --target-rrdtool - generate rrd file targets (default)\n"; |
148 | | | print " --target-dsstats - generate DSStats targets\n"; |
149 | | | print " --debug - enable debugging\n"; |
150 | | | print " --help - show this help\n"; |
151 | | | |
152 | | | exit(); |
153 | | | break; |
154 | | | } |
155 | | | } |
156 | | | } |
157 | | | |
158 | | | if ($inputmapfile == '' || $outputmapfile == '') { |
159 | | | print "You MUST specify an input and output file. See --help\n"; |
160 | | | exit(); |
161 | | | } |
162 | | | |
163 | | | // figure out which template has interface traffic. This might be wrong for you. |
164 | | | $data_template = "Interface - Traffic"; |
165 | | | $data_template_id = |
166 | | | db_fetch_cell("select id from data_template where name='" . mysql_real_escape_string($data_template) . "'"); |
167 | | | |
168 | | | $map = new WeatherMap; |
169 | | | |
170 | | | $map->ReadConfig($inputmapfile); |
171 | | | |
172 | | | $fmt_cacti_graph = |
173 | | | $cacti_url . "graph_image.php?local_graph_id=%d&rra_id=0&graph_nolegend=true&graph_height=100&graph_width=300"; |
174 | | | $fmt_cacti_graphpage = $cacti_url . "graph.php?rra_id=all&local_graph_id=%d"; |
175 | | | |
176 | | | // |
177 | | | // Try and populate all three SET vars for each NODE |
178 | | | // cacti_id (host.id) |
179 | | | // hostname (host.description) |
180 | | | // address (host.hostname) (sorry about that) |
181 | | | // |
182 | | | |
183 | | | foreach ($map->nodes as $node) { |
184 | | | $name = $node->name; |
185 | | | print "NODE $name\n"; |
186 | | | $host_id = $node->get_hint("cacti_id"); |
187 | | | $hostname = $node->get_hint("hostname"); |
188 | | | $address = $node->get_hint("address"); |
189 | | | |
190 | | | if ($host_id != '') { |
191 | | | $res1 = db_fetch_row("select hostname,description from host where id=" . intval($host_id)); |
192 | | | |
193 | | | if ($res1) { |
194 | | | if ($hostname == '') { |
195 | | | $hostname = $res1['description']; |
196 | | | $map->nodes[$node->name]->add_hint("hostname", $hostname); |
197 | | | } |
198 | | | |
199 | | | if ($address == '') { |
200 | | | $address = $res1['hostname']; |
201 | | | $map->nodes[$node->name]->add_hint("address", $address); |
202 | | | } |
203 | | | } |
204 | | | } |
205 | | | // 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 |
206 | | | else { |
207 | | | if ($address != '') { |
208 | | | $res2 = db_fetch_row("select id,description from host where hostname='" . mysql_real_escape_string($address) |
209 | | | . "'"); |
210 | | | |
211 | | | if ($res2) { |
212 | | | $host_id = $res2['id']; |
213 | | | $map->nodes[$node->name]->add_hint("cacti_id", $host_id); |
214 | | | |
215 | | | if ($hostname == '') { |
216 | | | $hostname = $res2['description']; |
217 | | | $map->nodes[$node->name]->add_hint("hostname", $hostname); |
218 | | | } |
219 | | | } |
220 | | | } elseif ($hostname != '') { |
221 | | | $res3 = |
222 | | | db_fetch_row("select id,hostname from host where description='" . mysql_real_escape_string($hostname) |
223 | | | . "'"); |
224 | | | |
225 | | | if ($res3) { |
226 | | | $host_id = $res3['id']; |
227 | | | $map->nodes[$node->name]->add_hint("cacti_id", $host_id); |
228 | | | |
229 | | | if ($address == '') { |
230 | | | $address = $res3['hostname']; |
231 | | | $map->nodes[$node->name]->add_hint("address", $address); |
232 | | | } |
233 | | | } |
234 | | | } |
235 | | | } |
236 | | | |
237 | | | if ($host_id != '') { |
238 | | | $info = $config['base_url'] . "host.php?id=" . $host_id; |
239 | | | $tgt = "cactimonitor:$host_id"; |
240 | | | $map->nodes[$node->name]->targets = array (array ( |
241 | | | $tgt, |
242 | | | '', |
243 | | | '', |
244 | | | 0, |
245 | | | $tgt |
246 | | | )); |
247 | | | |
248 | | | $map->nodes[$node->name]->infourl[IN] = $info; |
249 | | | } |
250 | | | |
251 | | | print " $host_id $hostname $address\n"; |
252 | | | } |
253 | | | |
254 | | | // Now lets go through the links |
255 | | | // we want links where at least one of the nodes has a cacti_id, and where either interface_in or interface_out is set |
256 | | | foreach ($map->links as $link) { |
257 | | | if (isset($link->a)) { |
258 | | | $name = $link->name; |
259 | | | $a = $link->a->name; |
260 | | | $b = $link->b->name; |
261 | | | $int_in = $link->get_hint("in_interface"); |
262 | | | $int_out = $link->get_hint("out_interface"); |
263 | | | $a_id = intval($map->nodes[$a]->get_hint("cacti_id")); |
264 | | | $b_id = intval($map->nodes[$b]->get_hint("cacti_id")); |
265 | | | |
266 | | | print "LINK $name\n"; |
267 | | | |
268 | | | if (count($link->targets) == 0 || $overwrite_targets ) { |
269 | | | if ((($a_id + $b_id) > 0) && ($int_out . $int_in == '')) { |
270 | | | print " (could do if there were interfaces)\n"; |
271 | | | } |
272 | | | |
273 | | | if ((($a_id + $b_id) == 0) && ($int_out . $int_in != '')) { |
274 | | | print " (could do if there were host_ids)\n"; |
275 | | | } |
276 | | | |
277 | | | $tgt_interface = ""; |
278 | | | $tgt_host = ""; |
279 | | | |
280 | | | if ($a_id > 0 && $int_out != '') { |
281 | | | print " We'll use the A end.\n"; |
282 | | | $tgt_interface = $int_out; |
283 | | | $tgt_host = $a_id; |
284 | | | $ds_names = ":traffic_in:traffic_out"; |
285 | | | } elseif ($b_id > 0 && $int_in != '') { |
286 | | | print " We'll use the B end and reverse it.\n"; |
287 | | | $tgt_interface = $int_in; |
288 | | | $tgt_host = $b_id; |
289 | | | $ds_names = ":traffic_out:traffic_in"; |
290 | | | } else { |
291 | | | print " No useful ends on this link - fill in more detail (host id, IP) on either NODE $a or $b\n"; |
292 | | | } |
293 | | | |
294 | | | if ($tgt_host != "") { |
295 | | | $int_list = explode(":::", $tgt_interface); |
296 | | | $total_speed = 0; |
297 | | | $total_target = array (); |
298 | | | |
299 | | | foreach ($int_list as $interface) { |
300 | | | print " Interface: $interface\n"; |
301 | | | |
302 | | | foreach (array ( |
303 | | | 'ifName', |
304 | | | 'ifDescr', |
305 | | | 'ifAlias' |
306 | | | ) as $field) { |
307 | | | $SQL = |
308 | | | sprintf( |
309 | | | "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;", |
310 | | | $tgt_host, $field, mysql_real_escape_string($interface), $data_template_id); |
311 | | | $res4 = db_fetch_row($SQL); |
312 | | | |
313 | | | if ($res4) |
314 | | | break; |
315 | | | } |
316 | | | |
317 | | | // if we found one, add the interface to the targets for this link |
318 | | | if ($res4) { |
319 | | | $target = $res4['data_source_path']; |
320 | | | $local_data_id = $res4['id']; |
321 | | | $snmp_index = $res4['snmp_index']; |
322 | | | $tgt = str_replace("<path_rra>", $config["rra_path"], $target); |
323 | | | $tgt = $tgt . $ds_names; |
324 | | | |
325 | | | if ($use_dsstats) { |
326 | | | $map->links[$link->name]->targets[] = array ( |
327 | | | $tgt, |
328 | | | '', |
329 | | | '', |
330 | | | 0, |
331 | | | $tgt |
332 | | | ); |
333 | | | } else { |
334 | | | $tgt = "8*dsstats:$local_data_id" . $ds_names; |
335 | | | $map->links[$link->name]->targets[] = array ( |
336 | | | $tgt, |
337 | | | '', |
338 | | | '', |
339 | | | 0, |
340 | | | $tgt |
341 | | | ); |
342 | | | } |
343 | | | |
344 | | | $SQL_speed = |
345 | | | "select field_value from host_snmp_cache where field_name='ifSpeed' and host_id=$tgt_host and snmp_index=$snmp_index"; |
346 | | | $speed = db_fetch_cell($SQL_speed); |
347 | | | |
348 | | | $SQL_hspeed = |
349 | | | "select field_value from host_snmp_cache where field_name='ifHighSpeed' and host_id=$tgt_host and snmp_index=$snmp_index"; |
350 | | | $hspeed = db_fetch_cell($SQL_hspeed); |
351 | | | |
352 | | | if ($hspeed && intval($hspeed) > 20) |
353 | | | $total_speed += ($hspeed * 1000000); |
354 | | | else if ($speed) |
355 | | | $total_speed += intval($speed); |
356 | | | |
357 | | | $SQL_graphid = |
358 | | | "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;"; |
359 | | | $graph_id = db_fetch_cell($SQL_graphid); |
360 | | | |
361 | | | if ($graph_id) { |
362 | | | $overlib = sprintf($fmt_cacti_graph, $graph_id); |
363 | | | $infourl = sprintf($fmt_cacti_graphpage, $graph_id); |
364 | | | |
365 | | | print " INFO $infourl\n"; |
366 | | | print " OVER $overlib\n"; |
367 | | | $map->links[$name]->overliburl[IN][] = $overlib; |
368 | | | $map->links[$name]->overliburl[OUT][] = $overlib; |
369 | | | $map->links[$name]->infourl[IN] = $infourl; |
370 | | | $map->links[$name]->infourl[OUT] = $infourl; |
371 | | | } else { |
372 | | | print " Couldn't find a graph that uses this rrd??\n"; |
373 | | | } |
374 | | | } else { |
375 | | | print " Failed to find RRD file for $tgt_host/$interface\n"; |
376 | | | } |
377 | | | } |
378 | | | |
379 | | | print " SPEED $total_speed\n"; |
380 | | | $map->links[$name]->max_bandwidth_in = $total_speed; |
381 | | | $map->links[$name]->max_bandwidth_out = $total_speed; |
382 | | | $map->links[$name]->max_bandwidth_in_cfg = nice_bandwidth($total_speed); |
383 | | | $map->links[$name]->max_bandwidth_out_cfg = nice_bandwidth($total_speed); |
384 | | | |
385 | | | if ($map_widths) { |
386 | | | foreach ($width_map as $map_speed => $map_width) { |
387 | | | if ($total_speed <= $map_speed) { |
388 | | | $map->links[$name]->width = $width_map{$map_speed}; |
389 | | | print " WIDTH " . $width_map{$map_speed}. "\n"; |
390 | | | continue 2; |
391 | | | } |
392 | | | } |
393 | | | } |
394 | | | } |
395 | | | } else { |
396 | | | print "Skipping link with targets\n"; |
397 | | | } |
398 | | | } |
399 | | | } |
400 | | | |
401 | | | $map->WriteConfig($outputmapfile); |
402 | | | |
403 | | | print "Wrote config to $outputmapfile\n"; |
404 | | | ?> |