Web-API

Last updated: December 14. 2017


1. Introduction

The Web-API enables configuration tasks that are normally performed manually in the WATO web interface to be automated using HTTP-invocation. The complete WATO functionality is in fact not currently available via API, but the interface is being constantly extended, and the most important things, such as the managing of hosts, folders, instances, users, groups and more is already possible. A full list of all API functions can be found here.

Most users utilise the Web-API for connecting existing CMDBs or for automatically linking hosts that are created automatically in a dynamic environment.

A basic knowledge of Python and its Data structures are needed for reading this article. The article is of course written as simply as possible so that the subject is also understandable to beginners.

2. The basics and requirements

2.1. The automation user

So that you can use the Web-API, first an Automated user will be required. Only this user is permitted to execute actions over the Web-API. On a newly-created site the automation user already exists and in this article it will always be used as an example. It can be found, like other users, in WATO ➳ Users.

If the site has been created with Version 1.2.8 or older, first create such an automation user. In principle any password can then be defined as the Automation secret for machine accounts, or with the die you can allow one to be generated by Check_MK.

The roles and and their associated permissions can be customised for an automated user in the same way as for a normal user. Make sure that for an own role the Access to Web-API permission has been set.

2.2. The URL structure

The following examples always draw on the curl command line program to clarify the general syntax of the invocations. If you are using another technology adapt the invocations as appropriate.

For the actual URL http://myserver/mysite/check_mk/webapi.py various parameters are required. These parameters contain the access data for the automated users, and the information regarding the tasks to be performed. If the invocation is to draw on a particular element in Check_MK, this data will be transferred as a payload:

Parameter Meaning
_username The automated users login name
_secret The automation password
action Defines the task to be performed
request_format The syntax for the request-data. python or json are possible
output_format The syntax of the answer. Here python and json are also possible
request The data to be transferred if required by the action

With curl the first five parameters can be transferred directly in the URL. They begin with a ? and are linked with a >&, and they can be coded in any order:

root@linux# curl "http://myserver/mysite/check_mk/webapi.py?action=get_all_hosts&_username=automation&_secret=mysecret&request_format=python&output_format=python"
{'result': {'myserver123': {'attributes': {'ipaddress': '192.168.0.42'}, 'hostname': 'myserver123', 'path': ''}, 'myserver456': {'attributes': {'ipaddress': '192.168.0.73'}, 'hostname': 'myserver456', 'path': 'windows'}}, 'result_code': 0}

On the one hand, the answer will contain a result_code – this will show if an error has ocurred during the query. If the query was successful a 0 will be returned, if there has been an error a 1 will be returned. On the other hand there is the (result) itself, in which the site's response is found. This response can be an error message if the query has failed, or it can contain the desired data if the query has been successful. If a command has been directed to the Check_MK server the result field can under some circumstances be empty, or respectively, a 'None' value can be returned.

Some commands require the request parameter. This contains the required data – for example, to query a specific host's configuration. The switch -d is used to transfer this data:

root@linux# curl "http://myserver/mysite/check_mk/webapi.py?action=get_host&_username=automation&_secret=mysecret&request_format=python&output_format=python" -d 'request={'hostname':'myserver123'}'
{'result': {'myserver123': {'attributes': {'ipaddress': '192.168.0.42'}, 'hostname': 'myserver123', 'path': ''}}, 'result_code': 0}

Important: In the following examples and in the Command reference the input and answer are often spread over several lines to improve readability and the overview in general. In practice both the input and the answer will be coded without line breaks.

2.3. Data format for the inputs and answers

The API recognises two parameters for defining the input or answer data format. The input format is defined by request_format, and the answer is defined by output_format. If these parameters are not used API defaults to JSON format.

These days however the support of JSON in Check_MK has become generally experimental/obsolete. Even though many commands use JSON without errors, Python should always be used for inputs and answers. Below is a practical example in which, for example, tuples are used in the answer:

root@linux# curl "http://myserver/mysite/check_mk/webapi.py?action=get_host&_username=automation&_secret=myautomationsecret&output_format=python" -d 'request={"hostname":"myserver123"}'
{'result': {'myserver123': {'attributes': {'ipaddress': '192.168.0.42', 'management_snmp_community': ('authPriv', 'md5', 'myuser', 'mypassword', 'DES', 'myprivacypassword')}, 'hostname': 'myserver123', 'path': ''}}, 'result_code': 0}

JSON and Python have a few other differences in their data formats. These are:

  • In JSON the zero value is 'null', and in Python 'None'.
  • As already mentioned, tuples are not used in JSON. They are used by some commands in API, and are converted to simple lists in JSON. If in the further processing a list instead of a tuple is submitted, then the data integrity in Check_MK cannot be guaranteed and the transfer of a configuration will be aborted with an error message.
  • JSON accepts only double quotes, while Python only requires the paired characters to be the same.
  • Boolean values (True and False) are coded as uppercase in Python, and as lowercase in JSON.

2.4. Testing the API locally

So that Web-API commands can be tested directly from the Check_MK server, it makes sense to work as an instance user. You can then access local variables and also directly read the automated user's password. In the following example the variables $OMD_SITE and $OMD_ROOT which refer to the site's name and home directory are used. The password will be directly output with cat:

OMD[mysite]:~$ curl "http://localhost/$OMD_SITE/check_mk/webapi.py?action=get_all_hosts&_username=automation&_secret=$(cat $OMD_ROOT/var/check_mk/web/automation/automation.secret)"

As long as the automation user is present this invocation will work on every site. You could could simply copy the above example and test it on your own site, for example. This of course can only work if the command is executed as an instance user on the Check_MK server.

3. Using commands

Check_MK uses a number of commands for managing the configurations of hosts, rules and much more. Have a look in the Command reference for a description of all of the commands.

To illustrate working with the API using a simple example, we will create a host with its services via the Web-API using only three commands. In principle you can proceed in exactly the same way as with Check_MK's WATO:

  • Create a host
  • Execute a Service Discovery on the host
  • Activate the changes

Creating a host

A host can be created in Check_MK with the add_host command. For this the minimum requirement is a host name and the directory where it is to be stored. Additionally, available attributes such as, for example, a host's IP-address, can also be explicitly defined. The request-component will look like this, for example:

{'hostname': 'myserver123',
 'folder': '',
 'attributes': {'ipaddress': '192.168.0.42',
                'site': 'mysite',
                'tag_agaent': 'cmk-agent'}}

In the above example the host myserver123 will be stored in the main directory. In the process it will receive an IP-address, and additionally be defined as a host that receives its data from a Check_MK agent, and it will be assigned to the instance mysite. To test on the command line, the host can be created as follows (substitute your own real values for the placeholders):

root@linux# curl "http://myserver/mysite/check_mk/webapi.py?action=add_host&_username=automation&_secret=myautomationsecret" -d 'request={"hostname":"myserver123","folder":"","attributes":{"ipaddress":"192.168.0.42","site":"mysite","tag_agent":"cmk-agent"}}'

Executing a Service Discovery

Once the host has been created, services can be added to it. Here enter the host name, and specify the type of Service Discovery as required. If nothing is entered only the newly-discovered services will be added:

root@linux# curl "http://myserver/mysite/check_mk/webapi.py?action=discover_services&_username=automation&_secret=myautomationsecret" -d 'request={"hostname":"myserver123"}'

Activating changes

Finally, the changes can be activated as in WATO:

root@linux# curl "http://myserver/mysite/check_mk/webapi.py?_secret=myautomationsecret&_username=automation&action=activate_changes" -d 'request={"sites":["mysite"]}'

4. Securing a Web-API

