Added munin support as of the cacti integration.
authorMichael Holm <hollo@hollo.dk>
Mon, 22 Oct 2012 10:39:14 +0000 (12:39 +0200)
committerDenis Ovsienko <infrastation@yandex.ru>
Tue, 23 Oct 2012 14:35:48 +0000 (18:35 +0400)
ChangeLog
wwwroot/inc/database.php
wwwroot/inc/install.php
wwwroot/inc/interface.php
wwwroot/inc/navigation.php
wwwroot/inc/ophandlers.php
wwwroot/inc/solutions.php
wwwroot/inc/triggers.php
wwwroot/inc/upgrade.php

index f292a48e2bd84fd53fb48a8c80a37f1b2526e2d9..69bc8ad7289de66c833f6da1db76ef82ea67b11d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,7 @@
        update: SLB: ability to specify multiple RS ports
        update: remove old gateways code, including Live VLANs
        new feature: abstract tags, which cannot be assigned (#577)
+       new feature: added support for munin graphs (#406) by Michael Holm
 0.20.1 2012-10-04
        bugfix: restore D-Link (#533) and Linux (#541) gateway support
        bugfix: IPv4 network capacity was not displayed on 32-bit machines (#602)
index 2753288d2a74daf1b88514819dc885605a14b62c..be37a76228d3e97e99e869955dfbf0be1933d753 100644 (file)
@@ -1211,6 +1211,8 @@ function commitResetObject ($object_id = 0)
        recordObjectHistory ($object_id);
        # Cacti graphs
        usePreparedDeleteBlade ('CactiGraph', array ('object_id' => $object_id));
+       # Munin graphs
+       usePreparedDeleteBlade ('MuninGraph', array ('object_id' => $object_id));
 }
 
 function commitDeleteRack($rack_id)
@@ -5082,6 +5084,16 @@ function getCactiGraphsForObject ($object_id)
        return reindexById ($result->fetchAll (PDO::FETCH_ASSOC), 'graph_id');
 }
 
+function getMuninGraphsForObject ($object_id)
+{
+       $result = usePreparedSelectBlade
+       (
+               'SELECT server_id, graph, caption FROM MuninGraph WHERE object_id = ? ORDER BY server_id, graph',
+               array ($object_id)
+       );
+       return reindexById ($result->fetchAll (PDO::FETCH_ASSOC), 'graph');
+}
+
 function touchVLANSwitch ($switch_id)
 {
        usePreparedExecuteBlade
@@ -5118,4 +5130,14 @@ function getCactiServers()
        return reindexById ($result->fetchAll (PDO::FETCH_ASSOC));
 }
 
+function getMuninServers()
+{
+       $result = usePreparedSelectBlade
+       (
+               'SELECT id, base_url, COUNT(MG.object_id) AS num_graphs ' .
+               'FROM MuninServer AS MS LEFT JOIN MuninGraph AS MG ON MS.id = MG.server_id GROUP BY id'
+       );
+       return reindexById ($result->fetchAll (PDO::FETCH_ASSOC));
+}
+
 ?>
index 4eec27db07458682d4380cfbdb01237a9d426774..74b68241342a1f4c81607a17096d8271e998a9cb 100644 (file)
@@ -762,6 +762,24 @@ CREATE TABLE `MountOperation` (
   CONSTRAINT `MountOperation-FK-new_molecule_id` FOREIGN KEY (`new_molecule_id`) REFERENCES `Molecule` (`id`) ON DELETE CASCADE
 ) ENGINE=InnoDB;
 
+CREATE TABLE `MuninGraph` (
+  `object_id` int(10) unsigned NOT NULL,
+  `server_id` int(10) unsigned NOT NULL,
+  `graph` char(255) NOT NULL,
+  `caption`  char(255) DEFAULT NULL,
+  PRIMARY KEY (`object_id`,`server_id`,`graph`),
+  KEY `server_id` (`server_id`),
+  KEY `graph` (`graph`),
+  CONSTRAINT `MuninGraph-FK-server_id` FOREIGN KEY (`server_id`) REFERENCES `MuninServer` (`id`),
+  CONSTRAINT `MuninGraph-FK-object_id` FOREIGN KEY (`object_id`) REFERENCES `Object` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB;
+
+CREATE TABLE `MuninServer` (
+  `id` int(10) unsigned NOT NULL auto_increment,
+  `base_url` char(255) DEFAULT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB;
+
 CREATE TABLE `ObjectLog` (
   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
   `object_id` int(10) unsigned NOT NULL,
@@ -1601,6 +1619,7 @@ INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, is_userdef
 ('SYNC_802Q_LISTSRC','','string','yes','no','no','List of VLAN switches sync is enabled on'),
 ('QUICK_LINK_PAGES','depot,ipv4space,rackspace','string','yes','no','yes','List of pages to dislay in quick links'),
 ('CACTI_LISTSRC','false','string','yes','no','no','List of object with Cacti graphs'),
+('MUNIN_LISTSRC','false','string','yes','no','no','List of object with Munin graphs'),
 ('VIRTUAL_OBJ_LISTSRC','1504,1505,1506,1507','string','no','no','no','List source: virtual objects'),
 ('DATETIME_ZONE','UTC','string','yes','no','yes','Timezone to use for displaying/calculating dates'),
 ('DATETIME_FORMAT','m/d/Y','string','no','no','yes','PHP date() format to use for date output'),
index a0a145b19d2cc6d161db4ecaf19364ca7682d78a..2eb6dcbcf907aeb1b2a75b5eb9bed1a6731e7647 100644 (file)
@@ -8593,6 +8593,55 @@ function renderObjectCactiGraphs ($object_id)
        finishPortlet ();
 }
 
+function renderObjectMuninGraphs ($object_id)
+{
+       function printNewItem ($options)
+       {
+               echo "<table cellspacing=\"0\" align=\"center\" width=\"50%\">";
+               echo "<tr><td>&nbsp;</td><th>Server</th><th>Graph</th><th>Caption</th><td>&nbsp;</td></tr>\n";
+               printOpFormIntro ('add');
+               echo "<tr><td>";
+               printImageHREF ('Attach', 'Link new graph', TRUE);
+               echo '</td><td>' . getSelect ($options, array ('name' => 'server_id'));
+               echo "</td><td><input type=text name=graph tabindex=100></td><td><input type=text name=caption tabindex=101></td><td>";
+               printImageHREF ('Attach', 'Link new graph', TRUE, 101);
+               echo "</td></tr></form>";
+               echo "</table>";
+               echo "<br/><br/>";
+       }
+       if (!extension_loaded ('curl'))
+               throw new RackTablesError ("The PHP cURL extension is not loaded.", RackTablesError::MISCONFIGURED);
+
+       $servers = getMuninServers();
+       $options = array();
+       foreach ($servers as $server)
+               $options[$server['id']] = "${server['id']}: ${server['base_url']}";
+       startPortlet ('Munin Graphs');
+       if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
+               printNewItem ($options);
+       echo "<table cellspacing=\"0\" cellpadding=\"10\" align=\"center\" width=\"50%\">";
+
+       $object = spotEntity ('object', $object_id);
+       list ($host, $domain) = preg_split ("/\./", $object['dname'], 2);
+
+       foreach (getMuninGraphsForObject ($object_id) as $graph_name => $graph)
+       {
+               $munin_url = $servers[$graph['server_id']]['base_url'];
+               $text = "(graph ${graph_name} on server ${graph['server_id']})";
+               echo "<tr><td>";
+               echo "<a href='${munin_url}/${domain}/${object['dname']}/${graph_name}.html' target='_blank'>";
+               echo "<img src='index.php?module=image&img=muningraph&object_id=${object_id}&server_id=${graph['server_id']}&graph=${graph_name}' alt='${text}' title='${text}'></a></td>";
+               echo "<td><a href='" . makeHrefProcess (array ('op' => 'del', 'server_id' => $graph['server_id'], 'graph' => $graph_name));
+               echo "' onclick=\"javascript:return confirm('Are you sure you want to delete the graph?')\">";
+               echo getImageHREF ('Cut', 'Unlink graph') . "</a>&nbsp; &nbsp;${graph['caption']}";
+               echo "</td></tr>";
+       }
+       echo '</table>';
+       if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
+               printNewItem ($options);
+       finishPortlet ();
+}
+
 function renderEditVlan ($vlan_ck)
 {
        global $vtoptions;
@@ -8791,4 +8840,57 @@ function renderCactiServersEditor()
        echo '</table>';
 }
 
+function renderMuninConfig()
+{
+       $servers = getMuninServers();
+       startPortlet ('Munin servers (' . count ($servers) . ')');
+       echo '<table cellspacing=0 cellpadding=5 align=center class=widetable>';
+       echo '<tr><th>base URL</th><th>graph(s)</th></tr>';
+       foreach ($servers as $server)
+       {
+               echo '<tr align=left valign=top><td>' . niftyString ($server['base_url']) . '</td>';
+               echo "<td class=tdright>${server['num_graphs']}</td></tr>";
+       }
+       echo '</table>';
+       finishPortlet();
+}
+
+function renderMuninServersEditor()
+{
+       function printNewItemTR()
+       {
+               printOpFormIntro ('add');
+               echo '<tr>';
+               echo '<td>' . getImageHREF ('create', 'add a new server', TRUE, 112) . '</td>';
+               echo '<td><input type=text size=48 name=base_url tabindex=101></td>';
+               echo '<td>&nbsp;</td>';
+               echo '<td>' . getImageHREF ('create', 'add a new server', TRUE, 111) . '</td>';
+               echo '</tr></form>';
+       }
+       echo '<table cellspacing=0 cellpadding=5 align=center class=widetable>';
+       echo '<tr><th>&nbsp;</th><th>base URL</th><th>graph(s)</th><th>&nbsp;</th></tr>';
+       if (getConfigVar ('ADDNEW_AT_TOP') == 'yes')
+               printNewItemTR();
+       foreach (getMuninServers() as $server)
+       {
+               printOpFormIntro ('upd', array ('id' => $server['id']));
+               echo '<tr><td>';
+               if ($server['num_graphs'])
+                       printImageHREF ('nodestroy', 'cannot delete, graphs exist');
+               else
+               {
+                       echo '<a href="' . makeHrefProcess (array ('op' => 'del', 'id' => $server['id'])) . '">';
+                       echo getImageHREF ('destroy', 'delete this server') . '</a>';
+               }
+               echo '</td>';
+               echo '<td><input type=text size=48 name=base_url value="' . htmlspecialchars ($server['base_url'], ENT_QUOTES, 'UTF-8') . '"></td>';
+               echo "<td class=tdright>${server['num_graphs']}</td>";
+               echo '<td>' . getImageHREF ('save', 'update this server', TRUE) . '</td>';
+               echo '</tr></form>';
+       }
+       if (getConfigVar ('ADDNEW_AT_TOP') != 'yes')
+               printNewItemTR();
+       echo '</table>';
+}
+
 ?>
index 488ee4ae9ca62f174df653844a0430ec6db67213..152752ac1b18757a538d23721b6fbdaae0f43165 100644 (file)
@@ -165,6 +165,7 @@ $tab['object']['8021qorder'] = '802.1Q order';
 $tab['object']['8021qports'] = '802.1Q ports';
 $tab['object']['8021qsync'] = '802.1Q sync';
 $tab['object']['cacti'] = 'Cacti Graphs';
+$tab['object']['munin'] = 'Munin Graphs';
 $tabhandler['object']['default'] = 'renderObject';
 $tabhandler['object']['edit'] = 'renderEditObjectForm';
 $tabhandler['object']['log'] = 'renderObjectLogEditor';
@@ -185,6 +186,7 @@ $tabhandler['object']['8021qorder'] = 'render8021QOrderForm';
 $tabhandler['object']['8021qports'] = 'renderObject8021QPorts';
 $tabhandler['object']['8021qsync'] = 'renderObject8021QSync';
 $tabhandler['object']['cacti'] = 'renderObjectCactiGraphs';
+$tabhandler['object']['munin'] = 'renderObjectMuninGraphs';
 $tabhandler['object']['ucs'] = 'renderEditUCSForm';
 $trigger['object']['rackspace'] = 'trigger_rackspace';
 $trigger['object']['ports'] = 'trigger_ports';
@@ -202,6 +204,7 @@ $trigger['object']['8021qorder'] = 'trigger_object_8021qorder';
 $trigger['object']['8021qports'] = 'trigger_object_8021qports';
 $trigger['object']['8021qsync'] = 'trigger_object_8021qsync';
 $trigger['object']['cacti'] = 'triggerCactiGraphs';
+$trigger['object']['munin'] = 'triggerMuninGraphs';
 $trigger['object']['ucs'] = 'trigger_ucs';
 $ophandler['object']['edit']['linkEntities'] = 'tableHandler';
 $ophandler['object']['edit']['unlinkEntities'] = 'tableHandler';
@@ -248,6 +251,8 @@ $ophandler['object']['8021qsync']['addPort'] = 'create8021QPortConfig';
 $ophandler['object']['8021qsync']['delPort'] = 'destroy8021QPortConfig';
 $ophandler['object']['cacti']['add'] = 'tableHandler';
 $ophandler['object']['cacti']['del'] = 'tableHandler';
+$ophandler['object']['munin']['add'] = 'tableHandler';
+$ophandler['object']['munin']['del'] = 'tableHandler';
 $ophandler['object']['ucs']['autoPopulateUCS'] = 'autoPopulateUCS';
 $ophandler['object']['ucs']['cleanupUCS'] = 'cleanupUCS';
 $delayauth['object-8021qports-save8021QConfig'] = TRUE;
@@ -570,6 +575,16 @@ $ophandler['cacti']['servers']['add'] = 'tableHandler';
 $ophandler['cacti']['servers']['del'] = 'tableHandler';
 $ophandler['cacti']['servers']['upd'] = 'tableHandler';
 
+$page['munin']['title'] = 'Munin';
+$page['munin']['parent'] = 'config';
+$tab['munin']['default'] = 'View';
+$tab['munin']['servers'] = 'Manage servers';
+$tabhandler['munin']['default'] = 'renderMuninConfig';
+$tabhandler['munin']['servers'] = 'renderMuninServersEditor';
+$ophandler['munin']['servers']['add'] = 'tableHandler';
+$ophandler['munin']['servers']['del'] = 'tableHandler';
+$ophandler['munin']['servers']['upd'] = 'tableHandler';
+
 $page['reports']['title'] = 'Reports';
 $page['reports']['parent'] = 'index';
 $tab['reports']['default'] = 'System';
index 33d51e46ac54adc3570aa318bef3d53de7812ea9..199166036973cceb1329259158010cc488bb35d9 100644 (file)
@@ -192,6 +192,29 @@ $opspec_list['object-cacti-del'] = array
                array ('url_argname' => 'graph_id', 'assertion' => 'uint'),
        ),
 );
+$opspec_list['object-munin-add'] = array
+(
+       'table' => 'MuninGraph',
+       'action' => 'INSERT',
+       'arglist' => array
+       (
+               array ('url_argname' => 'object_id', 'assertion' => 'uint'),
+               array ('url_argname' => 'server_id', 'assertion' => 'uint'),
+               array ('url_argname' => 'graph', 'assertion' => 'string'),
+               array ('url_argname' => 'caption', 'assertion' => 'string0'),
+       ),
+);
+$opspec_list['object-munin-del'] = array
+(
+       'table' => 'MuninGraph',
+       'action' => 'DELETE',
+       'arglist' => array
+       (
+               array ('url_argname' => 'object_id', 'assertion' => 'uint'),
+               array ('url_argname' => 'server_id', 'assertion' => 'uint'),
+               array ('url_argname' => 'graph', 'assertion' => 'string'),
+       ),
+);
 $opspec_list['ipv4net-properties-editRange'] = array
 (
        'table' => 'IPv4Network',
@@ -585,6 +608,37 @@ $opspec_list['cacti-servers-upd'] = array
                array ('url_argname' => 'id', 'assertion' => 'uint'),
        ),
 );
+$opspec_list['munin-servers-add'] = array
+(
+       'table' => 'MuninServer',
+       'action' => 'INSERT',
+       'arglist' => array
+       (
+               array ('url_argname' => 'base_url', 'assertion' => 'string')
+       ),
+);
+$opspec_list['munin-servers-del'] = array
+(
+       'table' => 'MuninServer',
+       'action' => 'DELETE',
+       'arglist' => array
+       (
+               array ('url_argname' => 'id', 'assertion' => 'uint'),
+       ),
+);
+$opspec_list['munin-servers-upd'] = array
+(
+       'table' => 'MuninServer',
+       'action' => 'UPDATE',
+       'set_arglist' => array
+       (
+               array ('url_argname' => 'base_url', 'assertion' => 'string'),
+       ),
+       'where_arglist' => array
+       (
+               array ('url_argname' => 'id', 'assertion' => 'uint'),
+       ),
+);
 
 $msgcode['addPortForwarding']['OK'] = 48;
 function addPortForwarding ()
@@ -1427,6 +1481,7 @@ function resetUIConfig()
        setConfigVar ('SYNC_802Q_LISTSRC', '');
        setConfigVar ('QUICK_LINK_PAGES', 'depot,ipv4space,rackspace');
        setConfigVar ('CACTI_LISTSRC', 'false');
+       setConfigVar ('MUNIN_LISTSRC', 'false');
        setConfigVar ('VIRTUAL_OBJ_LISTSRC', '1504,1505,1506,1507');
        setConfigVar ('DATETIME_ZONE', 'UTC');
        setConfigVar ('DATETIME_FORMAT', 'm/d/Y');
index 816c587c8479b978e00369804fb2526118600900..d7305b77b36209d3fca5cbf40a89545e16ce1ffa 100644 (file)
@@ -46,6 +46,17 @@ function dispatchImageRequest()
                        throw new InvalidRequestArgException ('graph_id', $_REQUEST['graph_id']);
                proxyCactiRequest ($_REQUEST['server_id'], $_REQUEST['graph_id']);
                break;
+       case 'muningraph':
+               $pageno = 'object';
+               $tabno = 'munin';
+               fixContext();
+               assertPermission();
+               genericAssertion ('server_id', 'uint');
+               genericAssertion ('graph', 'string');
+               if (! array_key_exists ($_REQUEST['graph'], getMuninGraphsForObject (getBypassValue())))
+                       throw new InvalidRequestArgException ('graph', $_REQUEST['graph']);
+               proxyMuninRequest ($_REQUEST['server_id'], $_REQUEST['graph']);
+               break;
        default:
                renderErrorImage();
        }
