Friday, October 2, 2009

More on Widgets

Even though there hasn't been any posts here lately the work is very much in progress.

There has been quite a lot of people testing Ninja/Merlin all during the last couple of months and we really appreciate all feedback that we get and try to respond as quickly as we possibly can. Keep it up!

There has been changes in some areas of Ninja during this time but the previous posts still holds.

When it comes to widgets, they now have some additional functionality which makes them even more useful.

Edit
All included widgets now supports editing if enabled (by setting class 'editable') in the wrapping div. By using JavaScript it is now possible to get background (Ajax) refresh with just a few lines of code.

Example:
In the network healt widget (netw_health) a javascript resource is added in the php file
$this->js = array('/js/netw_health');

This file only contains the following code:

$(document).ready(function() {
var netw_health = new widget('netw_health', 'widget-content');
});

As you can see, it's only one line of code wrapped in the document ready event listner. It creates a new instance of the widget JavaScript class with 2 arguments:
  • the widget identifier (widget name) and
  • what CSS class in the widget that should be updated by the Ajax call.
By adding this code, a JQuery UI slider will be created to be used when editing update frequency. The element with the CSS class 'widget-content' in the example above will be updated with the interval set by the slider (default 60 sec).

It's just that simple. ;-)

More features
There are also other nifty features that has been added lately:
  • Possibility to pause page refresh.
    Sometimes you don't want the page to keep refreshing. By checking the "Pause refresh" checkbox under settings you may now pause the page refresh.
  • Hide Page Header.
    By checking this checkbox under settings, the page header (with the status totals widget and links) will be hidden. This is a feature that the old CGI:s had and Ninja should of course have it too.
  • Paging.
    Host- and service status listings might get rather long and to make the pages load faster we now use paging. The default number of items shown is set to 100 by default but an arbitrary number of items can be used on each page. The dafault value has to be changed in config/pagination.php (the 'items_per_page' key) today but the plan is to move this to the GUI in the future.
  • Improved search functionality.
    This was demonstrated at Nordic Meet On Nagios 2009 but I haven't made any posts on this yet and a more in-depth post will cover this later. The functionality of the the search result will also be enhanced even further.
  • Floating table headers.
    Sometimes when viewing large data sets in tables, you loose sight of the table haders and to make it easier to see what the values in the table stand for. To amend this, we added floating table headers to make the column labels to float with the page as you scroll down.
There has been suggestions that we should set up a wiki to handle documentation for Ninja/Merlin and this will be launched shortly. Keep an eye on www.op5.org for updates!

Once again, thanks to everybody for contributions, suggestions, patches etc - we need your input!

Wednesday, June 10, 2009

Report from Nordic Meet On Nagios 2009

Last week I made a presentation of Ninja at the Nordic Meet On Nagios 2009 hosted by op5 in Stockholm, Sweden. The presentation received quite some attention and regarding from the number of questions afterwards, people were very interested and eager to hear about future plans and features.

The agenda for my presentation was:
  • Background
  • Dependencies
  • Short on MVC
  • The Ninja API
  • Possible modifications
  • Add-on integration
  • Differences to todays CGI's
  • Live DEMO
  • Thoughts on the future (Low Hanging Fruit and such)
The presentation lasted approximately 1 hr including questions etc and was broadcasted through Bambuser. It is still available from http://nordicmeetonnagios.op5.org/ and will soon be available from youtube as well.

If you don't have the time to watch the entire presentation my slides are also available as a PDF: The Ninja project - an alternative open source Nagios GUI goes live

After the presentation, Ethan Galstad, the Founder of Nagios who was was invited as a key speaker, raised the question if we (op5) would be interested in making Ninja the default Nagios GUI. Since one of our main goals was to create the leading Open Source web frontend for Nagios, the answer was rather given.

Ethan and the community has created a fantastic and impressive piece of software that deserves a modern web GUI. It deserves attention and ideas from the large group of skilled web developers and designers out there and we strongly believe that Ninja could be the way to achieve this. Both me personally and everybody at op5 will be happy to make this contribution to the Nagios project.

Thursday, May 21, 2009

Screenshots and progress update