Since an access over the Web-API can contain sensitive data, and it could – depending on the the automated user's permissions – perform comprehensive alterations to Check_MK, it would be desirable to have appropriate security for the access. The following are a couple of options for this security:

  • Check_MK over HTTPS: Use the Web-API exclusively over HTTPS, otherwise user names, passwords and also configuration data will be transmitted over the web in plain text.
  • Give the automated user a password of sufficient length. Because as a rule this will only need to be coded once in a script it is no problem to assign a very long one.
  • Pay close attention to the authorisation concept for scripts. Sensitive data such as configuration standards, passwords, etc., can be included in them. Ensure that only authorised users and groups can read these scripts.

5. Error handling

As explained above, a query returns an error code if it was unsuccessful. This is contained in the result_code. A description of the error is included in the result itself. This is a good place to start an analysis of the problem.

Also check whether the following requirements have been met:

  • The automated user has the necessary permissions for reading or setting configuration data.
  • The individual parameters have a leading question mark (?), and are linked with an ampersand (&). Also note that the _username and _secret begin with an underscore (_).
  • The request-component has the correct syntax.

Permissions

As already mentioned an automated user's permissions can be a source of errors if, for example, configuration data is to be retrieved. The automation user supplied with Check_MK has the Administrator role and it can thus see and process everything. Because every available role can be assigned to an automated user, the contact groups must be adapted as appropriate to be able to query or process specific hosts. In the case of an error, check that these permissions are correct for the relevant automated user.

Command syntax

When testing with curl it will quickly become confusing in the request-component. Therefore always check whether the syntax is correct (even if you are not using curl).

Coding the request-component in a file can be quite a good method to aid with visualisation:

~/home/myuser/pattern.txt
{"users": {"myuser": {"alias": "My User",
                      "email": "myuser@mycompany.org",
                      "language": None,
                      "pager": "01374-12233456",
                      "password": "mypassword"}}}

These lines can also be copied into a Python-Prompt, and then they can be output in one line with the print command:

root@linux# python
>>> print {"users": {"myuser": {"alias": "My User",
...                       "email": "myuser@mycompany.org",
...                       "language": None,
...                       "pager": "01374-12233456",
...                       "password": "mypassword"}}}
{'users': {'myuser': {'alias': 'My User', 'password': 'mypassword', 'pager': '01374-12233456', 'email': 'myuser@mycompany.org', 'language': None}}}

By the way, the blank characters can remain in the curl command:

OMD[mysite]:~$ curl "http://localhost/$OMD_SITE/check_mk/webapi.py?action=add_users&_username=automation&_secret=$(cat $OMD_ROOT/var/check_mk/web/automation/automation.secret)&output_format=python&request_format=python" -d "request={'users': {'myuser': {'alias': 'My User', 'password': 'mypassword', 'pager': '01374-12233456', 'email': 'myuser@mycompany.org', 'language': None}}}"
{'result': None, 'result_code': 0}

6. Files and directories

Path Function
etc/check_mk/conf.d/wato/ The directories stored here are the directories which are displayed with their Hosts in WATO.
etc/check_mk/conf.d/wato/.wato A directory's attributes and title are defined in this file. It is found in every directory under WATO.
etc/check_mk/conf.d/wato/hosts.mk Here the host's configuration which will be assigned to the appropriate directory is defined. This file is also present in every directory under WATO.
etc/check_mk/conf.d/wato/group.mk All defined groups are found here – including contact, service and host groups. There is only one version of this file.
etc/check_mk/multiside.d/wato/users.mk User settings in Check_MK are defined in this file.
etc/check_mk/conf.d/wato/rules.mk In this file the rules defined for every directory under WATO are held.
etc/check_mk/multisite.d/wato/hosttags.mk All host tags and auxiliary tags are defined here.
etc/check_mk/multisite.d/sites.mk All sites with their attributes are listed here. The local site will also be held here.
var/check_mk/agents/ Created/baked agents are stored here. For every host there is a link stored here which identifies the host's installation packet.
var/check_mk/web/myuser/user_custom_graphs.mk Self-created graphs are stored with the respective user. In the example shown here it is the user ‘myuser’.