@@ -432,6 +443,44 @@ function proxyCactiRequest ($server_id, $graph_id)
        echo $ret['contents'];
 }
 
+function proxyMuninRequest ($server_id, $graph)
+{
+    $object = spotEntity ('object', $server_id);
+    list ($host, $domain) = preg_split ("/\./", $object['dname'], 2);
+
+       $ret = array();
+       $servers = getMuninServers();
+       if (! array_key_exists ($server_id, $servers))
+               throw new InvalidRequestArgException ('server_id', $server_id);
+       $munin_url = $servers[$server_id]['base_url'];
+       $url = "${munin_url}/${domain}/${object['dname']}/${graph}-day.png";
+
+       $session = curl_init();
+
+       // Initial options up here so a specific type can override them
+       curl_setopt ($session, CURLOPT_FOLLOWLOCATION, FALSE);
+       curl_setopt ($session, CURLOPT_TIMEOUT, 10);
+       curl_setopt ($session, CURLOPT_RETURNTRANSFER, TRUE);
+       curl_setopt ($session, CURLOPT_URL, $url);
+
+       if (isset($_SESSION['MUNINCOOKIE'][$munin_url]))
+               curl_setopt ($session, CURLOPT_COOKIE, $_SESSION['MUNINCOOKIE'][$munin_url]);
+
+       // Request the image
+       $ret['contents'] = curl_exec ($session);
+       $ret['type'] = curl_getinfo ($session, CURLINFO_CONTENT_TYPE);
+       $ret['size'] = curl_getinfo ($session, CURLINFO_SIZE_DOWNLOAD);
+
+       curl_close ($session);
+
+       if ($ret['type'] != NULL)
+               header ("Content-Type: {$ret['type']}");
+       if ($ret['size'] > 0)
+               header ("Content-Length: {$ret['size']}");
+
+       echo $ret['contents'];
+}
+
 function printSVGMessageBar ($text = 'lost message', $textattrs = array(), $rectattrs = array())
 {
        $mytextattrs = array
index 844db83b1596934ad34266f1b75280cc01126e75..c838ab05daf44dbf11e87ec014cf796613267aee 100644 (file)
@@ -322,6 +322,20 @@ function triggerCactiGraphs ()
                return '';
 }
 
