[racktables-users] Re: Addon Functionality and Dynamic function calls

  • From: "Lacayo, Luis F" <lflacayo@xxxxxxxxxxxxx>
  • To: <racktables-users@xxxxxxxxxxxxx>
  • Date: Fri, 5 Mar 2010 11:10:38 -0600

Kind of makes sense.. If it makes a better product,  I don't think that
anyone will object. :-) 

Thanks,

Luis

-----Original Message-----
From: racktables-users-bounce@xxxxxxxxxxxxx
[mailto:racktables-users-bounce@xxxxxxxxxxxxx] On Behalf Of Tutton,
James
Sent: Friday, March 05, 2010 10:39 AM
To: racktables-users@xxxxxxxxxxxxx
Subject: [racktables-users] Addon Functionality and Dynamic function
calls

Hi All,

I am currently working to extend the rack tables functionality by adding
the ability to use plugins/addons.  This is currently only a proof of
concept but would like to share it with the community and ask the
changes required in the base code are considered for admission into the
tree. And also get feedback on the concept as whole.

Must say this is currently a proof of concept and should not be consider
security validated of bug free.

To achieve this we have created a new folder called addons.  
We have then added the following to inc/local.php 

###### APPEND TO inc/local.php

foreach (glob("/FULL_PATH_TO_RACK_TABLES/addons/*.php") as $filename) {
   include($filename);
}

###### END APPEND TO inc/local.php

To allow the use of classes within our addons we need to change the way
racktables calls functions by reference.

The main benefit here is we can build our addons as tight classes.
Without this change we have to ensure all our addons have unique
function names and this proved to be very problematic very quickly for
our needs.


###### Amend index.php aprrox line 81

                showMessageOrError();
                // Added call_user_func Method to allow Class Based
Invocations
           call_user_func($tabhandler[$pageno][$tabno],
$_REQUEST[$page[$pageno]['bypass']]);
                //$tabhandler[$pageno][$tabno]
($_REQUEST[$page[$pageno]['bypass']]);
        }
        else
        {
                showMessageOrError();
                // Added call_user_func Method to allow Class Based
Invocations 
                call_user_func($tabhandler[$pageno][$tabno]);
                //$tabhandler[$pageno][$tabno] ();


###### End Amend index.php

Addons will also work with callbacks but working on KISS principle for
this example.  

For reference though if anyone wants to go further using callbacks as
well then make similar changes in process.php line 32




Then we simply add our addons into the "addons" folder and they are
loaded into memory for later use.

An Example Addon is Below. This addon will list all your objects based
on Racktables type and then group them by hardware type.

New Tab is added to Reports -> Object Types

########################################################################
#######
<?php

// RMS Reports Object Types
// by James Tutton
// Version 0.1

// Installation:
// 1)  Add include to rms_addons folder;
// 2)  Make sure rms_addons folder is included in inc/local.php
//      foreach (glob("/home/1user/public_html/rms_addons/*.php") as
$filename) {
//      include($filename);
//      }


// Which Tab Section should we render on what should we Name the Tab
$tab['reports']['rmsobjecttypes'] = 'Object Types';

// What Function should render the tab content
// Add The New tab to appropriate page and set entry function options as
array('CLASSNAME', 'FUNCTIONNAME');  
// IMPORTANT FUNCTIONAME must be a static function as we have not
initialised the class as would be waste of memory to have class loaded
all the time 
$tabhandler['reports']['rmsobjecttypes'] = array('RMSObjectTypeReport',
'getContent');
// Which Should we Call to handle post back
// View only Report so post not required
// $ophandler['reports'][ 'rmsobjecttypes']['addObjectlog'] =
'addObjectlog';
class RMSObjectTypeReport 
{
        static public function getContent () {
                $obj = new RMSObjectTypeReport();
                $obj->rmsGetObjectsTypes();
        }

        function rmsGetObjectsTypes ()
        {
                echo "<link rel=stylesheet type='text/css'
href=/rms_addons/style.css />";
                echo "<div id=\"rms_addonWrapper\">";
                echo "<br/>";
                $output = "";
                $objecttypes= "SELECT *
                                                FROM Dictionary 
                                                WHERE chapter_id = 1";
                $obtyperesult = useSelectBlade ($objecttypes,
__FUNCTION__);
                $obtyperesult = $obtyperesult->fetchall();
                foreach ($obtyperesult as $objtyperow)
                {
                        $objtype_id = $objtyperow['dict_key'];
                        
                        $objectdetials =
$this->rmsGetObjectsByType($objtype_id);
                        if ($objectdetials <> "") {
                        $output .=  "<div class=\"rmsobjecttypes\">
".$objtyperow['dict_value']."</div>\n";
                        $output .=  $objectdetials;
                        
                        }
                        
                        
                }
                echo $output;
                echo "</div>";
        }

        function rmsGetObjectsByType ($objtype_id) {
                $output = "";
                $objquery ="SELECT RackObject.* , Dictionary.dict_value
as HWType
                                        FROM RackObject 
                                        LEFT OUTER JOIN AttributeValue 
                                        ON AttributeValue.object_id =
RackObject.id 
                                        AND attr_id = 2 
                                        LEFT OUTER JOIN Dictionary 
                                        ON AttributeValue.uint_value =
Dictionary.dict_key      
                                        WHERE`objtype_id` =$objtype_id
                                        ORDER  BY
Dictionary.dict_value";
                                        
                                        

                $objresult = useSelectBlade ($objquery, __FUNCTION__);
                $objresult = $objresult->fetchall();
                if (count($objresult) > 0 )
                {
                $output .=  "<TABLE id=\"rmsobjects\">\n";
                $output .=  "<TR><TH class=\"ObjectHWType\">HW
Type</TH><TH class=\"ObjectName\">Name</TH><TH
class=\"ObjectLabel\">Device Label</TH></TR>\n";
                $class = "even";
                foreach ($objresult as $object)
                {
                $class = ($class=='even') ? 'odd' : 'even';
                        $output .=  "<TR class=\"$class\">";
                        $output .=  "<TD
class=\"ObjectHWType\">".execGMarker(parseWikiLink($object['HWType'],'o'
))."</TD>";
                        $output .=  "<TD class=\"ObjectName\"><a
href=\"index.php?page=object&object_id=".$object['id'].
"\">".$object['name']."</a></TD>";
                        $output .=  "<TD
class=\"ObjectLabel\">".$object['label']."</TD>";
                        
                        $output .=  "</TR>\n";
                }
                $output .=  "</TABLE>\n";
                }
                return $output;
        }

}


?>
########################################################################
#######.


Other addons I am working on include a RIPE update addon for using with
the IP4 addresses. A helpdesk lookup based on the device name and Sql
connection to third party system. There is a style sheet that goes with
all this to neaten things up but don't want to provide to much if people
not interested.


James Tutton



Other related posts: