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 |