Components are essentially just a directory on your Fusion server with some specific PHP files included inside. Whenever you upload a component zip file into the component management page, all Fusion does behind the scenes is unzip it into a specific directory (/usr/local/nagiosfusion/html/includes/components/
). Because of the naming convention of the files included, the code is magically (it isn't magic) included everytime the Nagios Fusion codebase is instantiated.
In order to make sure this happens properly, we have to adhere to a few standards. We've outlined those standards in this document. All of the functions that we use in this document should be outlined in the accompanying function reference - the same goes for the callbacks and poll callbacks.
Before you dig in and work with the examples included here, make sure you've set your appropriate PHP warning/error settings for development. We generally like to make sure that display_errors
is set to On
, and error_reporting
is set to E_ALL & ~E_NOTICE
in our /etc/php.ini
file. Make sure you restart your apache server after setting these values (service httpd restart
or systemctl restart httpd
).
This document assumes you're working on a CentOS or Red Hat Enterprise Linux server (version 6 or 7) with a stock new install of Nagios Fusion 4. If you've changed your file locations, you'll have to make those adjustments on your own.
We're going to start off with our very own component. In order to save time, we're going to perform the development directly on the Fusion server. Don't worry, we can always export our component once it's been completed to share with the world.
A good starting point is usually determining what it is we want to do. You're in luck since we've already decided what we're doing. We'll make a Fusion component that includes a bit of text on each of the child pages.
So to start, we'll first create a directory and make some files:
mkdir -p /usr/local/nagiosfusion/html/includes/components/bitoftext/ cd /usr/local/nagiosfusion/html/includes/components/bitoftext/ touch bitoftext.inc.php
You see that file we touch
ed? Notice that the file name is the same name as the folder we created, with .inc.php
appended. This is important, because if that file didn't exist, our component would never be included in the Nagios Fusion codebase upon instantiation. In all cases, there must be at least a file with the same base name of the folder it is contained in appended by .inc.php
in order for that component to be included (.e.g: [component]/[component].inc.php
). You can have other files in there as well, but those would have to be explicitly included from your inc.php file.
Now fire up your favorite editor to edit our file (vi bitoftext.php
). Let's make the file look like the following, and then we'll explain what it all means in the next sections:
<?php register_bitoftext(); function register_bitoftext() { $component_args = array( COMPONENT_NAME => 'bitoftext', COMPONENT_TITLE => 'Bit of Text', COMPONENT_VERSION => '1.0.0', COMPONENT_DATE => '06/01/2017', COMPONENT_AUTHOR => 'Nagios Enterprises and Friends', COMPONENT_DESCRIPTION => 'Place a bit of text on each child page', COMPONENT_REQUIRES_VERSION => 4000, COMPONENT_FUNCTION => 'bitoftext_successful_registration', ); register_component($component_args); }
This is a pretty basic PHP file. We start with the opening tag <?php
and then jump right into calling a function (register_bitoftext();
) that we define on the next line.
This function is what's responsible for passing our arguments into Fusion to attempt and register the component. We have a long list of data that we can supply to Fusion.
Index | Explanation |
---|---|
COMPONENT_NAME | REQUIRED - The short, unique name of the component. |
COMPONENT_TITLE | REQUIRED - The full title of the component. This is displayed with the component information. |
COMPONENT_VERSION | The version of the component. This is displayed with the component information. |
COMPONENT_AUTHOR | The author of the component. This is displayed with the component information. |
COMPONENT_DESCRIPTION | REQUIRED - A brief description of the component. This is displayed with the component information. |
COMPONENT_DATE | The date that this component was last updated. This is displayed with the component information. |
COMPONENT_COPYRIGHT | The copyright notice of the component. This is displayed with the component information. |
COMPONENT_LICENSE | The license applied to this component. This is displayed with the component information. |
COMPONENT_HOMEPAGE | The webpage about the author, or where to find more details about the component. This is displayed with the component information. |
COMPONENT_CONFIG_FUNCTION | The configure function. This is a PHP function callback string. If this is specified, then there will be an icon under the manage components page in the 'Settings' column. The function specified here must accept a specific argument, and alter the output/processing depending on the value supplied by Fusion. |
COMPONENT_REQUIRES_VERSION |
The minimum product version that this component can work with. The version of your Fusion can be found with the output of the function get_product_release() .
|
COMPONENT_FUNCTION | This is a PHP function callback string. If the component register successfully, then this is the function that is executed. Preferrably, you'll want to put all of the callback registrations inside of the function you specify here. |
COMPONENT_ERROR_MESSAGE | The error message to display if your component can't be registered. |
Our function register_bitoftext()
builds our component argument array - which specifies our COMPONENT_FUNCTION
as bitoftext_successful_registration
- and then passes the array into the register_component()
function.
So what does the register_component()
function do, you ask? This let's Fusion perform some magic (it isn't magic) behind the scenes to make sure everything passed in was fine. If you've set the COMPONENT_FUNCTION
array index - then there won't be any issues - the component will simply print out an error message in the list and never finish registration.
Although this doesn't have anything to do with the component we're building: we're going to talk a bit about the COMPONENT_CONFIG_FUNCTION
before we continue on. In the table above, we said this argument array index corresponds to a PHP function callback string.
The function you define only needs to accept a single argument, we'll call it $mode
. Fusion sends a different value depending on where in the component configure process the user is.
Let's say that a user clicks on your 'Settings' icon in the manage components page. In that case, Fusion will call your COMPONENT_CONFIG_FUNCTION
defined function with $mode
set as COMPONENT_CONFIG_MODE_GET
. In this case, your function needs to return some output that will contain form elements.
Then once the user submits the form, Fusion will call that same function with $mode
set as COMPONENT_CONFIG_MODE_SET
. It will include the form elements you returned as text in the get mode. This is too easy. So let's make a quick fake function to show an example:
function customlogin_config_func($mode = null) { switch ($mode) { case COMPONENT_CONFIG_MODE_GET: return '<label>Some text: <input type="text" name="sometext" /></label>'; case COMPONENT_CONFIG_MODE_SET: $sometext = grab_request_var("sometext"); /* do some processing with $sometext */ } }
Note the use of the function grab_request_var
. This function is explained in greater detail in the Functions Reference page.
Now back to our regularly scheduled component...
One of the things that made extending Nagios XI so easy has been brought into the new Fusion: callbacks! A callback is essentially a defined moment in time during the instantiation and execution of the application that you can hook into and add your own processing.
We hook into callbacks by registering functions to be executed during the callback we specify. A common callback that's registered is the CALLBACK_MENU_INITIALIZED
. This is the callback executed when the menu items are being initialized, so that we can extend the menu object with our own links.
Let's take a look at the Network Operation Center component's use of registering a callback during menu initialization:
register_callback(CALLBACK_MENU_INITIALIZED, 'register_noc_menu'); /* ... */ function register_noc_menu($cb, &$menu) { $menu->add_link(menu_link(_('Network Operations Center'), 'includes/components/noc/noc.php'), 'home-server-status'); }
We'll get more into more detail about how these functions work and the arguments they accept on the Functions Reference page. But for now we're going to piggy back off of this example to finally build our bitoftext_successful_registration
function.
Since this is going to be the function that Fusion executes once registration is successful, we'll keep all of our callback registrations inside of that function. Take a look:
function bitoftext_successful_registration() { register_callback(CALLBACK_HEADER_END, 'bitoftext_header'); }
Again a nice and simple function. Don't worry, a full list of callbacks is available on the Callbacks Reference page. All you need to know right now is that we'll be injecting some text onto each page after the header has been printed on child pages.
What is a child page? It's true, we're psychic. A child page is the page built in the inner frame of the Fusion interface. The main navigation header, side navigation, and footer are all part of a parent page. When you click a link anywhere in Fusion, the inner frame is the page that is updated. And Fusion is so smart that it can tell which pages are child pages and which are parent pages.
Now let's define our bitoftext_header
function. All callbacks registered need to accept two arguments: the first argument will be the callback type ($cbtype
) followed by the arguments generated during the callback execution ($cbargs
). Some of the callbacks pass $cbargs
and expect you to alter it in some way - which means you need to accept this argument as a reference (&$cbargs
) such as in the case of the register_noc_menu
function listed previously.
In our case, we don't need to pass the arguments as reference:
function bitoftext_header($cbtype, $cbargs) { if ($cbtype == CALLBACK_HEADER_END) { $childpage = grab_array_var($cbargs, 'child', false); if ($childpage) { echo "<h4>This is a Bit of Text</h4>"; } } }
This should be fairly self explanatory. We use the Fusion function grab_array_var
to see if $cbargs['child']
is set (if it isn't we give it a default value of false
). We then check if $childpage
is true and if so we echo some code.
If you've been following along so far, whenever you view (almost) any page in Fusion, there should be an obnoxious bit of text up at the top of the page! It's probably (it isn't) magic!
That's pretty much it for our component. There is a specific topic we should touch on before we move on: poll callbacks.
Fusion is all about connecting all of your remote servers from one interface. It handles this by periodically polling those remote servers and storing the data in a database for quick retrieval when you access that interface.
This is all handled behind the scenes - magically (it isn't magic) - with the use of poll callbacks. Poll callbacks work a bit like regular callbacks, except for a few major differences:
We'll definitely cover this in more detail on the Poll Callbacks Reference page.
What follows is the entirety of the component we built together:
<?php register_bitoftext(); function register_bitoftext() { $component_args = array( COMPONENT_NAME => 'bitoftext', COMPONENT_TITLE => 'Bit of Text', COMPONENT_VERSION => '1.0.0', COMPONENT_DATE => '06/01/2017', COMPONENT_AUTHOR => 'Nagios Enterprises and Friends', COMPONENT_DESCRIPTION => 'Place a bit of text on each child page', COMPONENT_REQUIRES_VERSION => 4000, COMPONENT_FUNCTION => 'bitoftext_successful_registration', ); register_component($component_args); } function bitoftext_successful_registration() { register_callback(CALLBACK_HEADER_END, 'bitoftext_header'); } function bitoftext_header($cbtype, $cbargs) { if ($cbtype == CALLBACK_HEADER_END) { $childpage = grab_array_var($cbargs, 'child', false); if ($childpage) { echo "<h4>This is a Bit of Text</h4>"; } } }
If that exists inside of the file /usr/local/nagiosfusion/html/includes/components/bitoftext/bitoftext.inc.php
you should now be able to navigate to your Manage Components page, and click on the 'Download' icon under the 'Actions' column. This will download a zip on your local computer that you can upload to the Nagios Exchange to share with the world!