+function triggerMuninGraphs()
+{
+       if (! count (getMuninServers()))
+               return '';
+       if
+       (
+               count (getMuninGraphsForObject (getBypassValue())) or
+               considerConfiguredConstraint (spotEntity ('object', getBypassValue()), 'MUNIN_LISTSRC')
+       )
+               return 'std';
+       else
+               return '';
+}
+
 function trigger_ucs()
 {
        return checkTypeAndAttribute
index 09688d41ac65f04ed73bee64f6072c7baab444bc..cf5fe664bd9db9384ec7fae03b12b6a2dddcdf58 100644 (file)
@@ -1582,6 +1582,27 @@ CREATE TABLE `CactiServer` (
                        $query[] = "ALTER TABLE TagStorage ADD CONSTRAINT `TagStorage-FK-TagTree` FOREIGN KEY (tag_id, tag_is_assignable) REFERENCES TagTree (id, is_assignable)";
                        $query[] = "UPDATE UserAccount SET user_realname = NULL WHERE user_realname = ''";
                        $query[] = "UPDATE Config SET varvalue = '0.20.2' WHERE varname = 'DB_VERSION'";
+                       $query[] = "
+CREATE TABLE `MuninServer` (
+  `id` int(10) unsigned NOT NULL auto_increment,
+  `base_url` char(255) DEFAULT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB;
+";
+                       $query[] = "
+CREATE TABLE `MuninGraph` (
+  `object_id` int(10) unsigned NOT NULL,
+  `server_id` int(10) unsigned NOT NULL,
+  `graph` char(255) NOT NULL,
+  `caption`  char(255) DEFAULT NULL,
+  PRIMARY KEY (`object_id`,`server_id`,`graph`),
+  KEY `server_id` (`server_id`),
+  KEY `graph` (`graph`),
+  CONSTRAINT `MuninGraph-FK-server_id` FOREIGN KEY (`server_id`) REFERENCES `MuninServer` (`id`),
+  CONSTRAINT `MuninGraph-FK-object_id` FOREIGN KEY (`object_id`) REFERENCES `Object` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB;
+";
+                       $query[] = "INSERT INTO `Config` (varname, varvalue, vartype, emptyok, is_hidden, is_userdefined, description) VALUES ('MUNIN_LISTSRC','false','string','yes','no','no','List of object with Munin graphs')";
                        break;
                case 'dictionary':
                        $query = reloadDictionary();