Thought I'd just share a few words on how things a moving forward with the Ninja project.

The plan is to release an alpha during the Nordic Meet On Nagios 2009 conference in Stockholm, Sweden June 3-4. We are working quite hectic these days to make the plan hold and we are confident that we will succeed albeit we're on a very tight schedule.

Currently we are working with converting some of the last big CGI's and at the same time, our interface designer is polishing the default theme. If you are interested to see some screenshots, I suggest you take a look at http://www.op5.org/community/projects/ninja where we keep some screenshots of our prototypes.

As always, we would greatly appreciate all comments and feedback.

What would You like to see in the Ninja GUI?
Give me a hint - or download the code and do it yourself :)

Monday, April 20, 2009

Authentication

As default, the Nagios CGI's relies on basic authentication. Even though this is usually sufficient from a security perspective, it has some drawbacks. One is that it isn't possible to logout unless you use some third party (Firefox) plugins/addons or simply close all browser instances. Maintaining users in htpasswd files isn't that posh either - keeping user authentication data (login, password etc) in a database, on the other hand, is. Switching to LDAP or the like isn't a walk in the park either. Other means of authentication is what we need.

Currently we use the Kohana Auth Module which is a driver based authentication module using sessions. This will provide a reasonably good authentication with salted hash passwords stored in the database. As it is driver based, we plan to extend it with LDAP support in the future. If we are lucky enough the friendly guys over at Kohana will already have done this for us when we get this far on our journey ;-)

The auth Module has support for authorization (roles) but since Nagios has it's own way of configuring who will see and do what, we will probably stick with that to make things transparent to users that are already familiar with the Nagios concept.

The current authentication implementation is possibe to configure in the config/auth.php file. It is today possible to change the default session lifetime, hash_method (defaults to sha1), salt pattern, driver, minimum username characters and maximum failed login attempts (default is false). Even though the latter directive doesn't lock down an IP or whatever at the moment, it seemed like a good idea to include support for it from start :)

As mentioned before, this is work in progress and any input is highly appreciated.

Tuesday, April 14, 2009

Widgets

As stated in previous posts it is possible to extend the default Ninja functionality by creating widgets. In fact, we have included some widgets as default. They are primarily used in the Tactical Overview but the plan is to make it possible to add widgets to almost any page. By using a functionality similar to iGoogle it will be possible to move the widgets around, edit settings etc. All this is currently pretty much at design stage but it looks really promising. Today we are using the widgets as hard-coded, self-contained components on a page but this should change in a not so far future.

So how do you build a widget?
First of all - consider this a draft. We are still finding our way and input is always appreciated.

A widget is instantiated using the widget helper:

widget::add('netw_health', array('index', $this->model), $this);

The helper takes care of a lot of the backend stuff like handling paths and assigning master controller variables. More on this later.

Why do we use a helper and not a controller?
Since kohana fires off some system events (like system.post_controller) every time a controller is finished, we didn't want this overhead. Also, we didn't want the widget output to be returned to browser immediately but wanted the master (calling) template to decide where to render the output. Our solution was instead to use a helper class and buffer the output using ob_start() and ob_get_contents().

The widgets has to follow some simple rules to work:
It has to be placed in a folder with the exact name as the widget.
The folder should be in widgets or - if you are developing your own - in custom_widgets
The widget class should be named like the widget name + _Widget and should extend widget_Core. If we look at the netw_health widget as an example:
class Netw_health_Widget extends widget_Core
{
//
}
Everything is case sensitive here.

Our widget also needs a constructor:
public function __construct()
{
parent::__construct();

# needed to figure out path to widget
$this->set_widget_name(__CLASS__, basename(__FILE__));
}

The constructor sets the name and path needed for the master controller to be able to render the widget correctly.

To look at our example again:
widget::add('netw_health', array('index', $this->model), $this);

The second argument to widget::add() is an array and the first element should always be the method to call. Some widgets will need access to some data to be useful and in this case we are passing a reference to the model used in the master controller.
The last argument here is the reference to the master controller so that we are able to pass the generated widget content. The master controller takes care of putting these at the appropriate place in the rendered HTML head.

