View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 691 | RackTables | default | public | 2012-12-07 13:57 | 2013-04-16 16:24 |
| Reporter | MWilkinson | Assigned To | andriyanov | ||
| Priority | normal | Severity | feature | Reproducibility | N/A |
| Status | assigned | Resolution | open | ||
| Product Version | 0.20.1 | ||||
| Summary | 691: Patch to allow plugins to add Portlets to Object default page | ||||
| Description | The patch re-works the object default page rendering mechanism to introduce a feature similar to the tabs functionality allowing plugins to insert information within the rendered page rather than just before or after. Included is a demo-plugin which as well as demonstrating this feature provides a new tab and update operation. | ||||
| Steps To Reproduce | Apply patch against RackTables version 0.20.1 | ||||
| Additional Information | This could probably be extended to other default pages, but as the plugin I was working on dealt only with the objects, that is all I currently looked at implementing. Hopefully you will find this useful. Regards Mark | ||||
| Tags | No tags attached. | ||||
| Attached Files | racktables-0.20.1.patch (24,843 bytes)
diff -urN RackTables-0.20.1-orig/plugins/demo-plugin.php RackTables-0.20.1/plugins/demo-plugin.php
--- RackTables-0.20.1-orig/plugins/demo-plugin.php 1970-01-01 01:00:00.000000000 +0100
+++ RackTables-0.20.1/plugins/demo-plugin.php 2012-12-07 12:44:22.219569142 +0000
@@ -0,0 +1,53 @@
+<?php
+
+$tab['object']['demo'] = 'Demo';
+registerTabHandler('object', 'demo', 'myRenderDemo');
+registerOpHandler('object', 'demo', 'update', 'updateDemo');
+registerPortletHandler( 'object', 'default', 'left', 'Demo', 'myRenderObPortletDemo', 'after', 'Comment');
+
+
+function myRenderObPortletDemo ( $info )
+{
+ startPortlet('Demo Plugin Portlet');
+ echo "This text was produced by the Demo Plugin\n";
+ finishPortlet();
+}
+
+$msgcode['updateDemo']['OK'] = 43;
+function updateDemo()
+{
+ assertUIntArg ('object_id');
+//
+// Update something here
+//
+
+ showFuncMessage (__FUNCTION__, 'OK');
+ return buildRedirectURL (NULL, NULL, NULL);
+}
+
+function myRenderDemo ()
+{
+ global $pageno, $virtual_obj_types;
+ $object_id = getBypassValue();
+ $info = spotEntity ('object', $object_id);
+ amplifyCell ($info);
+
+ startPortlet ();
+ printOpFormIntro ('update');
+
+ echo '<table border=0 cellspacing=0 cellpadding=3 align=center>';
+ echo "<tr>";
+ echo "<td> </td>";
+ echo "<td>Insert form here</td>";
+ echo "<td> </td>";
+ echo "</tr>\n";
+ echo "<tr><th class=submit colspan=3>";
+ printImageHREF ('SAVE', 'Save changes', TRUE);
+
+ echo "</tr></table>";
+
+
+ echo "</form></th></tr></table>\n";
+ finishPortlet();
+
+}
diff -urN RackTables-0.20.1-orig/wwwroot/inc/functions.php RackTables-0.20.1/wwwroot/inc/functions.php
--- RackTables-0.20.1-orig/wwwroot/inc/functions.php 2012-10-04 13:06:14.000000000 +0100
+++ RackTables-0.20.1/wwwroot/inc/functions.php 2012-12-07 12:44:16.039569296 +0000
@@ -5656,4 +5656,51 @@
return arePortTypesCompatible ($portinfo_a['oif_id'], $portinfo_b['oif_id']);
}
+// Registers additional portleyhandler on page-tab-column triplet.
+// Valid $column values are 'left', 'right'
+// 'left' puts you portlet in the left hand column on a page (default)
+// 'right' puts you portlet in the left hand column on a page
+// $name is used as an identifer when inserting between current portlets
+// Valid $method values are 'before', 'after'.
+// 'before' puts your tabhandler in the beginning of the list (and thus before the default)
+// 'after' puts your tabhandler to the end of the list (and thus after the default)
+// $name2 modified the behaviour of $method to insert the new portlet between currently definded portlets on
+// the page.
+function registerPortletHandler ($page, $tab, $column = 'left', $name, $callback, $method = 'after', $name2 = '')
+{
+ global $portlethandler;
+
+ if ($name2 == '')
+ if ($method == 'before')
+ array_unshift ($portlethandler[$page][$tab][$column], array( 'name' => $name, 'callback' => $callback));
+ elseif ($method == 'after')
+ array_push ($portlethandler[$page][$tab][$column], array( 'name' => $name, 'callback' => $callback));
+ else
+ throw new RacktablesError ("unknown portlethandler injection method '$method'", RackTablesError::INTERNAL);
+ else
+ {
+ $done = 0;
+ foreach ($portlethandler[$page][$tab][$column] as $idx => $portlet)
+ if ($portlet['name'] == $name2)
+ {
+ if ($method == 'before')
+ {
+ array_splice($portlethandler[$page][$tab][$column], $idx, 0, array(array('name'=> $name, 'callback' => $callback)));
+ $done = 1;
+ }
+ elseif ($method == 'after')
+ {
+ array_splice($portlethandler[$page][$tab][$column], ($idx+1), 0, array(array('name'=> $name, 'callback' => $callback)));
+ $done = 1;
+ }
+ else
+ throw new RacktablesError ("unknown portlethandler injection method '$method'", RackTablesError::INTERNAL);
+ break;
+ }
+ if ( ! $done )
+ throw new RacktablesError ("unknown portlet ($name2) to insert $method", RackTablesError::MISCONFIGURED);
+ }
+
+}
+
?>
diff -urN RackTables-0.20.1-orig/wwwroot/inc/interface.php RackTables-0.20.1/wwwroot/inc/interface.php
--- RackTables-0.20.1-orig/wwwroot/inc/interface.php 2012-10-04 13:06:14.000000000 +0100
+++ RackTables-0.20.1/wwwroot/inc/interface.php 2012-12-07 11:57:17.109569551 +0000
@@ -12,6 +12,7 @@
require_once 'ajax-interface.php';
require_once 'slb-interface.php';
+require_once 'portlets.php';
// Interface function's special.
$nextorder['odd'] = 'even';
@@ -1101,237 +1102,26 @@
function renderObject ($object_id)
{
global $nextorder, $virtual_obj_types;
+ global $portlethandler;
$info = spotEntity ('object', $object_id);
amplifyCell ($info);
// Main layout starts.
echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
// left column with uknown number of portlets
- echo "<tr><td class=pcleft>";
-
- // display summary portlet
- $summary = array();
- if (strlen ($info['name']))
- $summary['Common name'] = $info['name'];
- elseif (considerConfiguredConstraint ($info, 'NAMEWARN_LISTSRC'))
- $summary[] = array ('<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>');
- $summary['Object type'] = '<a href="' . makeHref (array (
- 'page' => 'depot',
- 'tab' => 'default',
- 'cfe' => '{$typeid_' . $info['objtype_id'] . '}'
- )) . '">' . decodeObjectType ($info['objtype_id'], 'o') . '</a>';
- if (strlen ($info['label']))
- $summary['Visible label'] = $info['label'];
- if (strlen ($info['asset_no']))
- $summary['Asset tag'] = $info['asset_no'];
- elseif (considerConfiguredConstraint ($info, 'ASSETWARN_LISTSRC'))
- $summary[] = array ('<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>');
- $parents = getEntityRelatives ('parents', 'object', $object_id);
- if (count ($parents))
- {
- $fmt_parents = array();
- foreach ($parents as $parent)
- $fmt_parents[] = "<a href='".makeHref(array('page'=>$parent['page'], $parent['id_name'] => $parent['entity_id']))."'>${parent['name']}</a>";
- $summary[count($parents) > 1 ? 'Containers' : 'Container'] = implode ('<br>', $fmt_parents);
- }
- $children = getEntityRelatives ('children', 'object', $object_id);
- if (count ($children))
- {
- $fmt_children = array();
- foreach ($children as $child)
- $fmt_children[] = "<a href='".makeHref(array('page'=>$child['page'], $child['id_name']=>$child['entity_id']))."'>${child['name']}</a>";
- $summary['Contains'] = implode ('<br>', $fmt_children);
- }
- if ($info['has_problems'] == 'yes')
- $summary[] = array ('<tr><td colspan=2 class=msg_error>Has problems</td></tr>');
- foreach (getAttrValues ($object_id) as $record)
- if
- (
- strlen ($record['value']) and
- permitted (NULL, NULL, NULL, array (array ('tag' => '$attr_' . $record['id'])))
- )
- $summary['{sticker}' . $record['name']] = formatAttributeValue ($record);
- $summary[] = array (getOutputOf ('printTagTRs',
- $info,
- makeHref
- (
- array
- (
- 'page'=>'depot',
- 'tab'=>'default',
- 'andor' => 'and',
- 'cfe' => '{$typeid_' . $info['objtype_id'] . '}',
- )
- )."&"
- ));
- renderEntitySummary ($info, 'summary', $summary);
-
- if (strlen ($info['comment']))
- {
- startPortlet ('Comment');
- echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
- finishPortlet ();
- }
-
- $logrecords = getLogRecordsForObject ($_REQUEST['object_id']);
- if (count ($logrecords))
- {
- startPortlet ('log records');
- echo "<table cellspacing=0 cellpadding=5 align=center class=widetable width='100%'>";
- $order = 'odd';
- foreach ($logrecords as $row)
- {
- echo "<tr class=row_${order} valign=top>";
- echo '<td class=tdleft>' . $row['date'] . '<br>' . $row['user'] . '</td>';
- echo '<td class="logentry">' . string_insert_hrefs (htmlspecialchars ($row['content'], ENT_NOQUOTES)) . '</td>';
- echo '</tr>';
- $order = $nextorder[$order];
- }
- echo '</table>';
- finishPortlet();
- }
-
- switchportInfoJS ($object_id); // load JS code to make portnames interactive
- renderFilesPortlet ('object', $object_id);
-
- if (count ($info['ports']))
- {
- startPortlet ('ports and links');
- $hl_port_id = 0;
- if (isset ($_REQUEST['hl_port_id']))
- {
- assertUIntArg ('hl_port_id');
- $hl_port_id = $_REQUEST['hl_port_id'];
- addAutoScrollScript ("port-$hl_port_id");
- }
- echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>";
- echo '<tr><th class=tdleft>Local name</th><th class=tdleft>Visible label</th>';
- echo '<th class=tdleft>Interface</th><th class=tdleft>L2 address</th>';
- echo '<th class=tdcenter colspan=2>Remote object and port</th>';
- echo '<th class=tdleft>Cable ID</th></tr>';
- foreach ($info['ports'] as $port)
- callHook ('renderObjectPortRow', $port, ($hl_port_id == $port['id']));
- if (permitted (NULL, 'ports', 'set_reserve_comment'))
- addJS ('js/inplace-edit.js');
- echo "</table><br>";
- finishPortlet();
- }
-
- if (count ($info['ipv4']) + count ($info['ipv6']))
- {
- startPortlet ('IP addresses');
- echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
- if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
- echo "<tr><th>OS interface</th><th>IP address</th><th>network</th><th>routed by</th><th>peers</th></tr>\n";
- else
- echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
-
- // group IP allocations by interface name instead of address family
- $allocs_by_iface = array();
- foreach (array ('ipv4', 'ipv6') as $ip_v)
- foreach ($info[$ip_v] as $ip_bin => $alloc)
- $allocs_by_iface[$alloc['osif']][$ip_bin] = $alloc;
-
- // sort allocs array by portnames
- foreach (sortPortList ($allocs_by_iface) as $iface_name => $alloclist)
- {
- $is_first_row = TRUE;
- foreach ($alloclist as $alloc)
- {
- $rendered_alloc = callHook ('getRenderedAlloc', $object_id, $alloc);
- echo "<tr class='${rendered_alloc['tr_class']}' valign=top>";
-
- // display iface name, same values are grouped into single cell
- if ($is_first_row)
- {
- $rowspan = count ($alloclist) > 1 ? 'rowspan="' . count ($alloclist) . '"' : '';
- echo "<td class=tdleft $rowspan>" . $iface_name . $rendered_alloc['td_name_suffix'] . "</td>";
- $is_first_row = FALSE;
- }
- echo $rendered_alloc['td_ip'];
- if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
- {
- echo $rendered_alloc['td_network'];
- echo $rendered_alloc['td_routed_by'];
- }
- echo $rendered_alloc['td_peers'];
-
- echo "</tr>\n";
- }
- }
- echo "</table><br>\n";
- finishPortlet();
- }
-
- $forwards = $info['nat4'];
- if (count($forwards['in']) or count($forwards['out']))
+ echo "<tr>";
+ foreach (array('left','right') as $side)
{
- startPortlet('NATv4');
+ echo "<td class=pc$side>";
- if (count($forwards['out']))
+ foreach ($portlethandler['object']['default'][$side] as $idx => $portlet)
{
-
- echo "<h3>locally performed NAT</h3>";
-
- echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
- echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
-
- foreach ($forwards['out'] as $pf)
- {
- $class = 'trerror';
- $osif = '';
- if (isset ($alloclist [$pf['localip']]))
- {
- $class = $alloclist [$pf['localip']]['addrinfo']['class'];
- $osif = $alloclist [$pf['localip']]['osif'] . ': ';
- }
- echo "<tr class='$class'>";
- echo "<td>${pf['proto']}</td><td class=tdleft>${osif}" . getRenderedIPPortPair ($pf['localip'], $pf['localport']) . "</td>";
- echo "<td class=tdleft>" . getRenderedIPPortPair ($pf['remoteip'], $pf['remoteport']) . "</td>";
- $address = getIPAddress (ip4_parse ($pf['remoteip']));
- echo "<td class='description'>";
- if (count ($address['allocs']))
- foreach($address['allocs'] as $bond)
- echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
- elseif (strlen ($pf['remote_addr_name']))
- echo '(' . $pf['remote_addr_name'] . ')';
- echo "</td><td class='description'>${pf['description']}</td></tr>";
- }
- echo "</table><br><br>";
- }
- if (count($forwards['in']))
- {
- echo "<h3>arriving NAT connections</h3>";
- echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
- echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
- foreach ($forwards['in'] as $pf)
- {
- echo "<tr>";
- echo "<td>${pf['proto']}/" . getRenderedIPPortPair ($pf['localip'], $pf['localport']) . "</td>";
- echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
- echo "</td><td>" . getRenderedIPPortPair ($pf['remoteip'], $pf['remoteport']) . "</td>";
- echo "<td class='description'>${pf['description']}</td></tr>";
- }
- echo "</table><br><br>";
+ echo "<!-- $idx -->\n";
+ call_user_func($portlet['callback'], $info );
}
- finishPortlet();
+ echo "</td>\n";
}
- renderSLBTriplets ($info);
- echo "</td>\n";
-
- // After left column we have (surprise!) right column with rackspace portlet only.
- echo "<td class=pcright>";
- if (!in_array($info['objtype_id'], $virtual_obj_types))
- {
- // rackspace portlet
- startPortlet ('rackspace allocation');
- foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
- renderRack ($rack_id, $object_id);
- echo '<br>';
- finishPortlet();
- }
- echo "</td></tr>";
echo "</table>\n";
}
diff -urN RackTables-0.20.1-orig/wwwroot/inc/navigation.php RackTables-0.20.1/wwwroot/inc/navigation.php
--- RackTables-0.20.1-orig/wwwroot/inc/navigation.php 2012-10-04 13:06:14.000000000 +0100
+++ RackTables-0.20.1/wwwroot/inc/navigation.php 2012-12-07 11:56:17.869570284 +0000
@@ -35,6 +35,8 @@
$svghandler = array();
$ajaxhandler = array();
+$portlethandler = array();
+
$indexlayout = array
(
array ('rackspace', 'depot', 'ipv4space', 'ipv6space'),
@@ -254,6 +256,15 @@
$ophandler['object']['cacti']['del'] = 'tableHandler';
$ophandler['object']['ucs']['autoPopulateUCS'] = 'autoPopulateUCS';
$ophandler['object']['ucs']['cleanupUCS'] = 'cleanupUCS';
+$portlethandler['object']['default']['left'][] = array( 'name' => 'Summary', 'callback' => 'renderObPortletSummary' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'Comment', 'callback' => 'renderObPortletComment' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'Log', 'callback' => 'renderObPortletLog' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'Files', 'callback' => 'renderObPortletFiles' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'Ports', 'callback' => 'renderObPortletPorts' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'IPAddresses', 'callback' => 'renderObPortletIPAddresses' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'NATv4', 'callback' => 'renderObPortletNATv4' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'SLBTriplets', 'callback' => 'renderObPortletSLBTriplets' );
+$portlethandler['object']['default']['right'][] = array( 'name' => 'Rackspace', 'callback' => 'renderObPortletRackspace' );
$delayauth['object-8021qports-save8021QConfig'] = TRUE;
$delayauth['object-livevlans-setPortVLAN'] = TRUE;
$delayauth['object-8021qorder-add'] = TRUE;
diff -urN RackTables-0.20.1-orig/wwwroot/inc/portlets.php RackTables-0.20.1/wwwroot/inc/portlets.php
--- RackTables-0.20.1-orig/wwwroot/inc/portlets.php 1970-01-01 01:00:00.000000000 +0100
+++ RackTables-0.20.1/wwwroot/inc/portlets.php 2012-12-07 12:15:22.959570886 +0000
@@ -0,0 +1,248 @@
+<?php
+
+function renderObPortletSummary ( $info )
+{
+ $object_id = $info['id'];
+ $summary = array();
+ if (strlen ($info['name']))
+ $summary['Common name'] = $info['name'];
+ elseif (considerConfiguredConstraint ($info, 'NAMEWARN_LISTSRC'))
+ $summary[] = array ('<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>');
+ $summary['Object type'] = '<a href="' . makeHref (array (
+ 'page' => 'depot',
+ 'tab' => 'default',
+ 'cfe' => '{$typeid_' . $info['objtype_id'] . '}'
+ )) . '">' . decodeObjectType ($info['objtype_id'], 'o') . '</a>';
+ if (strlen ($info['label']))
+ $summary['Visible label'] = $info['label'];
+ if (strlen ($info['asset_no']))
+ $summary['Asset tag'] = $info['asset_no'];
+ elseif (considerConfiguredConstraint ($info, 'ASSETWARN_LISTSRC'))
+ $summary[] = array ('<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>');
+ $parents = getEntityRelatives ('parents', 'object', $object_id);
+ if (count ($parents))
+ {
+ $fmt_parents = array();
+ foreach ($parents as $parent)
+ $fmt_parents[] = "<a href='".makeHref(array('page'=>$parent['page'], $parent['id_name'] => $parent['entity_id']))."'>${parent['name']}</a>";
+ $summary[count($parents) > 1 ? 'Containers' : 'Container'] = implode ('<br>', $fmt_parents);
+ }
+ $children = getEntityRelatives ('children', 'object', $object_id);
+ if (count ($children))
+ {
+ $fmt_children = array();
+ foreach ($children as $child)
+ $fmt_children[] = "<a href='".makeHref(array('page'=>$child['page'], $child['id_name']=>$child['entity_id']))."'>${child['name']}</a>";
+ $summary['Contains'] = implode ('<br>', $fmt_children);
+ }
+ if ($info['has_problems'] == 'yes')
+ $summary[] = array ('<tr><td colspan=2 class=msg_error>Has problems</td></tr>');
+ foreach (getAttrValues ($object_id) as $record)
+ if
+ (
+ strlen ($record['value']) and
+ permitted (NULL, NULL, NULL, array (array ('tag' => '$attr_' . $record['id'])))
+ )
+ $summary['{sticker}' . $record['name']] = formatAttributeValue ($record);
+ $summary[] = array (getOutputOf ('printTagTRs',
+ $info,
+ makeHref
+ (
+ array
+ (
+ 'page'=>'depot',
+ 'tab'=>'default',
+ 'andor' => 'and',
+ 'cfe' => '{$typeid_' . $info['objtype_id'] . '}',
+ )
+ )."&"
+ ));
+ renderEntitySummary ($info, 'summary', $summary);
+}
+
+function renderObPortletComment ( $info )
+{
+
+ if (strlen ($info['comment']))
+ {
+ startPortlet ('Comment');
+ echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
+ finishPortlet ();
+ }
+}
+
+function renderObPortletLog ( $info )
+{
+ $logrecords = getLogRecordsForObject ($_REQUEST['object_id']);
+ if (count ($logrecords))
+ {
+ startPortlet ('log records');
+ echo "<table cellspacing=0 cellpadding=5 align=center class=widetable width='100%'>";
+ $order = 'odd';
+ foreach ($logrecords as $row)
+ {
+ echo "<tr class=row_${order} valign=top>";
+ echo '<td class=tdleft>' . $row['date'] . '<br>' . $row['user'] . '</td>';
+ echo '<td class="logentry">' . string_insert_hrefs (htmlspecialchars ($row['content'], ENT_NOQUOTES)) . '</td>';
+ echo '</tr>';
+ $order = $nextorder[$order];
+ }
+ echo '</table>';
+ finishPortlet();
+ }
+}
+
+function renderObPortletFiles ( $info )
+{
+ $object_id = $info['id'];
+ switchportInfoJS ($object_id); // load JS code to make portnames interactive
+ renderFilesPortlet ('object', $object_id);
+}
+
+function renderObPortletPorts ( $info )
+{
+ if (count ($info['ports']))
+ {
+ startPortlet ('Ports / Links');
+ $hl_port_id = 0;
+ if (isset ($_REQUEST['hl_port_id']))
+ {
+ assertUIntArg ('hl_port_id');
+ $hl_port_id = $_REQUEST['hl_port_id'];
+ addAutoScrollScript ("port-$hl_port_id");
+ }
+ echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>";
+ echo '<tr><th class=tdleft>Local name</th><th class=tdleft>Visible label</th>';
+ echo '<th class=tdleft>Interface</th><th class=tdleft>L2 address</th>';
+ echo '<th class=tdcenter colspan=2>Remote object and port</th>';
+ echo '<th class=tdleft>Cable ID</th></tr>';
+ foreach ($info['ports'] as $port)
+ callHook ('renderObjectPortRow', $port, ($hl_port_id == $port['id']));
+ if (permitted (NULL, 'ports', 'set_reserve_comment'))
+ addJS ('js/inplace-edit.js');
+ echo "</table><br>";
+ finishPortlet();
+ }
+}
+
+function renderObPortletIPAddresses ( $info )
+{
+ if (count ($info['ipv4']) + count ($info['ipv6']))
+ {
+ startPortlet ('IP Addresses');
+ echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
+ if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
+ echo "<tr><th>OS interface</th><th>IP address</th><th>network</th><th>routed by</th><th>peers</th></tr>\n";
+ else
+ echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
+
+ // group IP allocations by interface name instead of address family
+ $allocs_by_iface = array();
+ foreach (array ('ipv4', 'ipv6') as $ip_v)
+ foreach ($info[$ip_v] as $ip_bin => $alloc)
+ $allocs_by_iface[$alloc['osif']][$ip_bin] = $alloc;
+
+ // sort allocs array by portnames
+ foreach (sortPortList ($allocs_by_iface) as $iface_name => $alloclist)
+ {
+ $is_first_row = TRUE;
+ foreach ($alloclist as $alloc)
+ {
+ $rendered_alloc = callHook ('getRenderedAlloc', $object_id, $alloc);
+ echo "<tr class='${rendered_alloc['tr_class']}' valign=top>";
+
+ // display iface name, same values are grouped into single cell
+ if ($is_first_row)
+ {
+ $rowspan = count ($alloclist) > 1 ? 'rowspan="' . count ($alloclist) . '"' : '';
+ echo "<td class=tdleft $rowspan>" . $iface_name . $rendered_alloc['td_name_suffix'] . "</td>";
+ $is_first_row = FALSE;
+ }
+ echo $rendered_alloc['td_ip'];
+ if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
+ {
+ echo $rendered_alloc['td_network'];
+ echo $rendered_alloc['td_routed_by'];
+ }
+ echo $rendered_alloc['td_peers'];
+ echo "</tr>\n";
+ }
+ }
+ echo "</table><br>\n";
+ finishPortlet();
+ }
+}
+
+function renderObPortletNATv4 ( $info )
+{
+ $forwards = $info['nat4'];
+ if (count($forwards['in']) or count($forwards['out']))
+ {
+ startPortlet('NATv4');
+
+ if (count($forwards['out']))
+ {
+
+ echo "<h3>locally performed NAT</h3>";
+
+ echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
+ echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
+
+ foreach ($forwards['out'] as $pf)
+ {
+ $class = 'trerror';
+ $osif = '';
+ if (isset ($alloclist [$pf['localip']]))
+ {
+ $class = $alloclist [$pf['localip']]['addrinfo']['class'];
+ $osif = $alloclist [$pf['localip']]['osif'] . ': ';
+ }
+ echo "<tr class='$class'>";
+ echo "<td>${pf['proto']}</td><td class=tdleft>${osif}" . getRenderedIPPortPair ($pf['localip'], $pf['localport']) . "</td>";
+ echo "<td class=tdleft>" . getRenderedIPPortPair ($pf['remoteip'], $pf['remoteport']) . "</td>";
+ $address = getIPAddress (ip4_parse ($pf['remoteip']));
+ echo "<td class='description'>";
+ if (count ($address['allocs']))
+ foreach($address['allocs'] as $bond)
+ echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
+ elseif (strlen ($pf['remote_addr_name']))
+ echo '(' . $pf['remote_addr_name'] . ')';
+ echo "</td><td class='description'>${pf['description']}</td></tr>";
+ }
+ echo "</table><br><br>";
+ }
+ if (count($forwards['in']))
+ {
+ echo "<h3>arriving NAT connections</h3>";
+ echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
+ echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
+ foreach ($forwards['in'] as $pf)
+ {
+ echo "<tr>";
+ echo "<td>${pf['proto']}/" . getRenderedIPPortPair ($pf['localip'], $pf['localport']) . "</td>";
+ echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
+ echo "</td><td>" . getRenderedIPPortPair ($pf['remoteip'], $pf['remoteport']) . "</td>";
+ echo "<td class='description'>${pf['description']}</td></tr>";
+ }
+ echo "</table><br><br>";
+ }
+ finishPortlet();
+ }
+}
+
+function renderObPortletSLBTriplets ( $info )
+{
+ renderSLBTriplets ($info);
+}
+
+function renderObPortletRackspace ( $info )
+{ if (!in_array($info['objtype_id'], $virtual_obj_types))
+ {
+ // rackspace portlet
+ startPortlet ('rackspace allocation');
+ foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
+ renderRack ($rack_id, $object_id);
+ echo '<br>';
+ finishPortlet();
+ }
+}
racktables-0-20-3.patch (25,512 bytes)
diff -uNr RackTables-0.20.3-orig/plugins/demo-plugin.php RackTables-0.20.3-dev/plugins/demo-plugin.php
--- RackTables-0.20.3-orig/plugins/demo-plugin.php 1970-01-01 01:00:00.000000000 +0100
+++ RackTables-0.20.3-dev/plugins/demo-plugin.php 2012-12-24 10:23:11.999568017 +0000
@@ -0,0 +1,65 @@
+<?php
+
+$tab['object']['demo'] = 'Demo';
+registerTabHandler('object', 'demo', 'myRenderDemo');
+registerOpHandler('object', 'demo', 'update', 'updateDemo');
+registerPortletHandler( 'object', 'default', 'left', 'Demo', 'myRenderObPortletDemo', 'after', 'Comment');
+
+$tab['reports']['demo'] = 'Demo Report';
+registerTabHandler('reports', 'demo', 'myRenderDemoReport');
+
+
+function myRenderObPortletDemo ( $info )
+{
+ startPortlet('Demo Plugin Portlet');
+ echo "This text was produced by the Demo Plugin\n";
+ finishPortlet();
+}
+
+$msgcode['updateDemo']['OK'] = 43;
+function updateDemo()
+{
+ assertUIntArg ('object_id');
+//
+// Update something here
+//
+
+ showFuncMessage (__FUNCTION__, 'OK');
+ return buildRedirectURL (NULL, NULL, NULL);
+}
+
+function myRenderDemo ()
+{
+ global $pageno, $virtual_obj_types;
+ $object_id = getBypassValue();
+ $info = spotEntity ('object', $object_id);
+ amplifyCell ($info);
+
+ startPortlet ();
+ printOpFormIntro ('update');
+
+ echo '<table border=0 cellspacing=0 cellpadding=3 align=center>';
+ echo "<tr>";
+ echo "<td> </td>";
+ echo "<td>Insert form here</td>";
+ echo "<td> </td>";
+ echo "</tr>\n";
+ echo "<tr><th class=submit colspan=3>";
+ printImageHREF ('SAVE', 'Save changes', TRUE);
+
+ echo "</tr></table>";
+
+
+ echo "</form></th></tr></table>\n";
+ finishPortlet();
+
+}
+
+function myRenderDemoReport ()
+{
+ echo '<table border=0 cellspacing=0 cellpadding=3 align=center>';
+ echo "<tr><th><h3>Demo Report</h3></th></tr>\n";
+ echo "<td>Insert form here</td>";
+ echo "</tr>\n";
+ echo "</tr></table>";
+}
diff -uNr RackTables-0.20.3-orig/wwwroot/inc/functions.php RackTables-0.20.3-dev/wwwroot/inc/functions.php
--- RackTables-0.20.3-orig/wwwroot/inc/functions.php 2012-12-19 16:30:47.000000000 +0000
+++ RackTables-0.20.3-dev/wwwroot/inc/functions.php 2012-12-24 09:19:41.299570063 +0000
@@ -5705,4 +5705,51 @@
return $ret;
}
+// Registers additional portleyhandler on page-tab-column triplet.
+// Valid $column values are 'left', 'right'
+// 'left' puts you portlet in the left hand column on a page (default)
+// 'right' puts you portlet in the left hand column on a page
+// $name is used as an identifer when inserting between current portlets
+// Valid $method values are 'before', 'after'.
+// 'before' puts your tabhandler in the beginning of the list (and thus before the default)
+// 'after' puts your tabhandler to the end of the list (and thus after the default)
+// $name2 modified the behaviour of $method to insert the new portlet between currently definded portlets on
+// the page.
+function registerPortletHandler ($page, $tab, $column = 'left', $name, $callback, $method = 'after', $name2 = '')
+{
+ global $portlethandler;
+
+ if ($name2 == '')
+ if ($method == 'before')
+ array_unshift ($portlethandler[$page][$tab][$column], array( 'name' => $name, 'callback' => $callback));
+ elseif ($method == 'after')
+ array_push ($portlethandler[$page][$tab][$column], array( 'name' => $name, 'callback' => $callback));
+ else
+ throw new RacktablesError ("unknown portlethandler injection method '$method'", RackTablesError::INTERNAL);
+ else
+ {
+ $done = 0;
+ foreach ($portlethandler[$page][$tab][$column] as $idx => $portlet)
+ if ($portlet['name'] == $name2)
+ {
+ if ($method == 'before')
+ {
+ array_splice($portlethandler[$page][$tab][$column], $idx, 0, array(array('name'=> $name, 'callback' => $callback)));
+ $done = 1;
+ }
+ elseif ($method == 'after')
+ {
+ array_splice($portlethandler[$page][$tab][$column], ($idx+1), 0, array(array('name'=> $name, 'callback' => $callback)));
+ $done = 1;
+ }
+ else
+ throw new RacktablesError ("unknown portlethandler injection method '$method'", RackTablesError::INTERNAL);
+ break;
+ }
+ if ( ! $done )
+ throw new RacktablesError ("unknown portlet ($name2) to insert $method", RackTablesError::MISCONFIGURED);
+ }
+
+}
+
?>
diff -uNr RackTables-0.20.3-orig/wwwroot/inc/interface.php RackTables-0.20.3-dev/wwwroot/inc/interface.php
--- RackTables-0.20.3-orig/wwwroot/inc/interface.php 2012-12-19 16:30:47.000000000 +0000
+++ RackTables-0.20.3-dev/wwwroot/inc/interface.php 2012-12-24 09:53:52.859568602 +0000
@@ -12,6 +12,7 @@
require_once 'ajax-interface.php';
require_once 'slb-interface.php';
+require_once 'portlets.php';
// Interface function's special.
$nextorder['odd'] = 'even';
@@ -1098,243 +1099,32 @@
echo "</tr>";
}
+
function renderObject ($object_id)
{
global $nextorder, $virtual_obj_types;
+ global $portlethandler;
$info = spotEntity ('object', $object_id);
amplifyCell ($info);
// Main layout starts.
echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
// left column with uknown number of portlets
- echo "<tr><td class=pcleft>";
-
- // display summary portlet
- $summary = array();
- if (strlen ($info['name']))
- $summary['Common name'] = $info['name'];
- elseif (considerConfiguredConstraint ($info, 'NAMEWARN_LISTSRC'))
- $summary[] = array ('<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>');
- $summary['Object type'] = '<a href="' . makeHref (array (
- 'page' => 'depot',
- 'tab' => 'default',
- 'cfe' => '{$typeid_' . $info['objtype_id'] . '}'
- )) . '">' . decodeObjectType ($info['objtype_id'], 'o') . '</a>';
- if (strlen ($info['label']))
- $summary['Visible label'] = $info['label'];
- if (strlen ($info['asset_no']))
- $summary['Asset tag'] = $info['asset_no'];
- elseif (considerConfiguredConstraint ($info, 'ASSETWARN_LISTSRC'))
- $summary[] = array ('<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>');
- $parents = getEntityRelatives ('parents', 'object', $object_id);
- if (count ($parents))
- {
- $fmt_parents = array();
- foreach ($parents as $parent)
- $fmt_parents[] = "<a href='".makeHref(array('page'=>$parent['page'], $parent['id_name'] => $parent['entity_id']))."'>${parent['name']}</a>";
- $summary[count($parents) > 1 ? 'Containers' : 'Container'] = implode ('<br>', $fmt_parents);
- }
- $children = getEntityRelatives ('children', 'object', $object_id);
- if (count ($children))
- {
- $fmt_children = array();
- foreach ($children as $child)
- $fmt_children[] = "<a href='".makeHref(array('page'=>$child['page'], $child['id_name']=>$child['entity_id']))."'>${child['name']}</a>";
- $summary['Contains'] = implode ('<br>', $fmt_children);
- }
- if ($info['has_problems'] == 'yes')
- $summary[] = array ('<tr><td colspan=2 class=msg_error>Has problems</td></tr>');
- foreach (getAttrValues ($object_id) as $record)
- if
- (
- strlen ($record['value']) and
- permitted (NULL, NULL, NULL, array (array ('tag' => '$attr_' . $record['id'])))
- )
- $summary['{sticker}' . $record['name']] = formatAttributeValue ($record);
- $summary[] = array (getOutputOf ('printTagTRs',
- $info,
- makeHref
- (
- array
- (
- 'page'=>'depot',
- 'tab'=>'default',
- 'andor' => 'and',
- 'cfe' => '{$typeid_' . $info['objtype_id'] . '}',
- )
- )."&"
- ));
- renderEntitySummary ($info, 'summary', $summary);
-
- if (strlen ($info['comment']))
- {
- startPortlet ('Comment');
- echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
- finishPortlet ();
- }
-
- $logrecords = getLogRecordsForObject ($_REQUEST['object_id']);
- if (count ($logrecords))
- {
- startPortlet ('log records');
- echo "<table cellspacing=0 cellpadding=5 align=center class=widetable width='100%'>";
- $order = 'odd';
- foreach ($logrecords as $row)
- {
- echo "<tr class=row_${order} valign=top>";
- echo '<td class=tdleft>' . $row['date'] . '<br>' . $row['user'] . '</td>';
- echo '<td class="logentry">' . string_insert_hrefs (htmlspecialchars ($row['content'], ENT_NOQUOTES)) . '</td>';
- echo '</tr>';
- $order = $nextorder[$order];
- }
- echo '</table>';
- finishPortlet();
- }
-
- switchportInfoJS ($object_id); // load JS code to make portnames interactive
- renderFilesPortlet ('object', $object_id);
-
- if (count ($info['ports']))
- {
- startPortlet ('ports and links');
- $hl_port_id = 0;
- if (isset ($_REQUEST['hl_port_id']))
- {
- assertUIntArg ('hl_port_id');
- $hl_port_id = $_REQUEST['hl_port_id'];
- addAutoScrollScript ("port-$hl_port_id");
- }
- echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>";
- echo '<tr><th class=tdleft>Local name</th><th class=tdleft>Visible label</th>';
- echo '<th class=tdleft>Interface</th><th class=tdleft>L2 address</th>';
- echo '<th class=tdcenter colspan=2>Remote object and port</th>';
- echo '<th class=tdleft>Cable ID</th></tr>';
- foreach ($info['ports'] as $port)
- callHook ('renderObjectPortRow', $port, ($hl_port_id == $port['id']));
- if (permitted (NULL, 'ports', 'set_reserve_comment'))
- addJS ('js/inplace-edit.js');
- echo "</table><br>";
- finishPortlet();
- }
-
- if (count ($info['ipv4']) + count ($info['ipv6']))
- {
- startPortlet ('IP addresses');
- echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
- if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
- echo "<tr><th>OS interface</th><th>IP address</th><th>network</th><th>routed by</th><th>peers</th></tr>\n";
- else
- echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
-
- // group IP allocations by interface name instead of address family
- $allocs_by_iface = array();
- foreach (array ('ipv4', 'ipv6') as $ip_v)
- foreach ($info[$ip_v] as $ip_bin => $alloc)
- $allocs_by_iface[$alloc['osif']][$ip_bin] = $alloc;
-
- // sort allocs array by portnames
- foreach (sortPortList ($allocs_by_iface) as $iface_name => $alloclist)
- {
- $is_first_row = TRUE;
- foreach ($alloclist as $alloc)
- {
- $rendered_alloc = callHook ('getRenderedAlloc', $object_id, $alloc);
- echo "<tr class='${rendered_alloc['tr_class']}' valign=top>";
-
- // display iface name, same values are grouped into single cell
- if ($is_first_row)
- {
- $rowspan = count ($alloclist) > 1 ? 'rowspan="' . count ($alloclist) . '"' : '';
- echo "<td class=tdleft $rowspan>" . $iface_name . $rendered_alloc['td_name_suffix'] . "</td>";
- $is_first_row = FALSE;
- }
- echo $rendered_alloc['td_ip'];
- if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
- {
- echo $rendered_alloc['td_network'];
- echo $rendered_alloc['td_routed_by'];
- }
- echo $rendered_alloc['td_peers'];
-
- echo "</tr>\n";
- }
- }
- echo "</table><br>\n";
- finishPortlet();
- }
-
- $forwards = $info['nat4'];
- if (count($forwards['in']) or count($forwards['out']))
+ echo "<tr>";
+ foreach (array('left','right') as $side)
{
- startPortlet('NATv4');
+ echo "<td class=pc$side>";
- if (count($forwards['out']))
+ foreach ($portlethandler['object']['default'][$side] as $idx => $portlet)
{
-
- echo "<h3>locally performed NAT</h3>";
-
- echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
- echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
-
- foreach ($forwards['out'] as $pf)
- {
- $class = 'trerror';
- $osif = '';
- if (isset ($alloclist [$pf['localip']]))
- {
- $class = $alloclist [$pf['localip']]['addrinfo']['class'];
- $osif = $alloclist [$pf['localip']]['osif'] . ': ';
- }
- echo "<tr class='$class'>";
- echo "<td>${pf['proto']}</td><td class=tdleft>${osif}" . getRenderedIPPortPair ($pf['localip'], $pf['localport']) . "</td>";
- echo "<td class=tdleft>" . getRenderedIPPortPair ($pf['remoteip'], $pf['remoteport']) . "</td>";
- $address = getIPAddress (ip4_parse ($pf['remoteip']));
- echo "<td class='description'>";
- if (count ($address['allocs']))
- foreach($address['allocs'] as $bond)
- echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
- elseif (strlen ($pf['remote_addr_name']))
- echo '(' . $pf['remote_addr_name'] . ')';
- echo "</td><td class='description'>${pf['description']}</td></tr>";
- }
- echo "</table><br><br>";
- }
- if (count($forwards['in']))
- {
- echo "<h3>arriving NAT connections</h3>";
- echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
- echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
- foreach ($forwards['in'] as $pf)
- {
- echo "<tr>";
- echo "<td>${pf['proto']}/" . getRenderedIPPortPair ($pf['localip'], $pf['localport']) . "</td>";
- echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
- echo "</td><td>" . getRenderedIPPortPair ($pf['remoteip'], $pf['remoteport']) . "</td>";
- echo "<td class='description'>${pf['description']}</td></tr>";
- }
- echo "</table><br><br>";
+ call_user_func($portlet['callback'], $info );
}
- finishPortlet();
+ echo "</td>\n";
}
- renderSLBTriplets ($info);
- echo "</td>\n";
-
- // After left column we have (surprise!) right column with rackspace portlet only.
- echo "<td class=pcright>";
- if (!in_array($info['objtype_id'], $virtual_obj_types))
- {
- // rackspace portlet
- startPortlet ('rackspace allocation');
- foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
- renderRack ($rack_id, $object_id);
- echo '<br>';
- finishPortlet();
- }
- echo "</td></tr>";
echo "</table>\n";
}
-
+
function renderRackMultiSelect ($sname, $racks, $selected)
{
// Transform the given flat list into a list of groups, each representing a rack row.
diff -uNr RackTables-0.20.3-orig/wwwroot/inc/navigation.php RackTables-0.20.3-dev/wwwroot/inc/navigation.php
--- RackTables-0.20.3-orig/wwwroot/inc/navigation.php 2012-12-19 16:30:47.000000000 +0000
+++ RackTables-0.20.3-dev/wwwroot/inc/navigation.php 2012-12-24 09:19:41.299570063 +0000
@@ -35,6 +35,8 @@
$svghandler = array();
$ajaxhandler = array();
+$portlethandler = array();
+
$indexlayout = array
(
array ('rackspace', 'depot', 'ipv4space', 'ipv6space'),
@@ -254,6 +256,15 @@
$ophandler['object']['munin']['del'] = 'tableHandler';
$ophandler['object']['ucs']['autoPopulateUCS'] = 'autoPopulateUCS';
$ophandler['object']['ucs']['cleanupUCS'] = 'cleanupUCS';
+$portlethandler['object']['default']['left'][] = array( 'name' => 'Summary', 'callback' => 'renderObPortletSummary' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'Comment', 'callback' => 'renderObPortletComment' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'Log', 'callback' => 'renderObPortletLog' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'Files', 'callback' => 'renderObPortletFiles' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'Ports', 'callback' => 'renderObPortletPorts' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'IPAddresses', 'callback' => 'renderObPortletIPAddresses' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'NATv4', 'callback' => 'renderObPortletNATv4' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'SLBTriplets', 'callback' => 'renderObPortletSLBTriplets' );
+$portlethandler['object']['default']['right'][] = array( 'name' => 'Rackspace', 'callback' => 'renderObPortletRackspace' );
$delayauth['object-8021qports-save8021QConfig'] = TRUE;
$delayauth['object-8021qorder-add'] = TRUE;
$delayauth['object-8021qorder-del'] = TRUE;
diff -uNr RackTables-0.20.3-orig/wwwroot/inc/portlets.php RackTables-0.20.3-dev/wwwroot/inc/portlets.php
--- RackTables-0.20.3-orig/wwwroot/inc/portlets.php 1970-01-01 01:00:00.000000000 +0100
+++ RackTables-0.20.3-dev/wwwroot/inc/portlets.php 2012-12-24 10:05:22.559572928 +0000
@@ -0,0 +1,261 @@
+<?php
+
+function renderObPortletSummary ( $info )
+{
+ $object_id = $info['id'];
+ $summary = array();
+ if (strlen ($info['name']))
+ $summary['Common name'] = $info['name'];
+ elseif (considerConfiguredConstraint ($info, 'NAMEWARN_LISTSRC'))
+ $summary[] = array ('<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>');
+ $summary['Object type'] = '<a href="' . makeHref (array (
+ 'page' => 'depot',
+ 'tab' => 'default',
+ 'cfe' => '{$typeid_' . $info['objtype_id'] . '}'
+ )) . '">' . decodeObjectType ($info['objtype_id'], 'o') . '</a>';
+ if (strlen ($info['label']))
+ $summary['Visible label'] = $info['label'];
+ if (strlen ($info['asset_no']))
+ $summary['Asset tag'] = $info['asset_no'];
+ elseif (considerConfiguredConstraint ($info, 'ASSETWARN_LISTSRC'))
+ $summary[] = array ('<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>');
+ $parents = getEntityRelatives ('parents', 'object', $object_id);
+ if (count ($parents))
+ {
+ $fmt_parents = array();
+ foreach ($parents as $parent)
+ $fmt_parents[] = "<a href='".makeHref(array('page'=>$parent['page'], $parent['id_name'] => $parent['entity_id']))."'>${parent['name']}</a>";
+ $summary[count($parents) > 1 ? 'Containers' : 'Container'] = implode ('<br>', $fmt_parents);
+ }
+ $children = getEntityRelatives ('children', 'object', $object_id);
+ if (count ($children))
+ {
+ $fmt_children = array();
+ foreach ($children as $child)
+ $fmt_children[] = "<a href='".makeHref(array('page'=>$child['page'], $child['id_name']=>$child['entity_id']))."'>${child['name']}</a>";
+ $summary['Contains'] = implode ('<br>', $fmt_children);
+ }
+ if ($info['has_problems'] == 'yes')
+ $summary[] = array ('<tr><td colspan=2 class=msg_error>Has problems</td></tr>');
+ foreach (getAttrValues ($object_id) as $record)
+ if
+ (
+ strlen ($record['value']) and
+ permitted (NULL, NULL, NULL, array (array ('tag' => '$attr_' . $record['id'])))
+ )
+ $summary['{sticker}' . $record['name']] = formatAttributeValue ($record);
+ $summary[] = array (getOutputOf ('printTagTRs',
+ $info,
+ makeHref
+ (
+ array
+ (
+ 'page'=>'depot',
+ 'tab'=>'default',
+ 'andor' => 'and',
+ 'cfe' => '{$typeid_' . $info['objtype_id'] . '}',
+ )
+ )."&"
+ ));
+ renderEntitySummary ($info, 'summary', $summary);
+}
+
+function renderObPortletComments ( $info )
+{
+ $object_id = $info['id'];
+
+ if (strlen ($info['comment']))
+ {
+ startPortlet ('Comment');
+ echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
+ finishPortlet ();
+ }
+}
+
+function renderObPortletLog ( $info )
+{
+ $object_id = $info['id'];
+
+ $logrecords = getLogRecordsForObject ($object_id);
+ if (count ($logrecords))
+ {
+ startPortlet ('log records');
+ echo "<table cellspacing=0 cellpadding=5 align=center class=widetable width='100%'>";
+ $order = 'odd';
+ foreach ($logrecords as $row)
+ {
+ echo "<tr class=row_${order} valign=top>";
+ echo '<td class=tdleft>' . $row['date'] . '<br>' . $row['user'] . '</td>';
+ echo '<td class="logentry">' . string_insert_hrefs (htmlspecialchars ($row['content'], ENT_NOQUOTES)) . '</td>';
+ echo '</tr>';
+ $order = $nextorder[$order];
+ }
+ echo '</table>';
+ finishPortlet();
+ }
+}
+
+function renderObPortletFiles ( $info )
+{
+ $object_id = $info['id'];
+ renderFilesPortlet ('object', $object_id);
+}
+
+function renderObPortletPorts ( $info )
+{
+ $object_id = $info['id'];
+
+ switchportInfoJS ($object_id); // load JS code to make portnames interactive
+ if (count ($info['ports']))
+ {
+ startPortlet ('ports and links');
+ $hl_port_id = 0;
+ if (isset ($_REQUEST['hl_port_id']))
+ {
+ assertUIntArg ('hl_port_id');
+ $hl_port_id = $_REQUEST['hl_port_id'];
+ addAutoScrollScript ("port-$hl_port_id");
+ }
+ echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>";
+ echo '<tr><th class=tdleft>Local name</th><th class=tdleft>Visible label</th>';
+ echo '<th class=tdleft>Interface</th><th class=tdleft>L2 address</th>';
+ echo '<th class=tdcenter colspan=2>Remote object and port</th>';
+ echo '<th class=tdleft>Cable ID</th></tr>';
+ foreach ($info['ports'] as $port)
+ callHook ('renderObjectPortRow', $port, ($hl_port_id == $port['id']));
+ if (permitted (NULL, 'ports', 'set_reserve_comment'))
+ addJS ('js/inplace-edit.js');
+ echo "</table><br>";
+ finishPortlet();
+ }
+}
+
+function renderObPortletIPAddresses ( $info )
+{
+ $object_id = $info['id'];
+
+ if (count ($info['ipv4']) + count ($info['ipv6']))
+ {
+ startPortlet ('IP addresses');
+ echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
+ if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
+ echo "<tr><th>OS interface</th><th>IP address</th><th>network</th><th>routed by</th><th>peers</th></tr>\n";
+ else
+ echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
+
+ // group IP allocations by interface name instead of address family
+ $allocs_by_iface = array();
+ foreach (array ('ipv4', 'ipv6') as $ip_v)
+ foreach ($info[$ip_v] as $ip_bin => $alloc)
+ $allocs_by_iface[$alloc['osif']][$ip_bin] = $alloc;
+
+ // sort allocs array by portnames
+ foreach (sortPortList ($allocs_by_iface) as $iface_name => $alloclist)
+ {
+ $is_first_row = TRUE;
+ foreach ($alloclist as $alloc)
+ {
+ $rendered_alloc = callHook ('getRenderedAlloc', $object_id, $alloc);
+ echo "<tr class='${rendered_alloc['tr_class']}' valign=top>";
+
+ // display iface name, same values are grouped into single cell
+ if ($is_first_row)
+ {
+ $rowspan = count ($alloclist) > 1 ? 'rowspan="' . count ($alloclist) . '"' : '';
+ echo "<td class=tdleft $rowspan>" . $iface_name . $rendered_alloc['td_name_suffix'] . "</td>";
+ $is_first_row = FALSE;
+ }
+ echo $rendered_alloc['td_ip'];
+ if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
+ {
+ echo $rendered_alloc['td_network'];
+ echo $rendered_alloc['td_routed_by'];
+ }
+ echo $rendered_alloc['td_peers'];
+
+ echo "</tr>\n";
+ }
+ }
+ echo "</table><br>\n";
+ finishPortlet();
+ }
+}
+
+function renderObPortletNATv4 ( $info )
+{
+ $forwards = $info['nat4'];
+ if (count($forwards['in']) or count($forwards['out']))
+ {
+ startPortlet('NATv4');
+
+ if (count($forwards['out']))
+ {
+
+ echo "<h3>locally performed NAT</h3>";
+
+ echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
+ echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
+
+ foreach ($forwards['out'] as $pf)
+ {
+ $class = 'trerror';
+ $osif = '';
+ if (isset ($alloclist [$pf['localip']]))
+ {
+ $class = $alloclist [$pf['localip']]['addrinfo']['class'];
+ $osif = $alloclist [$pf['localip']]['osif'] . ': ';
+ }
+ echo "<tr class='$class'>";
+ echo "<td>${pf['proto']}</td><td class=tdleft>${osif}" . getRenderedIPPortPair ($pf['localip'], $pf['localport']) . "</td>";
+ echo "<td class=tdleft>" . getRenderedIPPortPair ($pf['remoteip'], $pf['remoteport']) . "</td>";
+ $address = getIPAddress (ip4_parse ($pf['remoteip']));
+ echo "<td class='description'>";
+ if (count ($address['allocs']))
+ foreach($address['allocs'] as $bond)
+ echo "<a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$bond['object_id']))."'>${bond['object_name']}(${bond['name']})</a> ";
+ elseif (strlen ($pf['remote_addr_name']))
+ echo '(' . $pf['remote_addr_name'] . ')';
+ echo "</td><td class='description'>${pf['description']}</td></tr>";
+ }
+ echo "</table><br><br>";
+ }
+ if (count($forwards['in']))
+ {
+ echo "<h3>arriving NAT connections</h3>";
+ echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
+ echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
+ foreach ($forwards['in'] as $pf)
+ {
+ echo "<tr>";
+ echo "<td>${pf['proto']}/" . getRenderedIPPortPair ($pf['localip'], $pf['localport']) . "</td>";
+ echo "<td class='description'><a href='".makeHref(array('page'=>'object', 'tab'=>'default', 'object_id'=>$pf['object_id']))."'>${pf['object_name']}</a>";
+ echo "</td><td>" . getRenderedIPPortPair ($pf['remoteip'], $pf['remoteport']) . "</td>";
+ echo "<td class='description'>${pf['description']}</td></tr>";
+ }
+ echo "</table><br><br>";
+ }
+ finishPortlet();
+ }
+}
+
+function renderObPortletSLBTriplets ( $info )
+{
+ renderSLBTriplets ($info);
+}
+
+function renderObPortletRackspace ( $info )
+{
+ $object_id = $info['id'];
+
+ if (!in_array($info['objtype_id'], $virtual_obj_types))
+ {
+ // rackspace portlet
+ startPortlet ('rackspace allocation');
+ foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
+ renderRack ($rack_id, $object_id);
+ echo '<br>';
+ finishPortlet();
+ }
+}
+
+?>
portlet-0.20.4.patch (27,799 bytes)
diff -uNr RackTables-0.20.4-orig/plugins/demo-plugin.php RackTables-0.20.4-dev/plugins/demo-plugin.php
--- RackTables-0.20.4-orig/plugins/demo-plugin.php 1970-01-01 01:00:00.000000000 +0100
+++ RackTables-0.20.4-dev/plugins/demo-plugin.php 2013-04-16 15:16:16.211660164 +0100
@@ -0,0 +1,75 @@
+<?php
+
+$tab['object']['demo'] = 'Demo';
+registerTabHandler('object', 'demo', 'myRenderDemo');
+registerOpHandler('object', 'demo', 'update', 'updateDemo');
+if ( function_exists('registerPortletHandler') )
+{
+ registerPortletHandler( 'object', 'default', 'left', 'Demo', 'myRenderObPortletDemo', 'after', 'Comment');
+ registerPortletHandler( 'object', 'default', 'right', 'Demo', 'myRenderObPortletDemo2');
+}
+
+$tab['reports']['demo'] = 'Demo Report';
+registerTabHandler('reports', 'demo', 'myRenderDemoReport');
+
+
+function myRenderObPortletDemo ( $info )
+{
+ startPortlet('Demo Plugin Portlet');
+ echo "This text was produced by the Demo Plugin\n";
+ finishPortlet();
+}
+function myRenderObPortletDemo2 ( $info )
+{
+ startPortlet('Demo Plugin Portlet');
+ echo "This text was also produced by the Demo Plugin\n";
+ finishPortlet();
+}
+
+$msgcode['updateDemo']['OK'] = 43;
+function updateDemo()
+{
+ assertUIntArg ('object_id');
+//
+// Update something here
+//
+
+ showFuncMessage (__FUNCTION__, 'OK');
+ return buildRedirectURL (NULL, NULL, NULL);
+}
+
+function myRenderDemo ()
+{
+ global $pageno, $virtual_obj_types;
+ $object_id = getBypassValue();
+ $info = spotEntity ('object', $object_id);
+ amplifyCell ($info);
+
+ startPortlet ();
+ printOpFormIntro ('update');
+
+ echo '<table border=0 cellspacing=0 cellpadding=3 align=center>';
+ echo "<tr>";
+ echo "<td> </td>";
+ echo "<td>Insert form here</td>";
+ echo "<td> </td>";
+ echo "</tr>\n";
+ echo "<tr><th class=submit colspan=3>";
+ printImageHREF ('SAVE', 'Save changes', TRUE);
+
+ echo "</tr></table>";
+
+
+ echo "</form></th></tr></table>\n";
+ finishPortlet();
+
+}
+
+function myRenderDemoReport ()
+{
+ echo '<table border=0 cellspacing=0 cellpadding=3 align=center>';
+ echo "<tr><th><h3>Demo Report</h3></th></tr>\n";
+ echo "<td>Insert form here</td>";
+ echo "</tr>\n";
+ echo "</tr></table>";
+}
diff -uNr RackTables-0.20.4-orig/wwwroot/inc/functions.php RackTables-0.20.4-dev/wwwroot/inc/functions.php
--- RackTables-0.20.4-orig/wwwroot/inc/functions.php 2013-04-14 21:27:19.000000000 +0100
+++ RackTables-0.20.4-dev/wwwroot/inc/functions.php 2013-04-16 11:30:30.561661364 +0100
@@ -6045,4 +6045,51 @@
return FALSE;
}
+// Registers additional portleyhandler on page-tab-column triplet.
+// Valid $column values are 'left', 'right'
+// 'left' puts you portlet in the left hand column on a page (default)
+// 'right' puts you portlet in the left hand column on a page
+// $name is used as an identifer when inserting between current portlets
+// Valid $method values are 'before', 'after'.
+// 'before' puts your tabhandler in the beginning of the list (and thus before the default)
+// 'after' puts your tabhandler to the end of the list (and thus after the default)
+// $name2 modified the behaviour of $method to insert the new portlet between currently definded portlets on
+// the page.
+function registerPortletHandler ($page, $tab, $column = 'left', $name, $callback, $method = 'after', $name2 = '')
+{
+ global $portlethandler;
+
+ if ($name2 == '')
+ if ($method == 'before')
+ array_unshift ($portlethandler[$page][$tab][$column], array( 'name' => $name, 'callback' => $callback));
+ elseif ($method == 'after')
+ array_push ($portlethandler[$page][$tab][$column], array( 'name' => $name, 'callback' => $callback));
+ else
+ throw new RacktablesError ("unknown portlethandler injection method '$method'", RackTablesError::INTERNAL);
+ else
+ {
+ $done = 0;
+ foreach ($portlethandler[$page][$tab][$column] as $idx => $portlet)
+ if ($portlet['name'] == $name2)
+ {
+ if ($method == 'before')
+ {
+ array_splice($portlethandler[$page][$tab][$column], $idx, 0, array(array('name'=> $name, 'callback' => $callback)));
+ $done = 1;
+ }
+ elseif ($method == 'after')
+ {
+ array_splice($portlethandler[$page][$tab][$column], ($idx+1), 0, array(array('name'=> $name, 'callback' => $callback)));
+ $done = 1;
+ }
+ else
+ throw new RacktablesError ("unknown portlethandler injection method '$method'", RackTablesError::INTERNAL);
+ break;
+ }
+ if ( ! $done )
+ throw new RacktablesError ("unknown portlet ($name2) to insert $method", RackTablesError::MISCONFIGURED);
+ }
+
+}
+
?>
diff -uNr RackTables-0.20.4-orig/wwwroot/inc/interface.php RackTables-0.20.4-dev/wwwroot/inc/interface.php
--- RackTables-0.20.4-orig/wwwroot/inc/interface.php 2013-04-14 21:27:19.000000000 +0100
+++ RackTables-0.20.4-dev/wwwroot/inc/interface.php 2013-04-16 15:03:03.241660771 +0100
@@ -12,6 +12,7 @@
require_once 'ajax-interface.php';
require_once 'slb-interface.php';
+require_once 'portlets.php';
// Interface function's special.
$nextorder['odd'] = 'even';
@@ -1084,238 +1085,24 @@
function renderObject ($object_id)
{
- global $nextorder, $virtual_obj_types;
+ global $nextorder, $virtual_obj_types, $portlethandler;
$info = spotEntity ('object', $object_id);
amplifyCell ($info);
// Main layout starts.
echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
// left column with uknown number of portlets
- echo "<tr><td class=pcleft>";
-
- // display summary portlet
- $summary = array();
- if (strlen ($info['name']))
- $summary['Common name'] = $info['name'];
- elseif (considerConfiguredConstraint ($info, 'NAMEWARN_LISTSRC'))
- $summary[] = array ('<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>');
- $summary['Object type'] = '<a href="' . makeHref (array (
- 'page' => 'depot',
- 'tab' => 'default',
- 'cfe' => '{$typeid_' . $info['objtype_id'] . '}'
- )) . '">' . decodeObjectType ($info['objtype_id'], 'o') . '</a>';
- if (strlen ($info['label']))
- $summary['Visible label'] = $info['label'];
- if (strlen ($info['asset_no']))
- $summary['Asset tag'] = $info['asset_no'];
- elseif (considerConfiguredConstraint ($info, 'ASSETWARN_LISTSRC'))
- $summary[] = array ('<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>');
- $parents = getEntityRelatives ('parents', 'object', $object_id);
- if (count ($parents))
- {
- $fmt_parents = array();
- foreach ($parents as $parent)
- $fmt_parents[] = "<a href='".makeHref(array('page'=>$parent['page'], $parent['id_name'] => $parent['entity_id']))."'>${parent['name']}</a>";
- $summary[count($parents) > 1 ? 'Containers' : 'Container'] = implode ('<br>', $fmt_parents);
- }
- $children = getEntityRelatives ('children', 'object', $object_id);
- if (count ($children))
- {
- $fmt_children = array();
- foreach ($children as $child)
- $fmt_children[] = "<a href='".makeHref(array('page'=>$child['page'], $child['id_name']=>$child['entity_id']))."'>${child['name']}</a>";
- $summary['Contains'] = implode ('<br>', $fmt_children);
- }
- if ($info['has_problems'] == 'yes')
- $summary[] = array ('<tr><td colspan=2 class=msg_error>Has problems</td></tr>');
- foreach (getAttrValues ($object_id) as $record)
- if
- (
- strlen ($record['value']) and
- permitted (NULL, NULL, NULL, array (array ('tag' => '$attr_' . $record['id'])))
- )
- $summary['{sticker}' . $record['name']] = formatAttributeValue ($record);
- $summary[] = array (getOutputOf ('printTagTRs',
- $info,
- makeHref
- (
- array
- (
- 'page'=>'depot',
- 'tab'=>'default',
- 'andor' => 'and',
- 'cfe' => '{$typeid_' . $info['objtype_id'] . '}',
- )
- )."&"
- ));
- renderEntitySummary ($info, 'summary', $summary);
-
- if (strlen ($info['comment']))
- {
- startPortlet ('Comment');
- echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
- finishPortlet ();
- }
-
- $logrecords = getLogRecordsForObject ($_REQUEST['object_id']);
- if (count ($logrecords))
- {
- startPortlet ('log records');
- echo "<table cellspacing=0 cellpadding=5 align=center class=widetable width='100%'>";
- $order = 'odd';
- foreach ($logrecords as $row)
- {
- echo "<tr class=row_${order} valign=top>";
- echo '<td class=tdleft>' . $row['date'] . '<br>' . $row['user'] . '</td>';
- echo '<td class="logentry">' . string_insert_hrefs (htmlspecialchars ($row['content'], ENT_NOQUOTES)) . '</td>';
- echo '</tr>';
- $order = $nextorder[$order];
- }
- echo '</table>';
- finishPortlet();
- }
-
- switchportInfoJS ($object_id); // load JS code to make portnames interactive
- renderFilesPortlet ('object', $object_id);
-
- if (count ($info['ports']))
- {
- startPortlet ('ports and links');
- $hl_port_id = 0;
- if (isset ($_REQUEST['hl_port_id']))
- {
- assertUIntArg ('hl_port_id');
- $hl_port_id = $_REQUEST['hl_port_id'];
- addAutoScrollScript ("port-$hl_port_id");
- }
- echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>";
- echo '<tr><th class=tdleft>Local name</th><th class=tdleft>Visible label</th>';
- echo '<th class=tdleft>Interface</th><th class=tdleft>L2 address</th>';
- echo '<th class=tdcenter colspan=2>Remote object and port</th>';
- echo '<th class=tdleft>Cable ID</th></tr>';
- foreach ($info['ports'] as $port)
- callHook ('renderObjectPortRow', $port, ($hl_port_id == $port['id']));
- if (permitted (NULL, 'ports', 'set_reserve_comment'))
- addJS ('js/inplace-edit.js');
- echo "</table><br>";
- finishPortlet();
- }
-
- if (count ($info['ipv4']) + count ($info['ipv6']))
- {
- startPortlet ('IP addresses');
- echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
- if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
- echo "<tr><th>OS interface</th><th>IP address</th><th>network</th><th>routed by</th><th>peers</th></tr>\n";
- else
- echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
-
- // group IP allocations by interface name instead of address family
- $allocs_by_iface = array();
- foreach (array ('ipv4', 'ipv6') as $ip_v)
- foreach ($info[$ip_v] as $ip_bin => $alloc)
- $allocs_by_iface[$alloc['osif']][$ip_bin] = $alloc;
-
- // sort allocs array by portnames
- foreach (sortPortList ($allocs_by_iface) as $iface_name => $alloclist)
- {
- $is_first_row = TRUE;
- foreach ($alloclist as $alloc)
- {
- $rendered_alloc = callHook ('getRenderedAlloc', $object_id, $alloc);
- echo "<tr class='${rendered_alloc['tr_class']}' valign=top>";
-
- // display iface name, same values are grouped into single cell
- if ($is_first_row)
- {
- $rowspan = count ($alloclist) > 1 ? 'rowspan="' . count ($alloclist) . '"' : '';
- echo "<td class=tdleft $rowspan>" . $iface_name . $rendered_alloc['td_name_suffix'] . "</td>";
- $is_first_row = FALSE;
- }
- echo $rendered_alloc['td_ip'];
- if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
- {
- echo $rendered_alloc['td_network'];
- echo $rendered_alloc['td_routed_by'];
- }
- echo $rendered_alloc['td_peers'];
-
- echo "</tr>\n";
- }
- }
- echo "</table><br>\n";
- finishPortlet();
- }
-
- $forwards = $info['nat4'];
- if (count($forwards['in']) or count($forwards['out']))
+ echo "<tr>";
+ foreach (array('left','right') as $side)
{
- startPortlet('NATv4');
-
- if (count($forwards['out']))
+ echo "<td class=pc$side>";
+ foreach ($portlethandler['object']['default'][$side] as $idx => $portlet)
{
-
- echo "<h3>locally performed NAT</h3>";
-
- echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
- echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
-
- foreach ($forwards['out'] as $pf)
- {
- $class = 'trerror';
- $osif = '';
- if (isset ($alloclist [$pf['localip']]))
- {
- $class = $alloclist [$pf['localip']]['addrinfo']['class'];
- $osif = $alloclist [$pf['localip']]['osif'] . ': ';
- }
- echo "<tr class='$class'>";
- echo "<td>${pf['proto']}</td><td class=tdleft>${osif}" . getRenderedIPPortPair ($pf['localip'], $pf['localport']) . "</td>";
- echo "<td class=tdleft>" . getRenderedIPPortPair ($pf['remoteip'], $pf['remoteport']) . "</td>";
- $address = getIPAddress (ip4_parse ($pf['remoteip']));
- echo "<td class='description'>";
- if (count ($address['allocs']))
- foreach($address['allocs'] as $bond)
- echo mkA ("${bond['object_name']}(${bond['name']})", 'object', $bond['object_id']) . ' ';
- elseif (strlen ($pf['remote_addr_name']))
- echo '(' . $pf['remote_addr_name'] . ')';
- echo "</td><td class='description'>${pf['description']}</td></tr>";
- }
- echo "</table><br><br>";
- }
- if (count($forwards['in']))
- {
- echo "<h3>arriving NAT connections</h3>";
- echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
- echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
- foreach ($forwards['in'] as $pf)
- {
- echo "<tr>";
- echo "<td>${pf['proto']}/" . getRenderedIPPortPair ($pf['localip'], $pf['localport']) . "</td>";
- echo '<td class="description">' . mkA ($pf['object_name'], 'object', $pf['object_id']);
- echo "</td><td>" . getRenderedIPPortPair ($pf['remoteip'], $pf['remoteport']) . "</td>";
- echo "<td class='description'>${pf['description']}</td></tr>";
- }
- echo "</table><br><br>";
+ call_user_func($portlet['callback'], $info );
}
- finishPortlet();
+ echo "</td>\n";
}
-
- renderSLBTriplets ($info);
- echo "</td>\n";
-
- // After left column we have (surprise!) right column with rackspace portlet only.
- echo "<td class=pcright>";
- if (!in_array($info['objtype_id'], $virtual_obj_types))
- {
- // rackspace portlet
- startPortlet ('rackspace allocation');
- foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
- renderRack ($rack_id, $object_id);
- echo '<br>';
- finishPortlet();
- }
- echo "</td></tr>";
+ echo "</tr>";
echo "</table>\n";
}
@@ -3863,24 +3650,27 @@
function renderRackPage ($rack_id)
{
- $rackData = spotEntity ('rack', $rack_id);
- amplifyCell ($rackData);
- echo "<table border=0 class=objectview cellspacing=0 cellpadding=0><tr>";
-
- // Left column with information.
- echo "<td class=pcleft>";
- renderRackInfoPortlet ($rackData);
- renderFilesPortlet ('rack', $rack_id);
- echo '</td>';
+ global $portlethandler;
+ $info = spotEntity ('rack', $rack_id);
+ amplifyCell ($info);
+ // Main layout starts.
+ echo "<table border=0 class=objectview cellspacing=0 cellpadding=0>";
+ echo "<tr><td colspan=2 align=center><h1>${info['dname']}</h1></td></tr>\n";
+ // left column with uknown number of portlets
+ echo "<tr>";
+ foreach (array('left','right') as $side)
+ {
+ echo "<td class=pc$side>";
+ foreach ($portlethandler['rack']['default'][$side] as $idx => $portlet)
+ {
+ call_user_func($portlet['callback'], $info );
+ }
+ echo "</td>\n";
+ }
- // Right column with rendered rack.
- echo '<td class=pcright>';
- startPortlet ('Rack diagram');
- renderRack ($rack_id);
- finishPortlet();
- echo '</td>';
+ echo "</tr>";
+ echo "</table>\n";
- echo '</tr></table>';
}
function renderDictionary ()
diff -uNr RackTables-0.20.4-orig/wwwroot/inc/navigation.php RackTables-0.20.4-dev/wwwroot/inc/navigation.php
--- RackTables-0.20.4-orig/wwwroot/inc/navigation.php 2013-04-14 21:27:19.000000000 +0100
+++ RackTables-0.20.4-dev/wwwroot/inc/navigation.php 2013-04-16 15:05:50.691661405 +0100
@@ -35,6 +35,8 @@
$svghandler = array();
$ajaxhandler = array();
+$portlethandler = array();
+
$indexlayout = array
(
array ('rackspace', 'depot', 'ipv4space', 'ipv6space'),
@@ -144,6 +146,9 @@
$ophandler['rack']['files']['addFile'] = 'addFileToEntity';
$ophandler['rack']['files']['linkFile'] = 'linkFileToEntity';
$ophandler['rack']['files']['unlinkFile'] = 'unlinkFile';
+$portlethandler['rack']['default']['left'][] = array( 'name' => 'Summary', 'callback' => 'renderRackInfoPortlet' );
+$portlethandler['rack']['default']['left'][] = array( 'name' => 'Files', 'callback' => 'renderRkPortletFiles' );
+$portlethandler['rack']['default']['right'][] = array( 'name' => 'Rack Diagram', 'callback' => 'renderRkPortletDiagram' );
$page['object']['bypass'] = 'object_id';
$page['object']['bypass_type'] = 'uint';
@@ -259,6 +264,15 @@
$ophandler['object']['munin']['del'] = 'tableHandler';
$ophandler['object']['ucs']['autoPopulateUCS'] = 'autoPopulateUCS';
$ophandler['object']['ucs']['cleanupUCS'] = 'cleanupUCS';
+$portlethandler['object']['default']['left'][] = array( 'name' => 'Summary', 'callback' => 'renderObPortletSummary' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'Comment', 'callback' => 'renderObPortletComment' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'Log', 'callback' => 'renderObPortletLog' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'Files', 'callback' => 'renderObPortletFiles' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'Ports', 'callback' => 'renderObPortletPorts' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'IPAddresses', 'callback' => 'renderObPortletIPAddresses' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'NATv4', 'callback' => 'renderObPortletNATv4' );
+$portlethandler['object']['default']['left'][] = array( 'name' => 'SLBTriplets', 'callback' => 'renderObPortletSLBTriplets' );
+$portlethandler['object']['default']['right'][] = array( 'name' => 'Rackspace', 'callback' => 'renderObPortletRackspace' );
$delayauth['object-8021qports-save8021QConfig'] = TRUE;
$delayauth['object-8021qorder-add'] = TRUE;
$delayauth['object-8021qorder-del'] = TRUE;
diff -uNr RackTables-0.20.4-orig/wwwroot/inc/portlets.php RackTables-0.20.4-dev/wwwroot/inc/portlets.php
--- RackTables-0.20.4-orig/wwwroot/inc/portlets.php 1970-01-01 01:00:00.000000000 +0100
+++ RackTables-0.20.4-dev/wwwroot/inc/portlets.php 2013-04-16 15:05:00.991661666 +0100
@@ -0,0 +1,283 @@
+<?php
+
+function renderObPortletSummary( $info )
+{
+ $object_id = $info['id'];
+
+ // display summary portlet
+ $summary = array();
+ if (strlen ($info['name']))
+ $summary['Common name'] = $info['name'];
+ elseif (considerConfiguredConstraint ($info, 'NAMEWARN_LISTSRC'))
+ $summary[] = array ('<tr><td colspan=2 class=msg_error>Common name is missing.</td></tr>');
+ $summary['Object type'] = '<a href="' . makeHref (array (
+ 'page' => 'depot',
+ 'tab' => 'default',
+ 'cfe' => '{$typeid_' . $info['objtype_id'] . '}'
+ )) . '">' . decodeObjectType ($info['objtype_id'], 'o') . '</a>';
+ if (strlen ($info['label']))
+ $summary['Visible label'] = $info['label'];
+ if (strlen ($info['asset_no']))
+ $summary['Asset tag'] = $info['asset_no'];
+ elseif (considerConfiguredConstraint ($info, 'ASSETWARN_LISTSRC'))
+ $summary[] = array ('<tr><td colspan=2 class=msg_error>Asset tag is missing.</td></tr>');
+ $parents = getEntityRelatives ('parents', 'object', $object_id);
+ if (count ($parents))
+ {
+ $fmt_parents = array();
+ foreach ($parents as $parent)
+ $fmt_parents[] = "<a href='".makeHref(array('page'=>$parent['page'], $parent['id_name'] => $parent['entity_id']))."'>${parent['name']}</a>";
+ $summary[count($parents) > 1 ? 'Containers' : 'Container'] = implode ('<br>', $fmt_parents);
+ }
+ $children = getEntityRelatives ('children', 'object', $object_id);
+ if (count ($children))
+ {
+ $fmt_children = array();
+ foreach ($children as $child)
+ $fmt_children[] = "<a href='".makeHref(array('page'=>$child['page'], $child['id_name']=>$child['entity_id']))."'>${child['name']}</a>";
+ $summary['Contains'] = implode ('<br>', $fmt_children);
+ }
+ if ($info['has_problems'] == 'yes')
+ $summary[] = array ('<tr><td colspan=2 class=msg_error>Has problems</td></tr>');
+ foreach (getAttrValues ($object_id) as $record)
+ if
+ (
+ strlen ($record['value']) and
+ permitted (NULL, NULL, NULL, array (array ('tag' => '$attr_' . $record['id'])))
+ )
+ $summary['{sticker}' . $record['name']] = formatAttributeValue ($record);
+ $summary[] = array (getOutputOf ('printTagTRs',
+ $info,
+ makeHref
+ (
+ array
+ (
+ 'page'=>'depot',
+ 'tab'=>'default',
+ 'andor' => 'and',
+ 'cfe' => '{$typeid_' . $info['objtype_id'] . '}',
+ )
+ )."&"
+ ));
+ renderEntitySummary ($info, 'summary', $summary);
+}
+
+function renderObPortletComments( $info )
+{
+ $object_id = $info['id'];
+
+ if (strlen ($info['comment']))
+ {
+ startPortlet ('Comment');
+ echo '<div class=commentblock>' . string_insert_hrefs ($info['comment']) . '</div>';
+ finishPortlet ();
+ }
+}
+
+function renderObPortletLog( $info )
+{
+ $object_id = $info['id'];
+
+ $logrecords = getLogRecordsForObject ($object_id);
+ if (count ($logrecords))
+ {
+ startPortlet ('log records');
+ echo "<table cellspacing=0 cellpadding=5 align=center class=widetable width='100%'>";
+ $order = 'odd';
+ foreach ($logrecords as $row)
+ {
+ echo "<tr class=row_${order} valign=top>";
+ echo '<td class=tdleft>' . $row['date'] . '<br>' . $row['user'] . '</td>';
+ echo '<td class="logentry">' . string_insert_hrefs (htmlspecialchars ($row['content'], ENT_NOQUOTES)) . '</td>';
+ echo '</tr>';
+ $order = $nextorder[$order];
+ }
+ echo '</table>';
+ finishPortlet();
+ }
+}
+
+
+function renderObPortletFiles( $info )
+{
+ $object_id = $info['id'];
+
+ renderFilesPortlet ('object', $object_id);
+}
+
+function renderObPortletPorts( $info )
+{
+ $object_id = $info['id'];
+
+ switchportInfoJS ($object_id); // load JS code to make portnames interactive
+ if (count ($info['ports']))
+ {
+ startPortlet ('ports and links');
+ $hl_port_id = 0;
+ if (isset ($_REQUEST['hl_port_id']))
+ {
+ assertUIntArg ('hl_port_id');
+ $hl_port_id = $_REQUEST['hl_port_id'];
+ addAutoScrollScript ("port-$hl_port_id");
+ }
+ echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>";
+ echo '<tr><th class=tdleft>Local name</th><th class=tdleft>Visible label</th>';
+ echo '<th class=tdleft>Interface</th><th class=tdleft>L2 address</th>';
+ echo '<th class=tdcenter colspan=2>Remote object and port</th>';
+ echo '<th class=tdleft>Cable ID</th></tr>';
+ foreach ($info['ports'] as $port)
+ callHook ('renderObjectPortRow', $port, ($hl_port_id == $port['id']));
+ if (permitted (NULL, 'ports', 'set_reserve_comment'))
+ addJS ('js/inplace-edit.js');
+ echo "</table><br>";
+ finishPortlet();
+ }
+}
+
+function renderObPortletIpAddresses( $info )
+{
+ $object_id = $info['id'];
+
+ if (count ($info['ipv4']) + count ($info['ipv6']))
+ {
+ startPortlet ('IP addresses');
+ echo "<table cellspacing=0 cellpadding='5' align='center' class='widetable'>\n";
+ if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
+ echo "<tr><th>OS interface</th><th>IP address</th><th>network</th><th>routed by</th><th>peers</th></tr>\n";
+ else
+ echo "<tr><th>OS interface</th><th>IP address</th><th>peers</th></tr>\n";
+
+ // group IP allocations by interface name instead of address family
+ $allocs_by_iface = array();
+ foreach (array ('ipv4', 'ipv6') as $ip_v)
+ foreach ($info[$ip_v] as $ip_bin => $alloc)
+ $allocs_by_iface[$alloc['osif']][$ip_bin] = $alloc;
+
+ // sort allocs array by portnames
+ foreach (sortPortList ($allocs_by_iface) as $iface_name => $alloclist)
+ {
+ $is_first_row = TRUE;
+ foreach ($alloclist as $alloc)
+ {
+ $rendered_alloc = callHook ('getRenderedAlloc', $object_id, $alloc);
+ echo "<tr class='${rendered_alloc['tr_class']}' valign=top>";
+
+ // display iface name, same values are grouped into single cell
+ if ($is_first_row)
+ {
+ $rowspan = count ($alloclist) > 1 ? 'rowspan="' . count ($alloclist) . '"' : '';
+ echo "<td class=tdleft $rowspan>" . $iface_name . $rendered_alloc['td_name_suffix'] . "</td>";
+ $is_first_row = FALSE;
+ }
+ echo $rendered_alloc['td_ip'];
+ if (getConfigVar ('EXT_IPV4_VIEW') == 'yes')
+ {
+ echo $rendered_alloc['td_network'];
+ echo $rendered_alloc['td_routed_by'];
+ }
+ echo $rendered_alloc['td_peers'];
+
+ echo "</tr>\n";
+ }
+ }
+ echo "</table><br>\n";
+ finishPortlet();
+ }
+}
+
+function renderObPortletNATv4( $info )
+{
+ $object_id = $info['id'];
+
+ $forwards = $info['nat4'];
+ if (count($forwards['in']) or count($forwards['out']))
+ {
+ startPortlet('NATv4');
+
+ if (count($forwards['out']))
+ {
+
+ echo "<h3>locally performed NAT</h3>";
+
+ echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
+ echo "<tr><th>Proto</th><th>Match endpoint</th><th>Translate to</th><th>Target object</th><th>Rule comment</th></tr>\n";
+
+ foreach ($forwards['out'] as $pf)
+ {
+ $class = 'trerror';
+ $osif = '';
+ if (isset ($alloclist [$pf['localip']]))
+ {
+ $class = $alloclist [$pf['localip']]['addrinfo']['class'];
+ $osif = $alloclist [$pf['localip']]['osif'] . ': ';
+ }
+ echo "<tr class='$class'>";
+ echo "<td>${pf['proto']}</td><td class=tdleft>${osif}" . getRenderedIPPortPair ($pf['localip'], $pf['localport']) . "</td>";
+ echo "<td class=tdleft>" . getRenderedIPPortPair ($pf['remoteip'], $pf['remoteport']) . "</td>";
+ $address = getIPAddress (ip4_parse ($pf['remoteip']));
+ echo "<td class='description'>";
+ if (count ($address['allocs']))
+ foreach($address['allocs'] as $bond)
+ echo mkA ("${bond['object_name']}(${bond['name']})", 'object', $bond['object_id']) . ' ';
+ elseif (strlen ($pf['remote_addr_name']))
+ echo '(' . $pf['remote_addr_name'] . ')';
+ echo "</td><td class='description'>${pf['description']}</td></tr>";
+ }
+ echo "</table><br><br>";
+ }
+ if (count($forwards['in']))
+ {
+ echo "<h3>arriving NAT connections</h3>";
+ echo "<table class='widetable' cellpadding=5 cellspacing=0 border=0 align='center'>\n";
+ echo "<tr><th>Matched endpoint</th><th>Source object</th><th>Translated to</th><th>Rule comment</th></tr>\n";
+ foreach ($forwards['in'] as $pf)
+ {
+ echo "<tr>";
+ echo "<td>${pf['proto']}/" . getRenderedIPPortPair ($pf['localip'], $pf['localport']) . "</td>";
+ echo '<td class="description">' . mkA ($pf['object_name'], 'object', $pf['object_id']);
+ echo "</td><td>" . getRenderedIPPortPair ($pf['remoteip'], $pf['remoteport']) . "</td>";
+ echo "<td class='description'>${pf['description']}</td></tr>";
+ }
+ echo "</table><br><br>";
+ }
+ finishPortlet();
+ }
+}
+
+function renderObPortletSLBTriplets( $info )
+{
+ $object_id = $info['id'];
+
+ renderSLBTriplets ($info);
+}
+
+function renderObPortletRackspace( $info )
+{
+ $object_id = $info['id'];
+
+ if (!in_array($info['objtype_id'], $virtual_obj_types))
+ {
+ // rackspace portlet
+ startPortlet ('rackspace allocation');
+ foreach (getResidentRacksData ($object_id, FALSE) as $rack_id)
+ renderRack ($rack_id, $object_id);
+ echo '<br>';
+ finishPortlet();
+ }
+}
+
+function renderRkPortletFiles ( $info )
+{
+ $rack_id = $info['id'];
+
+ renderFilesPortlet ('rack', $rack_id);
+}
+
+
+function renderRkPortletDiagram ( $info )
+{
+ $rack_id = $info['id'];
+ startPortlet ('Rack diagram');
+ renderRack ($rack_id);
+ finishPortlet();
+}
| ||||
|
Have attached a new version of the patch against version 0.20.3 Slight increase in the demo plugin with regards to adding a placeholder for reports |
|
| Have attached new version of patch for Racktables 0.20.4, extended functionality to renderRackPage for use with updated wattage_consumption plugin | |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2012-12-07 13:57 | MWilkinson | New Issue | |
| 2012-12-07 13:57 | MWilkinson | File Added: racktables-0.20.1.patch | |
| 2012-12-12 11:23 | andriyanov | Assigned To | => andriyanov |
| 2012-12-12 11:23 | andriyanov | Status | new => assigned |
| 2012-12-24 11:27 | MWilkinson | File Added: racktables-0-20-3.patch | |
| 2012-12-24 11:35 | MWilkinson | Note Added: 0001039 | |
| 2013-04-16 16:22 | MWilkinson | File Added: portlet-0.20.4.patch | |
| 2013-04-16 16:24 | MWilkinson | Note Added: 0001325 |