1 # <a id="icinga2-api"></a> Icinga 2 API
3 ## <a id="icinga2-api-setup"></a> Setting up the API
5 You can run the CLI command `icinga2 api setup` to enable the
6 `api` [feature](11-cli-commands.md#enable-features) and set up
7 certificates as well as a new API user `root` with an auto-generated password in the
8 `/etc/icinga2/conf.d/api-users.conf` configuration file:
12 Make sure to restart Icinga 2 to enable the changes you just made:
14 # service icinga2 restart
16 If you prefer to set up the API manually, you will have to perform the following steps:
18 * Set up X.509 certificates for Icinga 2
19 * Enable the `api` feature (`icinga2 feature enable api`)
20 * Create an `ApiUser` object for authentication
22 The next chapter provides a quick overview of how you can use the API.
24 ## <a id="icinga2-api-introduction"></a> Introduction
26 The Icinga 2 API allows you to manage configuration objects
27 and resources in a simple, programmatic way using HTTP requests.
29 The URL endpoints are logically separated allowing you to easily
32 * query, create, modify and delete [config objects](12-icinga2-api.md#icinga2-api-config-objects)
33 * perform [actions](12-icinga2-api.md#icinga2-api-actions) (reschedule checks, etc.)
34 * subscribe to [event streams](12-icinga2-api.md#icinga2-api-event-streams)
35 * [manage configuration packages](12-icinga2-api.md#icinga2-api-config-management)
36 * evaluate [script expressions](12-icinga2-api.md#icinga2-api-console)
38 ### <a id="icinga2-api-requests"></a> Requests
40 Any tool capable of making HTTP requests can communicate with
41 the API, for example [curl](http://curl.haxx.se).
43 Requests are only allowed to use the HTTPS protocol so that
44 traffic remains encrypted.
46 By default the Icinga 2 API listens on port `5665` which is shared with
47 the cluster stack. The port can be changed by setting the `bind_port` attribute
48 for the [ApiListener](9-object-types.md#objecttype-apilistener)
49 object in the `/etc/icinga2/features-available/api.conf`
52 Supported request methods:
56 GET | Retrieve information about configuration objects. Any request using the GET method is read-only and does not affect any objects.
57 POST | Update attributes of a specified configuration object.
58 PUT | Create a new object. The PUT request must include all attributes required to create a new object.
59 DELETE | Remove an object created by the API. The DELETE method is idempotent and does not require any check if the object actually exists.
61 All requests apart from `GET` require that the following `Accept` header is set:
63 Accept: application/json
65 Each URL is prefixed with the API version (currently "/v1").
67 ### <a id="icinga2-api-responses"></a> Responses
69 Successful requests will send back a response body containing a `results`
70 list. Depending on the number of affected objects in your request, the
71 `results` list may contain more than one entry.
73 The output will be sent back as a JSON object:
80 "status": "Object was created."
85 Tip: If you are working on the CLI with curl you can also use [jq](https://stedolan.github.io/jq/)
86 to format the returned JSON output in a readable manner. The documentation
87 prefers `python -m json.tool` as Python is available nearly everywhere.
91 > Future versions of Icinga 2 might set additional fields. Your application
92 > should gracefully handle fields it is not familiar with, for example by
95 ### <a id="icinga2-api-http-statuses"></a> HTTP Statuses
97 The API will return standard [HTTP statuses](https://www.ietf.org/rfc/rfc2616.txt)
98 including error codes.
100 When an error occurs, the response body will contain additional information
101 about the problem and its source.
103 A status code between 200 and 299 generally means that the request was
106 Return codes within the 400 range indicate that there was a problem with the
107 request. Either you did not authenticate correctly, you are missing the authorization
108 for your requested action, the requested object does not exist or the request
111 A status in the range of 500 generally means that there was a server-side problem
112 and Icinga 2 is unable to process your request.
114 ### <a id="icinga2-api-authentication"></a> Authentication
116 There are two different ways for authenticating against the Icinga 2 API:
118 * username and password using HTTP basic auth
121 In order to configure a new API user you'll need to add a new [ApiUser](9-object-types.md#objecttype-apiuser)
122 configuration object. In this example `root` will be the basic auth username
123 and the `password` attribute contains the basic auth password.
125 # vim /etc/icinga2/conf.d/api-users.conf
127 object ApiUser "root" {
131 Alternatively you can use X.509 client certificates by specifying the `client_cn`
132 the API should trust. The X.509 certificate has to be signed by the CA certificate
133 that is configured in the [ApiListener](9-object-types.md#objecttype-apilistener) object.
135 # vim /etc/icinga2/conf.d/api-users.conf
137 object ApiUser "root" {
138 client_cn = "CertificateCommonName"
141 An `ApiUser` object can have both authentication methods configured.
143 You can test authentication by sending a GET request to the API:
145 $ curl -k -s -u root:icinga 'https://localhost:5665/v1'
147 In case you get an error message make sure to check the API user credentials.
149 When using client certificates for authentication you'll need to pass your client certificate
150 and private key to the curl call:
152 $ curl -k --cert example.localdomain.crt --key example.localdomain.key 'https://example.localdomain:5665/v1/status'
154 In case of an error make sure to verify the client certificate and CA.
156 The curl parameter `-k` disables certificate verification and should therefore
157 only be used for testing. In order to securely check each connection you'll need to
158 specify the trusted CA certificate using the curl parameter`--cacert`:
160 $ curl -u root:icinga --cacert ca.crt 'icinga2.node1.localdomain:5665/v1'
162 Read the next chapter on [API permissions](12-icinga2-api.md#icinga2-api-permissions)
163 in order to configure authorization settings for your newly created API user.
165 ### <a id="icinga2-api-permissions"></a> Permissions
167 By default an API user does not have any permissions to perform
168 actions on the URL endpoints.
170 Permissions for API users must be specified in the `permissions` attribute
171 as array. The array items can be a list of permission strings with wildcard
174 Example for an API user with all permissions:
176 permissions = [ "*" ]
178 Note that you can use wildcards. Here's another example that only allows the user
179 to perform read-only object queries for hosts and services:
181 permissions = [ "objects/query/Host", "objects/query/Service" ]
183 You can also further restrict permissions by specifying a filter expression. The
184 filter expression has to be a [lambda function](17-language-reference.md#nullary-lambdas)
185 which must return a boolean value.
187 The following example allows the API user to query all hosts and services which have a
188 custom attribute `os` that matches the regular expression `^Linux`.
189 The [regex function](18-library-reference.md#global-functions-regex) is available as global function.
193 permission = "objects/query/Host"
194 filter = {{ regex("^Linux", host.vars.os) }}
197 permission = "objects/query/Service"
198 filter = {{ regex("^Linux", service.vars.os) }}
202 More information about filters can be found in the [filters](12-icinga2-api.md#icinga2-api-filters) chapter.
204 Available permissions for specific URL endpoints:
206 Permissions | URL Endpoint | Supports Filters
207 ------------------------------|---------------|-----------------
208 actions/<action> | /v1/actions | Yes
209 config/query | /v1/config | No
210 config/modify | /v1/config | No
211 console | /v1/console | No
212 events/<type> | /v1/events | No
213 objects/query/<type> | /v1/objects | Yes
214 objects/create/<type> | /v1/objects | No
215 objects/modify/<type> | /v1/objects | Yes
216 objects/delete/<type> | /v1/objects | Yes
217 status/query | /v1/status | Yes
218 templates/<type> | /v1/templates | Yes
219 types | /v1/types | Yes
220 variables | /v1/variables | Yes
222 The required actions or types can be replaced by using a wildcard match ("\*").
224 ### <a id="icinga2-api-parameters"></a> Parameters
226 Depending on the request method there are two ways of
227 passing parameters to the request:
229 * JSON object as request body (all request methods other than `GET`)
230 * Query string as URL parameter (all request methods)
232 Reserved characters by the HTTP protocol must be [URL-encoded](https://en.wikipedia.org/wiki/Percent-encoding)
233 as query string, e.g. a space character becomes `%20`.
235 Example for a URL-encoded query string:
237 /v1/objects/hosts?filter=match(%22example.localdomain*%22,host.name)&attrs=name&attrs=state
239 Here are the exact same query parameters as a JSON object:
241 { "filter": "match(\"example.localdomain*\",host.name)", "attrs": [ "host.name", "host.state" ] }
243 The [match function](18-library-reference.md#global-functions-match) is available as global function
246 ### <a id="icinga2-api-requests-method-override"></a> Request Method Override
248 `GET` requests do not allow you to send a request body. In case you cannot pass everything as URL parameters (e.g. complex filters or JSON-encoded dictionaries) you can use the `X-HTTP-Method-Override` header. This comes in handy when you are using HTTP proxies disallowing `PUT` or `DELETE` requests too.
250 Query an existing object by sending a `POST` request with `X-HTTP-Method-Override: GET` as request header:
252 $ curl -k -s -u 'root:icinga' -H 'X-HTTP-Method-Override: GET' -X POST 'https://localhost:5665/v1/objects/hosts'
254 Delete an existing object by sending a `POST` request with `X-HTTP-Method-Override: DELETE` as request header:
256 $ curl -k -s -u 'root:icinga' -H 'X-HTTP-Method-Override: DELETE' -X POST 'https://localhost:5665/v1/objects/hosts/example.localdomain'
258 ### <a id="icinga2-api-filters"></a> Filters
260 #### <a id="icinga2-api-simple-filters"></a> Simple Filters
262 By default actions and queries operate on all objects unless further restricted by the user. For
263 example, the following query returns all `Host` objects:
265 https://localhost:5665/v1/objects/hosts
267 If you're only interested in a single object, you can limit the output to that object by specifying its name:
269 https://localhost:5665/v1/objects/hosts?host=localhost
271 **The name of the URL parameter is the lower-case version of the type the query applies to.** For
272 example, for `Host` objects the URL parameter therefore is `host`, for `Service` objects it is
275 You can also specify multiple objects:
277 https://localhost:5665/v1/objects/hosts?hosts=first-host&hosts=second-host
279 Again -- like in the previous example -- the name of the URL parameter is the lower-case version of the type. However, because we're specifying multiple objects here the **plural form** of the type is used.
281 When specifying names for objects which have composite names like for example services the
282 full name has to be used:
284 https://localhost:5665/v1/objects/services?service=localhost!ping6
286 The full name of an object can be obtained by looking at the `__name` attribute.
288 #### <a id="icinga2-api-advanced-filters"></a> Advanced Filters
290 Most of the information provided in this chapter applies to both permission filters (as used when
291 configuring `ApiUser` objects) and filters specified in queries.
293 Advanced filters allow users to filter objects using lambda expressions. The syntax for these filters is the same like for [apply rule expressions](3-monitoring-basics.md#using-apply-expressions).
297 > Filters used as URL parameter must be URL-encoded. The following examples
298 > are **not URL-encoded** for better readability.
300 Example matching all services in NOT-OK state:
302 https://localhost:5665/v1/objects/services?filter=service.state!=ServiceOK
304 Example [matching](18-library-reference.md#global-functions-match) all hosts by a name string pattern:
306 https://localhost:5665/v1/objects/hosts?filter=match("example.localdomain*",host.name)
308 Example for all hosts which are in the host group `linux-servers`:
310 https://localhost:5665/v1/objects/hosts?filter="linux-servers" in host.groups
312 User-specified filters are run in a sandbox environment which ensures that filters cannot
313 modify Icinga's state, for example object attributes or global variables.
315 When querying objects of a specific type the filter expression is evaluated for each object
316 of that type. The object is made available to the filter expression as a variable whose name
317 is the lower-case version of the object's type name.
319 For example when querying objects of type `Host` the variable in the filter expression is named
320 `host`. Additionally related objects such as the host's check command are also made available
321 (e.g., via the `check_command` variable). The variable names are the exact same as for the `joins`
322 query parameter; see [object query joins](12-icinga2-api.md#icinga2-api-config-objects-query-joins)
325 The object is also made available via the `obj` variable. This makes it easier to build
326 filters which can be used for more than one object type (e.g., for permissions).
328 Some queries can be performed for more than just one object type. One example is the 'reschedule-check'
329 action which can be used for both hosts and services. When using advanced filters you will also have to specify the
330 type using the `type` parameter:
332 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/reschedule-check' \
333 -d '{ "type": "Service", "filter": "service.name==\"ping6\"" }' | python -m json.tool
335 When building filters you have to ensure that values such as
336 `"linux-servers"` are escaped properly according to the rules of the Icinga 2 configuration
339 To make using the API in scripts easier you can use the `filter_vars` attribute to specify
340 variables which should be made available to your filter expression. This way you don't have
341 to worry about escaping values:
343 $ curl -k -s -u 'root:icinga' -H 'X-HTTP-Method-Override: GET' -X POST 'https://localhost:5665/v1/objects/hosts' \
344 -d '{ "filter": "host.vars.os == os", "filter_vars": { "os": "Linux" } }'
346 We're using X-HTTP-Method-Override here because the HTTP specification does
347 not allow message bodies for GET requests.
349 The `filters_vars` attribute can only be used inside the request body, but not as
350 a URL parameter because there is no way to specify a dictionary in a URL.
352 ## <a id="icinga2-api-config-objects"></a> Config Objects
354 Provides methods to manage configuration objects:
356 * [creating objects](12-icinga2-api.md#icinga2-api-config-objects-create)
357 * [querying objects](12-icinga2-api.md#icinga2-api-config-objects-query)
358 * [modifying objects](12-icinga2-api.md#icinga2-api-config-objects-modify)
359 * [deleting objects](12-icinga2-api.md#icinga2-api-config-objects-delete)
361 ### <a id="icinga2-api-config-objects-cluster-sync"></a> API Objects and Cluster Config Sync
363 Newly created or updated objects can be synced throughout your
364 Icinga 2 cluster. Set the `zone` attribute to the zone this object
365 belongs to and let the API and cluster handle the rest.
367 Objects without a zone attribute are only synced in the same zone the Icinga instance belongs to.
371 > Cluster nodes must accept configuration for creating, modifying
372 > and deleting objects. Ensure that `accept_config` is set to `true`
373 > in the [ApiListener](9-object-types.md#objecttype-apilistener) object
376 If you add a new cluster instance, or reconnect an instance which has been offline
377 for a while, Icinga 2 takes care of the initial object sync for all objects
380 ### <a id="icinga2-api-config-objects-query"></a> Querying Objects
382 You can request information about configuration objects by sending
383 a `GET` query to the `/v1/objects/<type>` URL endpoint. `<type` has
384 to be replaced with the plural name of the object type you are interested
387 $ curl -k -s -u root:icinga 'https://localhost:5665/v1/objects/hosts'
389 A list of all available configuration types is available in the
390 [object types](9-object-types.md#object-types) chapter.
392 The following URL parameters are available:
394 Parameters | Type | Description
395 -----------|--------------|----------------------------
396 attrs | string array | **Optional.** Limits attributes in the output.
397 joins | string array | **Optional.** Join related object types and their attributes (`?joins=host` for the entire set, or selectively by `?joins=host.name`).
398 meta | string array | **Optional.** Enable meta information using `?meta=used_by` (references from other objects) and/or `?meta=location` (location information). Defaults to disabled.
400 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) may be provided.
402 Instead of using a filter you can optionally specify the object name in the
403 URL path when querying a single object. For objects with composite names
404 (e.g. services) the full name (e.g. `localhost!http`) must be specified:
406 $ curl -k -s -u root:icinga 'https://localhost:5665/v1/objects/services/localhost!http'
408 You can limit the output to specific attributes using the `attrs` URL parameter:
410 $ curl -k -s -u root:icinga 'https://localhost:5665/v1/objects/hosts/example.localdomain?attrs=name&attrs=address' | python -m json.tool
415 "name": "example.localdomain"
416 "address": "192.168.1.1"
420 "name": "example.localdomain",
426 #### <a id="icinga2-api-config-objects-query-result"></a> Object Queries Result
428 Each response entry in the results array contains the following attributes:
430 Attribute | Type | Description
431 -----------|------------|--------------
432 name | string | Full object name.
433 type | string | Object type.
434 attrs | dictionary | Object attributes (can be filtered using the URL parameter `attrs`).
435 joins | dictionary | [Joined object types](12-icinga2-api.md#icinga2-api-config-objects-query-joins) as key, attributes as nested dictionary. Disabled by default.
436 meta | dictionary | Contains `used_by` object references. Disabled by default, enable it using `?meta=used_by` as URL parameter.
438 #### <a id="icinga2-api-config-objects-query-joins"></a> Object Query Joins
440 Icinga 2 knows about object relations. For example it can optionally return
441 information about the host when querying service objects.
443 The following query retrieves all host attributes:
445 https://localhost:5665/v1/objects/services?joins=host
447 Instead of requesting all host attributes you can also limit the output to specific
450 https://localhost:5665/v1/objects/services?joins=host.name&joins=host.address
452 You can request that all available joins are returned in the result set by using
453 the `all_joins` query parameter.
455 https://localhost:5665/v1/objects/services?all_joins=1
459 > For performance reasons you should only request attributes which your application
462 The following joins are available:
464 Object Type | Object Relations (`joins` prefix name)
465 -------------|------------------------------------------
466 Service | host, check\_command, check\_period, event\_command, command\_endpoint
467 Host | check\_command, check\_period, event\_command, command\_endpoint
468 Notification | host, service, command, period
469 Dependency | child\_host, child\_service, parent\_host, parent\_service, period
473 Here's an example that retrieves all service objects for hosts which have had their `os`
474 custom attribute set to `Linux`. The result set contains the `display_name` and `check_command`
475 attributes for the service. The query also returns the host's `name` and `address` attribute
478 $ curl -k -s -u root:icinga 'https://localhost:5665/v1/objects/services?attrs=display_name&attrs=check_command&joins=host.name&joins=host.address&filter=host.vars.os==%22Linux%22' | python -m json.tool
484 "check_command": "ping4",
485 "display_name": "ping4"
489 "address": "192.168.1.1",
490 "name": "example.localdomain"
494 "name": "example.localdomain!ping4",
499 "check_command": "ssh",
500 "display_name": "ssh"
504 "address": "192.168.1.1",
505 "name": "example.localdomain"
509 "name": "example.localdomain!ssh",
515 In case you want to fetch all [comments](9-object-types.md#objecttype-comment)
516 for hosts and services, you can use the following query URL (similar example
519 https://localhost:5665/v1/objects/comments?joins=host&joins=service
521 This is another example for listing all service objects which are unhandled problems (state is not OK
522 and no downtime or acknowledgement set):
524 $ curl -k -s -u root:icinga -H 'X-HTTP-Method-Override: GET' -X POST 'https://127.0.0.1:5665/v1/objects/services' \
525 -d '{ "joins": [ "host.name", "host.address" ], "attrs": [ "name", "state", "downtime_depth", "acknowledgement" ], "filter": "service.state != ServiceOK && service.downtime_depth == 0.0 && service.acknowledgement == 0.0" }' | python -m json.tool
531 "acknowledgement": 0.0,
532 "downtime_depth": 0.0,
533 "name": "10807-service",
543 "name": "10807-host!10807-service",
550 ### <a id="icinga2-api-config-objects-create"></a> Creating Config Objects
552 New objects must be created by sending a PUT request. The following
553 parameters need to be passed inside the JSON body:
555 Parameters | Type | Description
556 -----------|--------------|--------------------------
557 templates | string array | **Optional.** Import existing configuration templates for this object type. Note: These templates must either be statically configured or provided in [config packages](12-icinga2-api.md#icinga2-api-config-management)-
558 attrs | dictionary | **Required.** Set specific object attributes for this [object type](9-object-types.md#object-types).
560 The object name must be specified as part of the URL path. For objects with composite names (e.g. services)
561 the full name (e.g. `localhost!http`) must be specified.
563 If attributes are of the Dictionary type, you can also use the indexer format. This might be necessary to only override specific custom variables and keep all other existing custom variables (e.g. from templates):
565 "attrs": { "vars.os": "Linux" }
567 Example for creating the new host object `example.localdomain`:
569 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X PUT 'https://localhost:5665/v1/objects/hosts/example.localdomain' \
570 -d '{ "templates": [ "generic-host" ], "attrs": { "address": "192.168.1.1", "check_command": "hostalive", "vars.os" : "Linux" } }' \
571 | python -m json.tool
576 "status": "Object was created."
581 If the configuration validation fails, the new object will not be created and the response body
582 contains a detailed error message. The following example is missing the `check_command` attribute
583 which is required for host objects:
585 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X PUT 'https://localhost:5665/v1/objects/hosts/example.localdomain' \
586 -d '{ "attrs": { "address": "192.168.1.1", "vars.os" : "Linux" } }' \
587 | python -m json.tool
593 "Error: Validation failed for object 'example.localdomain' of type 'Host'; Attribute 'check_command': Attribute must not be empty."
595 "status": "Object could not be created."
600 Service objects must be created using their full name ("hostname!servicename") referencing an existing host object:
602 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X PUT 'https://localhost:5665/v1/objects/services/localhost!realtime-load' \
603 -d '{ "templates": [ "generic-service" ], "attrs": { "check_command": "load", "check_interval": 1,"retry_interval": 1 } }'
606 Example for a new CheckCommand object:
608 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X PUT 'https://localhost:5665/v1/objects/checkcommands/mytest' \
609 -d '{ "templates": [ "plugin-check-command" ], "attrs": { "command": [ "/usr/local/sbin/check_http" ], "arguments": { "-I": "$mytest_iparam$" } } }'
612 ### <a id="icinga2-api-config-objects-modify"></a> Modifying Objects
614 Existing objects must be modified by sending a `POST` request. The following
615 parameters need to be passed inside the JSON body:
617 Parameters | Type | Description
618 -----------|------------|---------------------------
619 attrs | dictionary | **Required.** Set specific object attributes for this [object type](9-object-types.md#object-types).
621 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) should be provided.
623 **Note**: Modified attributes do not trigger a re-evaluation of existing
624 static [apply rules](3-monitoring-basics.md#using-apply) and [group assignments](3-monitoring-basics.md#group-assign-intro).
625 Delete and re-create the objects if you require such changes.
626 Furthermore you cannot modify templates which have already been resolved
627 during [object creation](12-icinga2-api.md#icinga2-api-config-objects-create).
630 If attributes are of the Dictionary type, you can also use the indexer format:
632 "attrs": { "vars.os": "Linux" }
634 The following example updates the `address` attribute and the custom attribute `os` for the `example.localdomain` host:
636 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/objects/hosts/example.localdomain' \
637 -d '{ "attrs": { "address": "192.168.1.2", "vars.os" : "Windows" } }' \
638 | python -m json.tool
643 "name": "example.localdomain",
644 "status": "Attributes updated.",
651 ### <a id="icinga2-api-config-objects-delete"></a> Deleting Objects
653 You can delete objects created using the API by sending a `DELETE`
656 Parameters | Type | Description
657 -----------|---------|---------------
658 cascade | boolean | **Optional.** Delete objects depending on the deleted objects (e.g. services on a host).
660 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) should be provided.
662 Example for deleting the host object `example.localdomain`:
664 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X DELETE 'https://localhost:5665/v1/objects/hosts/example.localdomain?cascade=1' | python -m json.tool
669 "name": "example.localdomain",
670 "status": "Object was deleted.",
676 ## <a id="icinga2-api-config-templates"></a> Config Templates
678 Provides methods to manage configuration templates:
680 * [querying templates](12-icinga2-api.md#icinga2-api-config-templates-query)
682 Creation, modification and deletion of templates at runtime is not supported.
684 ### <a id="icinga2-api-config-templates-query"></a> Querying Templates
686 You can request information about configuration templates by sending
687 a `GET` query to the `/v1/templates/<type>` URL endpoint. `<type` has
688 to be replaced with the plural name of the object type you are interested
691 $ curl -k -s -u root:icinga 'https://localhost:5665/v1/templates/hosts'
693 A list of all available configuration types is available in the
694 [object types](9-object-types.md#object-types) chapter.
696 A [filter](12-icinga2-api.md#icinga2-api-filters) may be provided for this query type. The
697 template object can be accessed in the filter using the `tmpl` variable. In this
698 example the [match function](18-library-reference.md#global-functions-match) is used to
699 check a wildcard string pattern against `tmpl.name`:
701 $ curl -k -s -u root:icinga 'https://localhost:5661/v1/templates/hosts' -H "Accept: application/json" -X PUT -H "X-HTTP-Method-Override: GET" \
702 -d '{ "filter": "match(\"g*\", tmpl.name)" }'
704 Instead of using a filter you can optionally specify the template name in the
705 URL path when querying a single object:
707 $ curl -k -s -u root:icinga 'https://localhost:5665/v1/templates/hosts/generic-host'
709 The result set contains the type, name as well as the location of the template.
711 ## <a id="icinga2-api-variables"></a> Variables
713 Provides methods to manage global variables:
715 * [querying variables](12-icinga2-api.md#icinga2-api-variables-query)
717 ### <a id="icinga2-api-variables-query"></a> Querying Variables
719 You can request information about global variables by sending
720 a `GET` query to the `/v1/variables/` URL endpoint:
722 $ curl -k -s -u root:icinga 'https://localhost:5665/v1/variables'
724 A [filter](12-icinga2-api.md#icinga2-api-filters) may be provided for this query type. The
725 variable information object can be accessed in the filter using the `variable` variable:
727 $ curl -u root:root -k 'https://localhost:5661/v1/variables' -H "Accept: application/json" -X PUT -H "X-HTTP-Method-Override: GET" \
728 -d '{ "filter": "variable.type in [ \"String\", \"Number\" ]" }'
730 Instead of using a filter you can optionally specify the variable name in the
731 URL path when querying a single variable:
733 $ curl -k -s -u root:icinga 'https://localhost:5665/v1/variables/PrefixDir'
735 The result set contains the type, name and value of the global variable.
737 ## <a id="icinga2-api-actions"></a> Actions
739 There are several actions available for Icinga 2 provided by the `/v1/actions`
740 URL endpoint. You can run actions by sending a `POST` request.
742 In case you have been using the [external commands](14-features.md#external-commands)
743 in the past, the API actions provide a similar interface with filter
744 capabilities for some of the more common targets which do not directly change
747 All actions return a 200 `OK` or an appropriate error code for each
748 action performed on each object matching the supplied filter.
750 Actions which affect the Icinga Application itself such as disabling
751 notification on a program-wide basis must be applied by updating the
752 [IcingaApplication object](12-icinga2-api.md#icinga2-api-config-objects)
755 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/objects/icingaapplications/app' -d '{ "attrs": { "enable_notifications": false } }'
757 ### <a id="icinga2-api-actions-process-check-result"></a> process-check-result
759 Process a check result for a host or a service.
761 Send a `POST` request to the URL endpoint `/v1/actions/process-check-result`.
763 Parameter | Type | Description
764 ------------------|--------------|--------------
765 exit\_status | integer | **Required.** For services: 0=OK, 1=WARNING, 2=CRITICAL, 3=UNKNOWN, for hosts: 0=OK, 1=CRITICAL.
766 plugin\_output | string | **Required.** The plugins main output. Does **not** contain the performance data.
767 performance\_data | string array | **Optional.** The performance data.
768 check\_command | string array | **Optional.** The first entry should be the check commands path, then one entry for each command line option followed by an entry for each of its argument.
769 check\_source | string | **Optional.** Usually the name of the `command_endpoint`
771 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
775 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/process-check-result?service=example.localdomain!passive-ping6' \
776 -d '{ "exit_status": 2, "plugin_output": "PING CRITICAL - Packet loss = 100%", "performance_data": [ "rta=5000.000000ms;3000.000000;5000.000000;0.000000", "pl=100%;80;100;0" ], "check_source": "example.localdomain" }' | python -m json.tool
782 "status": "Successfully processed check result for object 'localdomain!passive-ping6'."
787 ### <a id="icinga2-api-actions-reschedule-check"></a> reschedule-check
789 Reschedule a check for hosts and services. The check can be forced if required.
791 Send a `POST` request to the URL endpoint `/v1/actions/reschedule-check`.
793 Parameter | Type | Description
794 -------------|-----------|--------------
795 next\_check | timestamp | **Optional.** The next check will be run at this time. If omitted, the current time is used.
796 force\_check | boolean | **Optional.** Defaults to `false`. If enabled, the checks are executed regardless of time period restrictions and checks being disabled per object or on a global basis.
798 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
800 The example reschedules all services with the name "ping6" to immediately perform a check
801 (`next_check` default), ignoring any time periods or whether active checks are
802 allowed for the service (`force_check=true`).
804 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/reschedule-check' \
805 -d '{ "type": "Service", "filter": "service.name==\"ping6\"", "force_check": true }' | python -m json.tool
811 "status": "Successfully rescheduled check for object 'localhost!ping6'."
817 ### <a id="icinga2-api-actions-send-custom-notification"></a> send-custom-notification
819 Send a custom notification for hosts and services. This notification
820 type can be forced being sent to all users.
822 Send a `POST` request to the URL endpoint `/v1/actions/send-custom-notification`.
824 Parameter | Type | Description
825 ----------|---------|--------------
826 author | string | **Required.** Name of the author, may be empty.
827 comment | string | **Required.** Comment text, may be empty.
828 force | boolean | **Optional.** Default: false. If true, the notification is sent regardless of downtimes or whether notifications are enabled or not.
830 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
832 Example for a custom host notification announcing a global maintenance to
835 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/send-custom-notification' \
836 -d '{ "type": "Host", "author": "icingaadmin", "comment": "System is going down for maintenance", "force": true }' | python -m json.tool
842 "status": "Successfully sent custom notification for object 'host0'."
846 "status": "Successfully sent custom notification for object 'host1'."
850 ### <a id="icinga2-api-actions-delay-notification"></a> delay-notification
852 Delay notifications for a host or a service.
853 Note that this will only have an effect if the service stays in the same problem
854 state that it is currently in. If the service changes to another state, a new
855 notification may go out before the time you specify in the `timestamp` argument.
857 Send a `POST` request to the URL endpoint `/v1/actions/delay-notification`.
859 Parameter | Type | Description
860 ----------|-----------|--------------
861 timestamp | timestamp | **Required.** Delay notifications until this timestamp.
863 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
867 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/delay-notification' \
868 -d '{ "type": "Service", "timestamp": 1446389894 }' | python -m json.tool
874 "status": "Successfully delayed notifications for object 'host0!service0'."
878 "status": "Successfully delayed notifications for object 'host1!service1'."
882 ### <a id="icinga2-api-actions-acknowledge-problem"></a> acknowledge-problem
884 Allows you to acknowledge the current problem for hosts or services. By
885 acknowledging the current problem, future notifications (for the same state if `sticky` is set to `false`)
888 Send a `POST` request to the URL endpoint `/v1/actions/acknowledge-problem`.
890 Parameter | Type | Description
891 ----------|-----------|--------------
892 author | string | **Required.** Name of the author, may be empty.
893 comment | string | **Required.** Comment text, may be empty.
894 expiry | timestamp | **Optional.** If set, the acknowledgement will vanish after this timestamp.
895 sticky | boolean | **Optional.** If `true`, the default, the acknowledgement will remain until the service or host fully recovers.
896 notify | boolean | **Optional.** If `true`, a notification will be sent out to contacts to indicate this problem has been acknowledged. The default is false.
898 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
900 The following example acknowledges all services which are in a hard critical state and sends out
901 a notification for them:
903 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/acknowledge-problem?type=Service&filter=service.state==2&service.state_type=1' \
904 -d '{ "author": "icingaadmin", "comment": "Global outage. Working on it.", "notify": true }' | python -m json.tool
910 "status": "Successfully acknowledged problem for object 'example2.localdomain!ping4'."
914 "status": "Successfully acknowledged problem for object 'example.localdomain!ping4'."
919 ### <a id="icinga2-api-actions-remove-acknowledgement"></a> remove-acknowledgement
921 Removes the acknowledgements for services or hosts. Once the acknowledgement has
922 been removed notifications will be sent out again.
924 Send a `POST` request to the URL endpoint `/v1/actions/remove-acknowledgement`.
926 A [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
928 The example removes all service acknowledgements:
930 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-acknowledgement?type=Service' | python -m json.tool
936 "status": "Successfully removed acknowledgement for object 'host0!service0'."
940 "status": "Successfully removed acknowledgement for object 'example2.localdomain!aws-health'."
944 ### <a id="icinga2-api-actions-add-comment"></a> add-comment
946 Adds a `comment` from an `author` to services or hosts.
948 Send a `POST` request to the URL endpoint `/v1/actions/add-comment`.
950 Parameter | Type | Description
951 ----------|--------|--------------
952 author | string | **Required.** Name of the author, may be empty.
953 comment | string | **Required.** Comment text, may be empty.
955 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
957 The following example adds a comment for all `ping4` services:
959 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/add-comment?type=Service&filter=service.name==%22ping4%22' -d '{ "author": "icingaadmin", "comment": "Troubleticket #123456789 opened." }' | python -m json.tool
965 "name": "example.localdomain!ping4!example.localdomain-1446824161-0",
966 "status": "Successfully added comment 'example.localdomain!ping4!example.localdomain-1446824161-0' for object 'example.localdomain!ping4'."
971 "name": "example2.localdomain!ping4!example.localdomain-1446824161-1",
972 "status": "Successfully added comment 'example2.localdomain!ping4!example.localdomain-1446824161-1' for object 'example2.localdomain!ping4'."
977 ### <a id="icinga2-api-actions-remove-comment"></a> remove-comment
979 Remove the comment using its `name` attribute , returns `OK` if the
980 comment did not exist.
981 **Note**: This is **not** the legacy ID but the comment name returned by
982 Icinga 2 when [adding a comment](12-icinga2-api.md#icinga2-api-actions-add-comment).
984 Send a `POST` request to the URL endpoint `/v1/actions/remove-comment`.
986 A [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host`, `Service` and `Comment`.
988 Example for a simple filter using the `comment` URL parameter:
990 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-comment?comment=example2.localdomain!ping4!mbmif.local-1446986367-0' | python -m json.tool
995 "status": "Successfully removed comment 'example2.localdomain!ping4!mbmif.local-1446986367-0'."
1000 Example for removing all service comments using a service name filter for `ping4`:
1002 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-comment?filter=service.name==%22ping4%22&type=Service' | python -m json.tool
1007 "status": "Successfully removed all comments for object 'example2.localdomain!ping4'."
1011 "status": "Successfully removed all comments for object 'example.localdomain!ping4'."
1017 ### <a id="icinga2-api-actions-schedule-downtime"></a> schedule-downtime
1019 Schedule a downtime for hosts and services.
1021 Send a `POST` request to the URL endpoint `/v1/actions/schedule-downtime`.
1023 Parameter | Type | Description
1024 --------------|-----------|--------------
1025 author | string | **Required.** Name of the author.
1026 comment | string | **Required.** Comment text.
1027 start\_time | timestamp | **Required.** Timestamp marking the beginning of the downtime.
1028 end\_time | timestamp | **Required.** Timestamp marking the end of the downtime.
1029 duration | integer | **Required.** Duration of the downtime in seconds if `fixed` is set to false.
1030 fixed | boolean | **Optional.** Defaults to `true`. If true, the downtime is `fixed` otherwise `flexible`. See [downtimes](8-advanced-topics.md#downtimes) for more information.
1031 trigger\_name | string | **Optional.** Sets the trigger for a triggered downtime. See [downtimes](8-advanced-topics.md#downtimes) for more information on triggered downtimes.
1032 child\_options | integer | **Optional.** Schedule child downtimes. `0` does not do anything, `1` schedules child downtimes triggered by this downtime, `2` schedules non-triggered downtimes. Defaults to `0`.
1034 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
1038 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/schedule-downtime?type=Service&filter=service.name==%22ping4%22' -d '{ "start_time": 1446388806, "end_time": 1446389806, "duration": 1000, "author": "icingaadmin", "comment": "IPv4 network maintenance" }' | python -m json.tool
1044 "name": "example2.localdomain!ping4!example.localdomain-1446822004-0",
1045 "status": "Successfully scheduled downtime 'example2.localdomain!ping4!example.localdomain-1446822004-0' for object 'example2.localdomain!ping4'."
1050 "name": "example.localdomain!ping4!example.localdomain-1446822004-1",
1051 "status": "Successfully scheduled downtime 'example.localdomain!ping4!example.localdomain-1446822004-1' for object 'example.localdomain!ping4'."
1056 ### <a id="icinga2-api-actions-remove-downtime"></a> remove-downtime
1058 Remove the downtime using its `name` attribute , returns `OK` if the
1059 downtime did not exist.
1060 **Note**: This is **not** the legacy ID but the downtime name returned by
1061 Icinga 2 when [scheduling a downtime](12-icinga2-api.md#icinga2-api-actions-schedule-downtime).
1063 Send a `POST` request to the URL endpoint `/v1/actions/remove-downtime`.
1065 A [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host`, `Service` and `Downtime`.
1067 Example for a simple filter using the `downtime` URL parameter:
1069 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-downtime?downtime=example.localdomain!ping4!mbmif.local-1446979168-6' | python -m json.tool
1074 "status": "Successfully removed downtime 'example.localdomain!ping4!mbmif.local-1446979168-6'."
1079 Example for removing all host downtimes using a host name filter for `example.localdomain`:
1081 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-downtime?filter=host.name==%22example.localdomain%22&type=Host' | python -m json.tool
1086 "status": "Successfully removed all downtimes for object 'example.localdomain'."
1091 Example for removing a downtime from a host but not the services filtered by the author name. This example uses
1092 filter variables explained in the [advanced filters](12-icinga2-api.md#icinga2-api-advanced-filters) chapter.
1094 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-downtime' \
1097 "filter": "host.name == filterHost && !service && downtime.author == filterAuthor",
1099 "filterHost": "example.localdomain",
1100 "filterAuthor": "icingaadmin"
1102 }' | python -m json.tool
1108 "status": "Successfully removed downtime 'example.localdomain!mbmif.local-1463043129-3'."
1113 ### <a id="icinga2-api-actions-shutdown-process"></a> shutdown-process
1115 Shuts down Icinga2. May or may not return.
1117 Send a `POST` request to the URL endpoint `/v1/actions/shutdown-process`.
1119 This action does not support a target type or filter.
1123 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/shutdown-process' | python -m json.tool
1129 "status": "Shutting down Icinga 2."
1134 ### <a id="icinga2-api-actions-restart-process"></a> restart-process
1136 Restarts Icinga2. May or may not return.
1138 Send a `POST` request to the URL endpoint `/v1/actions/restart-process`.
1140 This action does not support a target type or filter.
1144 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/restart-process' | python -m json.tool
1150 "status": "Restarting Icinga 2."
1155 ### <a id="icinga2-api-actions-generate-ticket"></a> generate-ticket
1157 Generates a PKI ticket for [CSR auto-signing](6-distributed-monitoring.md#distributed-monitoring-setup-csr-auto-signing).
1158 This can be used in combination with satellite/client setups requesting this ticket number.
1160 Send a `POST` request to the URL endpoint `/v1/actions/generate-ticket`.
1162 Parameter | Type | Description
1163 --------------|-----------|--------------
1164 cn | string | **Required.** The host's common name for which the ticket should be geenerated.
1168 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/generate-ticket' \
1169 -d '{ "cn": "icinga2-client1.localdomain" }' | python -m json.tool
1174 "status": "Generated PKI ticket '4f75d2ecd253575fe9180938ebff7cbca262f96e' for common name 'icinga2-client1.localdomain'.",
1175 "ticket": "4f75d2ecd253575fe9180938ebff7cbca262f96e"
1181 ## <a id="icinga2-api-event-streams"></a> Event Streams
1183 You can subscribe to event streams by sending a `POST` request to the URL endpoint `/v1/events`.
1184 The following parameters need to be specified (either as URL parameters or in a JSON-encoded message body):
1186 Parameter | Type | Description
1187 -----------|--------------|-------------
1188 types | string array | **Required.** Event type(s). Multiple types as URL parameters are supported.
1189 queue | string | **Required.** Unique queue name. Multiple HTTP clients can use the same queue as long as they use the same event types and filter.
1190 filter | string | **Optional.** Filter for specific event attributes using [filter expressions](12-icinga2-api.md#icinga2-api-filters).
1192 ### <a id="icinga2-api-event-streams-types"></a> Event Stream Types
1194 The following event stream types are available:
1197 -----------------------|--------------
1198 CheckResult | Check results for hosts and services.
1199 StateChange | Host/service state changes.
1200 Notification | Notification events including notified users for hosts and services.
1201 AcknowledgementSet | Acknowledgement set on hosts and services.
1202 AcknowledgementCleared | Acknowledgement cleared on hosts and services.
1203 CommentAdded | Comment added for hosts and services.
1204 CommentRemoved | Comment removed for hosts and services.
1205 DowntimeAdded | Downtime added for hosts and services.
1206 DowntimeRemoved | Downtime removed for hosts and services.
1207 DowntimeStarted | Downtime started for hosts and services.
1208 DowntimeTriggered | Downtime triggered for hosts and services.
1210 Note: Each type requires [API permissions](12-icinga2-api.md#icinga2-api-permissions)
1213 Example for all downtime events:
1215 &types=DowntimeAdded&types=DowntimeRemoved&types=DowntimeTriggered
1218 ### <a id="icinga2-api-event-streams-filter"></a> Event Stream Filter
1220 Event streams can be filtered by attributes using the prefix `event.`.
1222 Example for the `CheckResult` type with the `exit_code` set to `2`:
1224 &types=CheckResult&filter=event.check_result.exit_status==2
1226 Example for the `CheckResult` type with the service [matching](18-library-reference.md#global-functions-match)
1227 the string pattern "random\*":
1229 &types=CheckResult&filter=match%28%22random*%22,event.service%29
1232 ### <a id="icinga2-api-event-streams-response"></a> Event Stream Response
1234 The event stream response is separated with new lines. The HTTP client
1235 must support long-polling and HTTP/1.1. HTTP/1.0 is not supported.
1239 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/events?queue=michi&types=CheckResult&filter=event.check_result.exit_status==2'
1241 {"check_result":{ ... },"host":"example.localdomain","service":"ping4","timestamp":1445421319.7226390839,"type":"CheckResult"}
1242 {"check_result":{ ... },"host":"example.localdomain","service":"ping4","timestamp":1445421324.7226390839,"type":"CheckResult"}
1243 {"check_result":{ ... },"host":"example.localdomain","service":"ping4","timestamp":1445421329.7226390839,"type":"CheckResult"}
1246 ## <a id="icinga2-api-status"></a> Status and Statistics
1248 Send a `GET` request to the URL endpoint `/v1/status` to retrieve status information and statistics for Icinga 2.
1252 $ curl -k -s -u root:icinga 'https://localhost:5665/v1/status' | python -m json.tool
1256 "name": "ApiListener",
1257 "perfdata": [ ... ],
1262 "name": "IcingaAplication",
1263 "perfdata": [ ... ],
1270 You can limit the output by specifying a status type in the URL, e.g. `IcingaApplication`:
1272 $ curl -k -s -u root:icinga 'https://localhost:5665/v1/status/IcingaApplication' | python -m json.tool
1278 "icingaapplication": {
1280 "enable_event_handlers": true,
1281 "enable_flapping": true,
1282 "enable_host_checks": true,
1283 "enable_notifications": true,
1284 "enable_perfdata": true,
1285 "enable_service_checks": true,
1286 "node_name": "example.localdomain",
1288 "program_start": 1443019345.093372,
1289 "version": "v2.3.0-573-g380a131"
1298 ## <a id="icinga2-api-config-management"></a> Configuration Management
1300 The main idea behind configuration management is to allow external applications
1301 creating configuration packages and stages based on configuration files and
1302 directory trees. This replaces any additional SSH connection and whatnot to
1303 dump configuration files to Icinga 2 directly.
1304 In case you are pushing a new configuration stage to a package, Icinga 2 will
1305 validate the configuration asynchronously and populate a status log which
1306 can be fetched in a separated request.
1309 ### <a id="icinga2-api-config-management-create-package"></a> Creating a Config Package
1311 Send a `POST` request to a new config package called `example-cmdb` in this example. This
1312 will create a new empty configuration package.
1314 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST \
1315 'https://localhost:5665/v1/config/packages/example-cmdb' | python -m json.tool
1320 "package": "example-cmdb",
1321 "status": "Created package."
1326 Package names starting with an underscore are reserved for internal packages and must not be used.
1328 ### <a id="icinga2-api-config-management-create-config-stage"></a> Uploading configuration for a Config Package
1330 Configuration files in packages are managed in stages.
1331 Stages provide a way to maintain multiple configuration versions for a package.
1333 Send a `POST` request to the URL endpoint `/v1/config/stages` and add the name of an existing
1334 configuration package to the URL path (e.g. `example-cmdb`).
1335 The request body must contain the `files` attribute with the value being
1336 a dictionary of file targets and their content.
1338 The file path requires one of these two directories inside its path:
1340 Directory | Description
1341 ------------|------------------------------------
1342 conf.d | Local configuration directory.
1343 zones.d | Configuration directory for cluster zones, each zone must be put into its own zone directory underneath. Supports the [cluster config sync](6-distributed-monitoring.md#distributed-monitoring-top-down-config-sync).
1345 Example for a local configuration in the `conf.d` directory:
1347 "files": { "conf.d/host1.conf": "object Host \"local-host\" { address = \"127.0.0.1\", check_command = \"hostalive\" }" }
1349 Example for a host configuration inside the `satellite` zone in the `zones.d` directory:
1351 "files": { "zones.d/satellite/host2.conf": "object Host \"satellite-host\" { address = \"192.168.1.100\", check_command = \"hostalive\" }" }
1354 The example below will create a new file called `test.conf` in the `conf.d`
1355 directory. Note: This example contains an error (`chec_command`). This is
1358 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST \
1359 -d '{ "files": { "conf.d/test.conf": "object Host \"cmdb-host\" { chec_command = \"dummy\" }" } }' \
1360 'https://localhost:5665/v1/config/stages/example-cmdb' | python -m json.tool
1365 "package": "example-cmdb",
1366 "stage": "example.localdomain-1441625839-0",
1367 "status": "Created stage."
1372 The Icinga 2 API returns the `package` name this stage was created for, and also
1373 generates a unique name for the `stage` attribute you'll need for later requests.
1375 Icinga 2 automatically restarts the daemon in order to activate the new config stage.
1376 If the validation for the new config stage failed, the old stage and its configuration objects
1381 > Old stages are not purged automatically. You can [remove stages](12-icinga2-api.md#icinga2-api-config-management-delete-config-stage) that are no longer in use.
1383 Icinga 2 will create the following files in the configuration package
1384 stage after configuration validation:
1387 ------------|--------------
1388 status | Contains the [configuration validation](11-cli-commands.md#config-validation) exit code (everything else than 0 indicates an error).
1389 startup.log | Contains the [configuration validation](11-cli-commands.md#config-validation) output.
1391 You can [fetch these files](12-icinga2-api.md#icinga2-api-config-management-fetch-config-package-stage-files)
1392 in order to verify that the new configuration was deployed successfully.
1395 ### <a id="icinga2-api-config-management-list-config-packages"></a> List Configuration Packages and their Stages
1397 A list of packages and their stages can be retrieved by sending a `GET` request to the URL endpoint `/v1/config/packages`.
1399 The following example contains one configuration package `example-cmdb`. The package does not currently
1400 have an active stage.
1402 $ curl -k -s -u root:icinga 'https://localhost:5665/v1/config/packages' | python -m json.tool
1407 "name": "example-cmdb",
1409 "example.localdomain-1441625839-0"
1416 ### <a id="icinga2-api-config-management-list-config-package-stage-files"></a> List Configuration Packages and their Stages
1418 In order to retrieve a list of files for a stage you can send a `GET` request to
1419 the URL endpoint `/v1/config/stages`. You need to include
1420 the package name (`example-cmdb`) and stage name (`example.localdomain-1441625839-0`) in the URL:
1422 $ curl -k -s -u root:icinga 'https://localhost:5665/v1/config/stages/example-cmdb/example.localdomain-1441625839-0' | python -m json.tool
1427 "name": "startup.log",
1443 "name": "conf.d/test.conf",
1449 ### <a id="icinga2-api-config-management-fetch-config-package-stage-files"></a> Fetch Configuration Package Stage Files
1451 Send a `GET` request to the URL endpoint `/v1/config/files` and add
1452 the package name, the stage name and the relative path to the file to the URL path.
1456 > The returned files are plain-text instead of JSON-encoded.
1458 The following example fetches the configuration file `conf.d/test.conf`:
1460 $ curl -k -s -u root:icinga 'https://localhost:5665/v1/config/files/example-cmdb/example.localdomain-1441625839-0/conf.d/test.conf'
1462 object Host "cmdb-host" { chec_command = "dummy" }
1464 You can fetch a [list of existing files](12-icinga2-api.md#icinga2-api-config-management-list-config-package-stage-files)
1465 in a configuration stage and then specifically request their content.
1467 ### <a id="icinga2-api-config-management-config-package-stage-errors"></a> Configuration Package Stage Errors
1469 Now that we don't have an active stage for `example-cmdb` yet seen [here](12-icinga2-api.md#icinga2-api-config-management-list-config-packages),
1470 there must have been an error.
1472 In order to check for validation errors you can fetch the `startup.log` file
1473 by sending a `GET` request to the URL endpoint `/v1/config/files`. You must include
1474 the package name, stage name and the `startup.log` in the URL path.
1476 $ curl -k -s -u root:icinga 'https://localhost:5665/v1/config/files/example-cmdb/example.localdomain-1441133065-1/startup.log'
1479 critical/config: Error: Attribute 'chec_command' does not exist.
1481 /var/lib/icinga2/api/packages/example-cmdb/example.localdomain-1441133065-1/conf.d/test.conf(1): object Host "cmdb-host" { chec_command = "dummy" }
1482 ^^^^^^^^^^^^^^^^^^^^^^
1484 critical/config: 1 error
1486 The output is similar to the manual [configuration validation](11-cli-commands.md#config-validation).
1490 > The returned output is plain-text instead of JSON-encoded.
1493 ### <a id="icinga2-api-config-management-delete-config-stage"></a> Deleting Configuration Package Stage
1495 You can send a `DELETE` request to the URL endpoint `/v1/config/stages`
1496 in order to purge a configuration stage. You must include the package and
1497 stage name inside the URL path.
1499 The following example removes the failed configuration stage `example.localdomain-1441133065-1`
1500 in the `example-cmdb` configuration package:
1502 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X DELETE \
1503 'https://localhost:5665/v1/config/stages/example-cmdb/example.localdomain-1441133065-1' | python -m json.tool
1508 "status": "Stage deleted."
1514 ### <a id="icinga2-api-config-management-delete-config-package"></a> Deleting Configuration Package
1516 In order to completely purge a configuration package and its stages
1517 you can send a `DELETE` request to the URL endpoint `/v1/config/packages`
1518 with the package name in the URL path.
1520 This example entirely deletes the configuration package `example-cmdb`:
1522 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X DELETE \
1523 'https://localhost:5665/v1/config/packages/example-cmdb' | python -m json.tool
1528 "package": "example-cmdb",
1529 "status": "Deleted package."
1535 ## <a id="icinga2-api-types"></a> Types
1537 You can retrieve the configuration object types by sending a `GET` request to URL
1538 endpoint `/v1/types`.
1540 Each response entry in the results array contains the following attributes:
1542 Attribute | Type | Description
1543 ---------------|--------------|---------------------
1544 name | string | The type name.
1545 plural_name | string | The plural type name.
1546 fields | dictionary | Available fields including details on e.g. the type and attribute accessibility.
1547 abstract | boolean | Whether objects can be instantiated for this type.
1548 base | boolean | The base type (e.g. `Service` inherits fields and prototype methods from `Checkable`).
1549 prototype_keys | string array | Available prototype methods.
1551 In order to view a specific configuration object type specify its name inside the URL path:
1553 $ curl -k -s -u root:icinga 'https://localhost:5665/v1/types/Object' | python -m json.tool
1563 "navigation": false,
1564 "no_user_modify": false,
1565 "no_user_view": false,
1574 "plural_name": "Objects",
1585 ## <a id="icinga2-api-console"></a> Console
1587 You can inspect variables and execute other expressions by sending a `POST` request to the URL endpoint `/v1/console/execute-script`.
1588 In order to receive auto-completion suggestions, send a `POST` request to the URL endpoint `/v1/console/auto-complete-script`.
1590 The following parameters need to be specified (either as URL parameters or in a JSON-encoded message body):
1592 Parameter | Type | Description
1593 -----------|--------------|-------------
1594 session | string | **Optional.** The session ID. Ideally this should be a GUID or some other unique identifier.
1595 command | string | **Required.** Command expression for execution or auto-completion.
1596 sandboxed | number | **Optional.** Whether runtime changes are allowed or forbidden. Defaults to disabled.
1598 The [API permission](12-icinga2-api.md#icinga2-api-permissions) `console` is required for executing
1601 If you specify a session identifier, the same script context can be reused for multiple requests. This allows you to, for example, set a local variable in a request and use that local variable in another request. Sessions automatically expire after a set period of inactivity (currently 30 minutes).
1603 Example for fetching the command line from the local host's last check result:
1605 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/console/execute-script?command=get_host(NodeName).last_check_result.command&sandboxed=0&session=bb75fd7c-c686-407d-9688-582c04227756' | python -m json.tool
1611 "/usr/local/sbin/check_ping",
1619 "status": "Executed successfully."
1624 Example for fetching auto-completion suggestions for the `Host.` type. This works in a
1625 similar fashion when pressing TAB inside the [console CLI command](11-cli-commands.md#cli-command-console):
1627 $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/console/auto-complete-script?command=Host.&sandboxed=0&session=bb75fd7c-c686-407d-9688-582c04227756' | python -m json.tool
1632 "status": "Auto-completed successfully.",
1638 "Host.register_attribute_handler",
1640 "Host.notify_attribute",
1648 ## <a id="icinga2-api-clients"></a> API Clients
1650 There are a couple of existing clients which can be used with the Icinga 2 API:
1652 * [curl](http://curl.haxx.se) or any other HTTP client really
1653 * [Icinga 2 console (CLI command)](12-icinga2-api.md#icinga2-api-clients-cli-console)
1654 * [Icinga Studio](12-icinga2-api.md#icinga2-api-clients-icinga-studio)
1655 * [Icinga Web 2 Director](https://dev.icinga.org/projects/icingaweb2-modules)
1659 * [Dashing](https://github.com/Icinga/dashing-icinga2)
1660 * [API examples](https://github.com/Icinga/icinga2-api-examples)
1662 Additional [programmatic examples](12-icinga2-api.md#icinga2-api-clients-programmatic-examples)
1663 will help you getting started using the Icinga 2 API in your environment.
1665 ### <a id="icinga2-api-clients-icinga-studio"></a> Icinga Studio
1667 Icinga Studio is a graphical application to query configuration objects provided by the API.
1669 ![Icinga Studio Connection](images/icinga2-api/icinga2_api_icinga_studio_connect.png)
1671 ![Icinga Studio Overview](images/icinga2-api/icinga2_api_icinga_studio_overview.png)
1673 Please check the package repository of your distribution for available
1677 > Icinga Studio does not currently support SSL certificate verification.
1679 The Windows installer already includes Icinga Studio. On Debian and Ubuntu the package
1680 `icinga2-studio` can be used to install Icinga Studio.
1682 ### <a id="icinga2-api-clients-cli-console"></a> Icinga 2 Console
1684 By default the [console CLI command](11-cli-commands.md#cli-command-console) evaluates expressions in a local interpreter, i.e. independently from your Icinga 2 daemon. Using the `--connect` parameter you can use the Icinga 2 console to evaluate expressions via the API.
1686 ### <a id="icinga2-api-clients-programmatic-examples"></a> API Clients Programmatic Examples
1688 The programmatic examples use HTTP basic authentication and SSL certificate
1689 verification. The CA file is expected in `pki/icinga2-ca.crt`
1690 but you may adjust the examples for your likings.
1692 The request method is `POST` using `X-HTTP-Method-Override: GET`
1693 which allows you to send a JSON request body. The examples request
1694 specific service attributes joined with host attributes. `attrs`
1695 and `joins` are therefore specified as array.
1696 The `filter` attribute [matches](18-library-reference.md#global-functions-match)
1697 on all services with `ping` in their name.
1699 #### <a id="icinga2-api-clients-programmatic-examples-python"></a> Example API Client in Python
1701 The following example uses **Python** and the `requests` and `json` module:
1703 # pip install requests
1706 $ vim icinga2-api-example.py
1708 #!/usr/bin/env python
1710 import requests, json
1712 # Replace 'localhost' with your FQDN and certificate CN
1713 # for SSL verification
1714 request_url = "https://localhost:5665/v1/objects/services"
1716 'Accept': 'application/json',
1717 'X-HTTP-Method-Override': 'GET'
1720 "attrs": [ "name", "state", "last_check_result" ],
1721 "joins": [ "host.name", "host.state", "host.last_check_result" ],
1722 "filter": "match(\"ping*\", service.name)",
1725 r = requests.post(request_url,
1727 auth=('root', 'icinga'),
1728 data=json.dumps(data),
1729 verify="pki/icinga2-ca.crt")
1731 print "Request URL: " + str(r.url)
1732 print "Status code: " + str(r.status_code)
1734 if (r.status_code == 200):
1735 print "Result: " + json.dumps(r.json())
1738 r.raise_for_status()
1740 $ python icinga2-api-example.py
1743 #### <a id="icinga2-api-clients-programmatic-examples-ruby"></a> Example API Client in Ruby
1745 The following example uses **Ruby** and the `rest_client` gem:
1747 # gem install rest_client
1749 $ vim icinga2-api-example.rb
1753 require 'rest_client'
1755 # Replace 'localhost' with your FQDN and certificate CN
1756 # for SSL verification
1757 request_url = "https://localhost:5665/v1/objects/services"
1759 "Accept" => "application/json",
1760 "X-HTTP-Method-Override" => "GET"
1763 "attrs" => [ "name", "state", "last_check_result" ],
1764 "joins" => [ "host.name", "host.state", "host.last_check_result" ],
1765 "filter" => "match(\"ping*\", service.name)",
1768 r = RestClient::Resource.new(
1769 URI.encode(request_url),
1770 :headers => headers,
1772 :password => "icinga",
1773 :ssl_ca_file => "pki/icinga2-ca.crt")
1776 response = r.post(data.to_json)
1778 response = e.response
1781 puts "Status: " + response.code.to_s
1782 if response.code == 200
1783 puts "Result: " + (JSON.pretty_generate JSON.parse(response.body))
1785 puts "Error: " + response
1788 $ ruby icinga2-api-example.rb
1790 A more detailed example can be found in the [Dashing demo](https://github.com/Icinga/dashing-icinga2).
1792 #### <a id="icinga2-api-clients-programmatic-examples-php"></a> Example API Client in PHP
1794 The following example uses **PHP** and its `curl` library:
1796 $ vim icinga2-api-example.php
1800 # Replace 'localhost' with your FQDN and certificate CN
1801 # for SSL verification
1802 $request_url = "https://localhost:5665/v1/objects/services";
1804 $password = "icinga";
1806 'Accept: application/json',
1807 'X-HTTP-Method-Override: GET'
1810 attrs => array('name', 'state', 'last_check_result'),
1811 joins => array('host.name', 'host.state', 'host.last_check_result'),
1812 filter => 'match("ping*", service.name)',
1816 curl_setopt_array($ch, array(
1817 CURLOPT_URL => $request_url,
1818 CURLOPT_HTTPHEADER => $headers,
1819 CURLOPT_USERPWD => $username . ":" . $password,
1820 CURLOPT_RETURNTRANSFER => true,
1821 CURLOPT_CAINFO => "pki/icinga2-ca.crt",
1822 CURLOPT_POST => count($data),
1823 CURLOPT_POSTFIELDS => json_encode($data)
1826 $response = curl_exec($ch);
1827 if ($response === false) {
1828 print "Error: " . curl_error($ch) . "(" . $response . ")\n";
1831 $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
1833 print "Status: " . $code . "\n";
1836 $response = json_decode($response, true);
1841 $ php icinga2-api-example.php
1843 #### <a id="icinga2-api-clients-programmatic-examples-perl"></a> Example API Client in Perl
1845 The following example uses **Perl** and the `Rest::Client` module:
1847 # perl -MCPAN -e 'install REST::Client'
1848 # perl -MCPAN -e 'install JSON'
1849 # perl -MCPAN -e 'install MIME::Base64'
1850 # perl -MCPAN -e 'install Data::Dumper'
1852 $ vim icinga2-api-example.pl
1863 # Replace 'localhost' with your FQDN and certificate CN
1864 # for SSL verification
1865 my $request_host = "https://localhost:5665";
1866 my $userpass = "root:icinga";
1868 my $client = REST::Client->new();
1869 $client->setHost($request_host);
1870 $client->setCa("pki/icinga2-ca.crt");
1871 $client->addHeader("Accept", "application/json");
1872 $client->addHeader("X-HTTP-Method-Override", "GET");
1873 $client->addHeader("Authorization", "Basic " . encode_base64($userpass));
1875 attrs => ['name', 'state', 'last_check_result'],
1876 joins => ['host.name', 'host.state', 'host.last_check_result'],
1877 filter => 'match("ping*", service.name)',
1879 my $data = encode_json(\%json_data);
1880 $client->POST("/v1/objects/services", $data);
1882 my $status = $client->responseCode();
1883 print "Status: " . $status . "\n";
1884 my $response = $client->responseContent();
1885 if ($status == 200) {
1886 print "Result: " . Dumper(decode_json($response)) . "\n";
1888 print "Error: " . $response . "\n";
1891 $ perl icinga2-api-example.pl