Monitoring of OpenStack Resources through Nagios using Mistral

 In Openstack



Monitoring in an OpenStack based set-up is usually achieved through Ceilometer. Ceilometer is used to monitor various OpenStack components. However it is not effective when it comes to monitoring of each tenant and the various applications/services running on the tenants. Application/Service specific monitoring can be achieved through different monitoring tools such as Nagios , Zabbix..etc. In this blog we will discuss about using Nagios monitoring tools for such monitoring requirements.

Nagios monitoring system can be used to monitor the hosts and services for each tenants which can then send email or page alerts in case of any events in the monitored infrastructure.

This topic will have 2 sections, the first one will cover about the Nagios API for monitoring a Server or associated service and in the second section we will take a close look at the Mistral plug-in architecture and how it can be extended to support Nagios specific actions for monitoring.

Nagios plug-in:

Nagios Core, the opensource version of Nagios monitoring does not have the ability to control nagios using an API. However nagios-api(, a python package provides web services API for accessing and operating data of Nagios hosts and services, accessing Nagios configuration. It provides a set of REST-like interfaces to various maintenance and operations functions.

These interfaces include: acknowledge_problem, remove_acknowledgement, add_comment, delete_comment, enable_notifications, disable_notifications, log, objects, schedule_check, schedule_downtime, state, and submit_result.

Use of these functions in scripts and applications substantially eases the chore of maintaining Nagios. For example, adding a comment to a Nagios host is very straightforward using the add comment function.

Testing the API

[email protected]:~$ curl -X POST -H “Content-Type: application/json” -d ‘{“host_name”:”sample_host”, “address”:”″, “contacts”:”test”, “check_interval”:”5″, “max_check_attempts”:”2″}’
{“status”: true, “content”: “Host Added Successfully”}

The above snippet is an example of using the add_host API from CLI. It’s a POST call which creates a host config file with the given details in nagios and returns the response.You can view the added host file in the name of “sample_host.cfg” (host_name.cfg) in nagios host configuration file path(/usr/local/nagios/etc/objects/). Make sure that the contact name which you mentioned in the ‘contacts’ field must be available in contact definition in nagios. If not so, create a new contact in nagios by making use of ‘add_contact’ API and then do add_host call.

We have added other actions like add_service, add_contact,etc which can create service, contact configuration files in nagios respectively .

More information can be found in the following link for nagios-api installation process and the steps to run it in your nagios server.

Now we have set-up the Nagios API successfully, let’s define the mistral actions to invoke the same.

Mistral Plug-in Architecture:

Mistral provides actions extensibility so that anyone can write their own actions and plug them into the system. The essential idea is that actions form a class hierarchy with the root class Action described above. The main requirements for action plugin system are:

  • Ability to specify action namespace.
  • Ability to specify action shortcut.
  • Once an action is registered in Mistral it can be accessed in DSL using form ‘namespace.action_shortcut’.

Likewise we are extending mistral actions for nagios to invoke nagios api.

To create a custom plugin in mistral, the following structure has to be followed: (ref 1.1)


ref 1.1 – example for mistral folder structure

All action namespace should be registered in mapping.json and defined in .

mapping.json file

add_host : add_host

add_service: add_service

def add_host(self, host_name, address, **kwargs):
# Adds a host to nagios
uri = “add_host”
url = “%s/%s” % (nagios_url, uri) # nagios_url –nagios server endpoint
body = {“host_name”: host_name,
“address”: address
for key in kwargs:
body[key] = kwargs[key] body = json.dumps(body)
headers = {“content-type”: “application/json”}
response, body = self.httpclient.request(url, method=”POST”,
body=body, headers=headers)
body = self.json_loads(body)
return body


Namespaces and Invocation

Actions are grouped into namespaces. Also, Mistral has a number of standard actions. The standard actions can be referred via “std” namespace. For example, “std.http”.

Declaration of custom-actions

New namespaces and actions can be defined in DSL, based on existing actions.

action: nagios.add_host
address: ‘x.x.x.x’ // IP address of the host to be monitored
check_interval: ‘2’ // Frequency of checks in minutes to poll CPU
contacts: ‘test’ // Contact name to notify the monitoring status
host_name: ‘sample’ // Name of the host
max_check_attempts: ‘1’ // Maximum number of check attempts for Host
This snippet invokes the defined action “add_host” using the namespace “nagios” so that it’s possible to refer to it using “nagios.add_host”. This is how the task creation should be.
Here is a sample mistral template to add a host in nagios.

description: “This template is for monitoring linux host availability.”
description: “Name of a contact”
label: Contact_Name
type: string
description: “IP address of a given Host”
label: Host_IP
type: string
description: “Name of a Host”
label: Host_Name
type: string
default: 2
description: “Maximum number of check attempts for Host”
label: Max_Check_Attempts_Host
type: number
default: 2
description: “Frequency of checks in minutes for Host”
label: Polling_Interval_Host
type: number
Host_result: $.Host
action: nagios.add_host
address: $.Host_IP
check_interval: $.Polling_Interval_Host
contacts: $.Contact_Name
host_name: $.Host_Name
max_check_attempts: $.Max_Check_Attempts_Host
Host: $.content
type: direct
version: 2.0

Note: “input” (under tasks) is a keyword for specifying parameters of the custom action where parameter values may contain placeholders of the form “${some_value}” where “some_value” refers to one of the input parameters declared under “input” section.

Further Development

Certainly over time we will develop a few more functions to be implemented and will be writing more about that soon.

Recent Posts

Leave a Comment

Start typing and press Enter to search