Skip to end of metadata
Go to start of metadata

Icinga-Web REST API

Abstract

In this document we'll describe the Icinga-Web REST API which allows you to request your monitoring information via GET or POST requests (in the future (>1.2) , you will also be able to send commands via PUT).

Why should I use the API?

For most people, the combination Icinga/Icinga-web will fit most needs. You can see your monitoring status, act on problems and extend it to suit your needs (Modules/Cronks).
But sometimes, you have another piece of software that is interested in some monitoring data (for example, Icinga-Chromed-Status:http://www.icinga.org/2010/07/16/icinga-chromed-status-for-google-chromechromium/). You could parse the cgi output of Icinga (I think a lot of programs do that at this time), but that's not really a high performance solution - and certainly no fun for the developer. 

The goal of the REST API is to return the data you want (and only the data you want) in a standardized, machine-readable format like JSON or XML.

Features

Currently supported

  • Availability of almost all monitoring fields via GET or POST.
  • Return data as xml or json
  • AND & OR Search filtergroups with unlimited nesting levels (AND(OR(AND()))
  • You choose which columns you want returned, not the API (less overhead)
  • Support of limit, offset, order, group by
  • Return an additional total count field
  • Authorization via auth_key in request or cookies
  • Respects Icinga-web principals (for example, limit to specific hostgroups)
  • Since icinga v1.6: Retrieve detailed SLA information or enhance a request with sla information

Prerequisites

Icon

Since 1.5, api access is enabled by default

In order to use the api, you first have to enable the Auth provider for it. This can be done under
icinga-web/app/modules/AppKit/config/auth.xml.

Change "auth_enabled" to 'true' in this section:

Afterwards, clear the cache (icinga-web/bin/clearcache.sh).

Now, in icinga-web, you have to add an user with Api access:

  • Create a new user
  • Choose auth_key in the Auth_via field
  • Insert an API Key to use
  • Under principals, add the appkit.api.access principal

That's it, now you can start!

Reference

In the next few chapters we'll explain how the API can be accessed

Changes in 1.6+

Icon

Since v1.6, the api key must be inserted in the URL

 

GET

Advantages

  • Easy to use, it's just an URL!
  • You always see what parameters have been requested

Disadvantages

  • If you request it in a browser your API Key could be in the browser history
  • In a browser, you cannot add URLs with unlimited size (2,083 Characters for Internet explorer, for example)
  • Especially when parameters are escaped, the parameter list lacks a bit of clarity

The structure of the URL

To access, the api, the URL should look as in the following (italics are optional, bold ones are required)

host.com/icinga-web/web/api/ %TARGET% / %COLUMNS% / %FILTER% / %ORDER% / %GROUPING% / %LIMIT% / %COUNTFIELD% / %OUTPUT_TYPE%

Parameters in detail

  • TARGET : Which field to request, is a simple string like host
  • COLUMNS : A listing of columns to return, must look like this: columns[column1|column2|column3]
  • FILTER : Defines which filters to use in the request. Must always be nested in AND or OR groups. The filter itself looks like this:
    AND query-> filters[AND(%column%|%operator%|%value%;%column%|%operator%|%value%)] 
    OR query-> filters[OR(%column%|%operator%|%value%;%column%|%operator%|%value%)]
    AND \w OR>  filters[AND(%column%|%operator%|%value%;OR(%column%|%operator%|%value%;%column%|%operator%|%value%;)]

> Example: Select all services with smtp in the name, but only if they're ok or unknown

>Wrong: filtersSERVICE_NAME

>You always need a nesting level at the beginning, see:

>Correct: filtersAND ( SERVICE_NAME

  • ORDER : Defines which field to use for ordering and if ascending or descending ordering should be used.
    Example: orderCOLUMN
  • GROUPING : Defines a field to group by: groupCOL
  • LIMIT : Defines a starting offset and/or a limit: limitSTART;END ( if needed ) ||||||||\
  • COUNTFIELD : Adds a total field to the result which counts by this field (in most cases, the id): countColumn=COL
  • OUTPUT : At this time either json or xml

Example for GET

Get all Services that are critical or warning, but have an host that is ok. Sort descending by the service state and count the services. Authentification is done via authkey (here APITEST123456).
The request is broken in pieces for better readability,
XML:

This would return something like

If you change the xml to json you get the same information (plus additional infos for ExtJS, which you can ignore if you're not using it) in json format:

POST

Advantages

  • Unlimited parameter size, as it's made for big requests
  • You're parameters don't appear in the browser history, only the base url
  • It's easier to implement in applications (ok, that's my opinion (smile) )

Disadvantages

  • POST will be send via the header, so you can't request it easily from the browser's address field

Parameters in detail

The link is almost the same like the GET Baselink, but with the output type in it:
For example, host.com/icinga-web/web/api/json.

The following parameters are supported:

  • 'target' : The search target, like host
  • 'columns[]' : An array of columns

>Example:
columns 0 = SERVICE_NAME
columns 1 = SERVICE_ID

  • 'groups[]' : Group by this field
  • 'filters_json' : A json describing how to filter

> Example:

  • 'order_col' : Column to order by
  • 'order_dir' : Order direction (asc oder desc)
  • 'limit_start' : The offset of the records to start
  • 'limit' : Limits the result to x responses
  • 'countColumn' : Add a total field with this column

Example for POST

Lets take the example from Example for GET and use a post request this time. I'm going to use curl, so the example can be repeated from the console:

This would return the same result as the GET Request shown before.

  • No labels

12 Comments

  1. Anonymous

    Where can we get a list of targets & column names? Can't seem to find it in the documentation.

    1. Overview of targets & Columns will be app/modules/Api/models/Store/LegacyLayer/TargetModifierModel.class.php

  2. Anonymous

    Is it possible to get custom variable values with the REST API ?

  3. Anonymous

    The JSON example is invalid, JSON does not allow single quotes.

  4. JSON doesn't explicitly allow it, but it's supported by almost any parser, see http://stackoverflow.com/questions/2275359/jquery-single-quote-in-json-response for more details. But you're right: The mixed use of " and ' is not very clean.

  5. Anonymous

    I've had a hard time getting the example calls to give me anything but untrapped exceptions but I'm finally down to this url that does give me some output:

    icinga-web/web/api/service/authkey=secretkey/xml
    <results>
    <result/>
    <result/>
    <result/>
    <result/>
    <result/>
    <result/>
    <result/>
    <result/>
    </results>

     now, that's the right number of services but I can't find any way to actually get some useful service attributes in the output. can anyone help

  6. Anonymous

    fyi, the examples in the doc need fixing; the syntax is incorrect for (at least) the columns path fragment which shows parens instead of the required brackets. This is a simple url showing the expected syntax:

    http://localhost/icinga-web/web/api/host/filter[AND(HOST_CURRENT_STATE%7C=%7C0)]/columns[HOST_NAME]/authkey=xxxxxxxx/json

     

    Also, I had a hard time getting the authkey to work - until I spotted this in the appkit code:

    public function doAuthKeyLogin($key) {
    $this->doLogin($key,$key);
    }

    once I saw this, I created a user having identical userid and authkey - then the login works

    Andy Brown

    (I'd like to contribute to the code, if you want an extra hand?)

  7. Anonymous

    Hi,

    I had problems using the REST API following the above guide. Followed every step of the guide, but ended up with the following replies from the server:

    {"success":false,"errors":["User has insufficient rights to access the api"]}

    However, I found out that it only works if the auth_key and username are the same. Is this supposed to be the correct behaviour?

     

    PS: Noticed that another user spotted this on May 17, 2013, so please update this page!

     

    Cheers,

    Bjørn

  8. Icinga-Web 1.9.0

    The use of the parameter authkey with the POST methode as described in the Wiki doesn't work for me.

    I follow the tip above (name of the user = authkey) but i receive always an rights error:

    This works (authkey in the url):

    curl -d target=service -d 'filters_json= {"type":"AND","field":[{"type":"atom","field":["HOST_NAME"],"method":["="],"value":["V0001080"]},{"type":"atom","field":["SERVICE_NAME"],"method":["="],"value":["OS_CPU_Load"]}]}' -d columns[0]=SERVICE_NAME -d columns[1]=HOST_NAME -d columns[2]=SERVICE_CURRENT_STATE http://localhost/icinga-web/web/api/authkey=XXXXXX/xml   <?xml version="1.0" encoding="UTF-8"?>
    <results><result><column name="SERVICE_NAME">OS_CPU_Load</column><column name="HOST_NAME">V0001080</column><column name="SERVICE_CURRENT_STATE">0</column><column name="SERVICE_IS_PENDING">0</column></result></results>

    This doesn't work (authkey als parameter):

    curl -d target=service -d 'filters_json= {"type":"AND","field":[{"type":"atom","field":["HOST_NAME"],"method":["="],"value":["V0001080"]},{"type":"atom","field":["SERVICE_NAME"],"method":["="],"value":["OS_CPU_Load"]}]}' -d columns[0]=SERVICE_NAME -d columns[1]=HOST_NAME -d columns[2]=SERVICE_CURRENT_STATE -d 'authkey=XXXXXX' http://localhost/icinga-web/web/api/xml
    <?xml version="1.0" encoding="utf-8"?>
    <error><message>User has insufficient rights to access the api</message></error>

    Can somebody confirm this problem ? I would like to open an issue.

  9. Anonymous

    I am able to pull current bandwidth(service name) status for a given host. Thing I am trying to figure out is how to pull data for let's say 4 hours. I know Icinga stores this data, but I am not sure what API call would work for this.