Our index method:
public function index($arguments=false, $master=false)
{
$this->master_obj = $master;
}
This first assignment is important since it is how we refer back to the master controller - without it, the widget won't be visible anywhere.

The widgets view file could be called anything (as long as it has a php extension) and to use it you call $view_path = $this->view_path('view'); with the name of the view template as an argument.

The view (template) file:
The entire widget output should be contained in a div
<div class="widget movable collapsable removable closeconfirm" id="widget-network_health">
// widget content goes here
</div>
You should give the div an ID following the format: 'widget_'<widget_name> to make it possible to access it in a generic way using JavaScript.

To add extra css resources you assign $this->css with an array like this:
$this->css = array('/css/netw_health');. The same thing is done with needed JavaScript files using $this->js.

After writing the code that actually does something (left out here as I feel that it is somewhat out of scope for this post) there is only 2 more things to do:

require_once($view_path);
OK, so I stated earlier that you didn't have to write requires. Well even though I feel that it could be optimized, I don't feel that it's such a big deal. We could probably let the widget helper class do this but hey, we aren't finished with Ninja yet ;-)

Last thing needed is return $this->fetch(); which will do the ob_get_contents() thing and pass everything back to the calling controller.

The actual location of the widget on the rendered page, is then all up to the master controller and template - the widget should only return a view.

The netw_health widget code.
The view (template) code.

Pretty awesome, huh? :-)

Friday, April 3, 2009

Ninja Application structure, part 2

To give a somewhat better understanding on how the classes (controllers and models respectively) are related to each other I will here show some (really simple) architecture sketches.

Controllers
This shows how the base controllers are connected: Our Ninja controller extends the kohana base controller and is in charge of creating translation (gettext) object instances, database connection, session etc. Extending this we have default which doesn't require any login or anything - a typical start page and login controller.

As you might have guessed, the Authenticated_Controller takes care of authenticating users (more on this in some later post). All controllers that should require an authenticated user, should extend this class as does the tac controller in the sketch above.

Models
Here we also have a base Ninja class - the Ninja Model which also makes sure that application specific variables and objects are present.
All Ninja models should consequently extend this model.

This is brief overview of how the Ninja classes should be extended in order to save us from writing things several times and to be sure that we preserve the basic functionality. Hopefully it has given anyone interested a slightly better understanding.

Once again - this is to be considered a draft and is subject to change.

Ninja Application structure

This time I intend to clarify the Ninja directory structure. It is pretty simple but nevertheless it is important to place files at the correct location. For more info, please visit kohana's excellent website.
The files in the git repository consists of the following 3 folders:
  • application
    This is where all the Ninja files will go
  • modules
    ex: authentication, unit_test
  • system
    Kohana system files that should be updated when the kohana project is updated
So, the directory where we keep our Ninja files is in application.
To get a better understanding of the different parts and how everything is connected we will have a look at this folders subdirectories.
  • cache
    We currently don't use this but Kohana lets you cache any data in order to achieve maximum performance
  • config
    Configuration files for the application, routes, database, authentication, session. widget etc
  • controllers
    consist of the equivalent to todays cgi's, i.e tac, extinfo, status, cmd, etc
  • custom_widgets
    Widgets created by users and possibly uploaded. Will not be overwritten on update.
  • helpers
    nifty classes that extends the functionality and makes our life easier
  • hooks
    We don't use any hooks yet but it is yet another way of tweaking the kohana functionality
  • languages
    Translation files in mo/po (gettext) format
  • libraries
    Another way of adding functionality to kohana/ninja. We added unit_test
  • logs
    If you enable logging (in config/config.php) this is where the logs end up
  • media
    media resources (images, css, js etc) that should be globally accessible (not depending on the current theme)
  • models
    The data part of the application. Even if this is not entirely true since it may also contain some business logic etc, it is easiest to look at models this way.
  • vendor
    This is where we keep Zend components like Zend_Translate
  • widgets
    Default Ninja components that could be updated on upgrade
  • views
    Contains the presentation templates. Will contain the different themes (skins) available
As mentioned in previous post, it is essential to place the files in the correct folder and also to name the files and classes accordingly. This way you will hardly ever need to write any require_once or anything.

To be continued...