]> granicus.if.org Git - icinga2/blob - doc/12-icinga2-api.md
Merge pull request #5958 from Icinga/feature/icinga-check-min-version
[icinga2] / doc / 12-icinga2-api.md
1 # Icinga 2 API <a id="icinga2-api"></a>
2
3 ## Setting up the API <a id="icinga2-api-setup"></a>
4
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:
9
10     # icinga2 api setup
11
12 Make sure to restart Icinga 2 to enable the changes you just made:
13
14     # service icinga2 restart
15
16 If you prefer to set up the API manually, you will have to perform the following steps:
17
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
21
22 The next chapter provides a quick overview of how you can use the API.
23
24 ## Introduction <a id="icinga2-api-introduction"></a>
25
26 The Icinga 2 API allows you to manage configuration objects
27 and resources in a simple, programmatic way using HTTP requests.
28
29 The URL endpoints are logically separated allowing you to easily
30 make calls to
31
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)
37
38 ### Requests <a id="icinga2-api-requests"></a>
39
40 Any tool capable of making HTTP requests can communicate with
41 the API, for example [curl](https://curl.haxx.se/).
42
43 Requests are only allowed to use the HTTPS protocol so that
44 traffic remains encrypted.
45
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](09-object-types.md#objecttype-apilistener)
49 object in the `/etc/icinga2/features-available/api.conf`
50 configuration file.
51
52 Supported request methods:
53
54   Method | Usage
55   -------|--------
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.
60
61 All requests apart from `GET` require that the following `Accept` header is set:
62
63     Accept: application/json
64
65 Each URL is prefixed with the API version (currently "/v1").
66
67 ### Responses <a id="icinga2-api-responses"></a>
68
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.
72
73 The output will be sent back as a JSON object:
74
75
76     {
77         "results": [
78             {
79                 "code": 200.0,
80                 "status": "Object was created."
81             }
82         ]
83     }
84
85 > **Tip**
86 >
87 > You can use the `pretty` parameter to beautify the JSON response with Icinga v2.9+.
88
89 You can also use [jq](https://stedolan.github.io/jq/) or `python -m json.tool`
90 in combination with curl on the CLI.
91
92 ```
93 curl ... | python -m json.tool
94 ```
95
96 > **Note**
97 >
98 > Future versions of Icinga 2 might set additional fields. Your application
99 > should gracefully handle fields it is not familiar with, for example by
100 > ignoring them.
101
102 ### HTTP Statuses <a id="icinga2-api-http-statuses"></a>
103
104 The API will return standard [HTTP statuses](https://www.ietf.org/rfc/rfc2616.txt)
105 including error codes.
106
107 When an error occurs, the response body will contain additional information
108 about the problem and its source.
109
110 A status code between 200 and 299 generally means that the request was
111 successful.
112
113 Return codes within the 400 range indicate that there was a problem with the
114 request. Either you did not authenticate correctly, you are missing the authorization
115 for your requested action, the requested object does not exist or the request
116 was malformed.
117
118 A status in the range of 500 generally means that there was a server-side problem
119 and Icinga 2 is unable to process your request.
120
121 ### Authentication <a id="icinga2-api-authentication"></a>
122
123 There are two different ways for authenticating against the Icinga 2 API:
124
125 * username and password using HTTP basic auth
126 * X.509 certificate
127
128 In order to configure a new API user you'll need to add a new [ApiUser](09-object-types.md#objecttype-apiuser)
129 configuration object. In this example `root` will be the basic auth username
130 and the `password` attribute contains the basic auth password.
131
132     # vim /etc/icinga2/conf.d/api-users.conf
133
134     object ApiUser "root" {
135       password = "icinga"
136     }
137
138 Alternatively you can use X.509 client certificates by specifying the `client_cn`
139 the API should trust. The X.509 certificate has to be signed by the CA certificate
140 that is configured in the [ApiListener](09-object-types.md#objecttype-apilistener) object.
141
142     # vim /etc/icinga2/conf.d/api-users.conf
143
144     object ApiUser "root" {
145       client_cn = "CertificateCommonName"
146     }
147
148 An `ApiUser` object can have both authentication methods configured.
149
150 You can test authentication by sending a GET request to the API:
151
152     $ curl -k -s -u root:icinga 'https://localhost:5665/v1'
153
154 In case you get an error message make sure to check the API user credentials.
155
156 When using client certificates for authentication you'll need to pass your client certificate
157 and private key to the curl call:
158
159     $ curl -k --cert example.localdomain.crt --key example.localdomain.key 'https://example.localdomain:5665/v1/status'
160
161 In case of an error make sure to verify the client certificate and CA.
162
163 The curl parameter `-k` disables certificate verification and should therefore
164 only be used for testing. In order to securely check each connection you'll need to
165 specify the trusted CA certificate using the curl parameter`--cacert`:
166
167     $ curl -u root:icinga --cacert ca.crt 'icinga2.node1.localdomain:5665/v1'
168
169 Read the next chapter on [API permissions](12-icinga2-api.md#icinga2-api-permissions)
170 in order to configure authorization settings for your newly created API user.
171
172 ### Permissions <a id="icinga2-api-permissions"></a>
173
174 By default an API user does not have any permissions to perform
175 actions on the URL endpoints.
176
177 Permissions for API users must be specified in the `permissions` attribute
178 as array. The array items can be a list of permission strings with wildcard
179 matches.
180
181 Example for an API user with all permissions:
182
183     permissions = [ "*" ]
184
185 Note that you can use wildcards. Here's another example that only allows the user
186 to perform read-only object queries for hosts and services:
187
188     permissions = [ "objects/query/Host", "objects/query/Service" ]
189
190 You can also further restrict permissions by specifying a filter expression. The
191 filter expression has to be a [lambda function](17-language-reference.md#nullary-lambdas)
192 which must return a boolean value.
193
194 The following example allows the API user to query all hosts and services which have a
195 custom attribute `os` that matches the regular expression `^Linux`.
196 The [regex function](18-library-reference.md#global-functions-regex) is available as global function.
197
198     permissions = [
199       {
200         permission = "objects/query/Host"
201         filter = {{ regex("^Linux", host.vars.os) }}
202       },
203       {
204         permission = "objects/query/Service"
205         filter = {{ regex("^Linux", service.vars.os) }}
206       }
207     ]
208
209 More information about filters can be found in the [filters](12-icinga2-api.md#icinga2-api-filters) chapter.
210
211 Available permissions for specific URL endpoints:
212
213   Permissions                   | URL Endpoint  | Supports Filters
214   ------------------------------|---------------|-----------------
215   actions/&lt;action&gt;        | /v1/actions   | Yes
216   config/query                  | /v1/config    | No
217   config/modify                 | /v1/config    | No
218   console                       | /v1/console   | No
219   events/&lt;type&gt;           | /v1/events    | No
220   objects/query/&lt;type&gt;    | /v1/objects   | Yes
221   objects/create/&lt;type&gt;   | /v1/objects   | No
222   objects/modify/&lt;type&gt;   | /v1/objects   | Yes
223   objects/delete/&lt;type&gt;   | /v1/objects   | Yes
224   status/query                  | /v1/status    | Yes
225   templates/&lt;type&gt;        | /v1/templates | Yes
226   types                         | /v1/types     | Yes
227   variables                     | /v1/variables | Yes
228
229 The required actions or types can be replaced by using a wildcard match ("\*").
230
231 ### Parameters <a id="icinga2-api-parameters"></a>
232
233 Depending on the request method there are two ways of
234 passing parameters to the request:
235
236 * JSON object as request body (all request methods other than `GET`)
237 * Query string as URL parameter (all request methods)
238
239 Reserved characters by the HTTP protocol must be [URL-encoded](https://en.wikipedia.org/wiki/Percent-encoding)
240 as query string, e.g. a space character becomes `%20`.
241
242 Example for a URL-encoded query string:
243
244     /v1/objects/hosts?filter=match(%22example.localdomain*%22,host.name)&attrs=name&attrs=state
245
246 Here are the exact same query parameters as a JSON object:
247
248     { "filter": "match(\"example.localdomain*\",host.name)", "attrs": [ "host.name", "host.state" ] }
249
250 The [match function](18-library-reference.md#global-functions-match) is available as global function
251 in Icinga 2.
252
253 ### Request Method Override <a id="icinga2-api-requests-method-override"></a>
254
255 `GET` requests do not allow you to send a request body. In case you cannot pass everything as URL
256 parameters (e.g. complex filters or JSON-encoded dictionaries) you can use the `X-HTTP-Method-Override`
257 header. This comes in handy when you are using HTTP proxies disallowing `PUT` or `DELETE` requests too.
258
259 Query an existing object by sending a `POST` request with `X-HTTP-Method-Override: GET` as request header:
260
261     $ curl -k -s -u 'root:icinga' -H 'Accept: application/json' -X POST -H 'X-HTTP-Method-Override: GET' 'https://localhost:5665/v1/objects/hosts'
262
263 Delete an existing object by sending a `POST` request with `X-HTTP-Method-Override: DELETE` as request header:
264
265     $ curl -k -s -u 'root:icinga' -H 'Accept: application/json' -X POST -H 'X-HTTP-Method-Override: DELETE' 'https://localhost:5665/v1/objects/hosts/example.localdomain'
266
267 ### Filters <a id="icinga2-api-filters"></a>
268
269 #### Simple Filters <a id="icinga2-api-simple-filters"></a>
270
271 By default actions and queries operate on all objects unless further restricted by the user. For
272 example, the following query returns all `Host` objects:
273
274     https://localhost:5665/v1/objects/hosts
275
276 If you're only interested in a single object, you can limit the output to that object by specifying its name:
277
278     https://localhost:5665/v1/objects/hosts?host=localhost
279
280 **The name of the URL parameter is the lower-case version of the type the query applies to.** For
281 example, for `Host` objects the URL parameter therefore is `host`, for `Service` objects it is
282 `service` and so on.
283
284 You can also specify multiple objects:
285
286     https://localhost:5665/v1/objects/hosts?hosts=first-host&hosts=second-host
287
288 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.
289
290 When specifying names for objects which have composite names like for example services the
291 full name has to be used:
292
293     https://localhost:5665/v1/objects/services?service=localhost!ping6
294
295 The full name of an object can be obtained by looking at the `__name` attribute.
296
297 #### Advanced Filters <a id="icinga2-api-advanced-filters"></a>
298
299 Most of the information provided in this chapter applies to both permission filters (as used when
300 configuring `ApiUser` objects) and filters specified in queries.
301
302 Advanced filters allow users to filter objects using lambda expressions. The syntax for these filters is the same like for [apply rule expressions](03-monitoring-basics.md#using-apply-expressions).
303
304 > **Note**
305 >
306 > Filters used as URL parameter must be URL-encoded. The following examples
307 > are **not URL-encoded** for better readability.
308
309 Example matching all services in NOT-OK state:
310
311     https://localhost:5665/v1/objects/services?filter=service.state!=ServiceOK
312
313 Example [matching](18-library-reference.md#global-functions-match) all hosts by a name string pattern:
314
315     https://localhost:5665/v1/objects/hosts?filter=match("example.localdomain*",host.name)
316
317 Example for all hosts which are in the host group `linux-servers`:
318
319     https://localhost:5665/v1/objects/hosts?filter="linux-servers" in host.groups
320
321 User-specified filters are run in a sandbox environment which ensures that filters cannot
322 modify Icinga's state, for example object attributes or global variables.
323
324 When querying objects of a specific type the filter expression is evaluated for each object
325 of that type. The object is made available to the filter expression as a variable whose name
326 is the lower-case version of the object's type name.
327
328 For example when querying objects of type `Host` the variable in the filter expression is named
329 `host`. Additionally related objects such as the host's check command are also made available
330 (e.g., via the `check_command` variable). The variable names are the exact same as for the `joins`
331 query parameter; see [object query joins](12-icinga2-api.md#icinga2-api-config-objects-query-joins)
332 for details.
333
334 The object is also made available via the `obj` variable. This makes it easier to build
335 filters which can be used for more than one object type (e.g., for permissions).
336
337 Some queries can be performed for more than just one object type. One example is the 'reschedule-check'
338 action which can be used for both hosts and services. When using advanced filters you will also have to specify the
339 type using the `type` parameter:
340
341     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/reschedule-check' \
342     -d '{ "type": "Service", "filter": "service.name==\"ping6\"", "pretty": true }'
343
344 When building filters you have to ensure that values such as
345 `"linux-servers"` are escaped properly according to the rules of the Icinga 2 configuration
346 language.
347
348 To make using the API in scripts easier you can use the `filter_vars` attribute to specify
349 variables which should be made available to your filter expression. This way you don't have
350 to worry about escaping values:
351
352     $ curl -k -s -u 'root:icinga' -H 'Accept: application/json' -H 'X-HTTP-Method-Override: GET' -X POST 'https://localhost:5665/v1/objects/hosts' \
353     -d '{ "filter": "host.vars.os == os", "filter_vars": { "os": "Linux" }, "pretty": true }'
354
355 We're using [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override) here because
356 the HTTP specification does not allow message bodies for GET requests.
357
358 The `filters_vars` attribute can only be used inside the request body, but not as
359 a URL parameter because there is no way to specify a dictionary in a URL.
360
361 ## Config Objects <a id="icinga2-api-config-objects"></a>
362
363 Provides methods to manage configuration objects:
364
365 * [creating objects](12-icinga2-api.md#icinga2-api-config-objects-create)
366 * [querying objects](12-icinga2-api.md#icinga2-api-config-objects-query)
367 * [modifying objects](12-icinga2-api.md#icinga2-api-config-objects-modify)
368 * [deleting objects](12-icinga2-api.md#icinga2-api-config-objects-delete)
369
370 ### API Objects and Cluster Config Sync <a id="icinga2-api-config-objects-cluster-sync"></a>
371
372 Newly created or updated objects can be synced throughout your
373 Icinga 2 cluster. Set the `zone` attribute to the zone this object
374 belongs to and let the API and cluster handle the rest.
375
376 Objects without a zone attribute are only synced in the same zone the Icinga instance belongs to.
377
378 > **Note**
379 >
380 > Cluster nodes must accept configuration for creating, modifying
381 > and deleting objects. Ensure that `accept_config` is set to `true`
382 > in the [ApiListener](09-object-types.md#objecttype-apilistener) object
383 > on each node.
384
385 If you add a new cluster instance, or reconnect an instance which has been offline
386 for a while, Icinga 2 takes care of the initial object sync for all objects
387 created by the API.
388
389 ### Querying Objects <a id="icinga2-api-config-objects-query"></a>
390
391 You can request information about configuration objects by sending
392 a `GET` query to the `/v1/objects/<type>` URL endpoint. `<type` has
393 to be replaced with the plural name of the object type you are interested
394 in:
395
396     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/objects/hosts'
397
398 A list of all available configuration types is available in the
399 [object types](09-object-types.md#object-types) chapter.
400
401 The following URL parameters are available:
402
403   Parameters | Type         | Description
404   -----------|--------------|----------------------------
405   attrs      | Array        | **Optional.** Limited attribute list in the output.
406   joins      | Array        | **Optional.** Join related object types and their attributes specified as list (`?joins=host` for the entire set, or selectively by `?joins=host.name`).
407   meta       | Array        | **Optional.** Enable meta information using `?meta=used_by` (references from other objects) and/or `?meta=location` (location information) specified as list. Defaults to disabled.
408
409 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) may be provided.
410
411 Instead of using a filter you can optionally specify the object name in the
412 URL path when querying a single object. For objects with composite names
413 (e.g. services) the full name (e.g. `example.localdomain!http`) must be specified:
414
415     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/objects/services/example.localdomain!http'
416
417 You can limit the output to specific attributes using the `attrs` URL parameter:
418
419     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/objects/hosts/example.localdomain?attrs=name&attrs=address&pretty=1'
420     {
421         "results": [
422             {
423                 "attrs": {
424                     "name": "example.localdomain"
425                     "address": "192.168.1.1"
426                 },
427                 "joins": {},
428                 "meta": {},
429                 "name": "example.localdomain",
430                 "type": "Host"
431             }
432         ]
433     }
434
435 #### Object Queries Result <a id="icinga2-api-config-objects-query-result"></a>
436
437 Each response entry in the results array contains the following attributes:
438
439   Attribute  | Type       | Description
440   -----------|------------|--------------
441   name       | String     | Full object name.
442   type       | String     | Object type.
443   attrs      | Dictionary | Object attributes (can be filtered using the URL parameter `attrs`).
444   joins      | Dictionary | [Joined object types](12-icinga2-api.md#icinga2-api-config-objects-query-joins) as key, attributes as nested dictionary. Disabled by default.
445   meta       | Dictionary | Contains `used_by` object references. Disabled by default, enable it using `?meta=used_by` as URL parameter.
446
447 #### Object Query Joins <a id="icinga2-api-config-objects-query-joins"></a>
448
449 Icinga 2 knows about object relations. For example it can optionally return
450 information about the host when querying service objects.
451
452 The following query retrieves all host attributes:
453
454     https://localhost:5665/v1/objects/services?joins=host
455
456 Instead of requesting all host attributes you can also limit the output to specific
457 attributes:
458
459     https://localhost:5665/v1/objects/services?joins=host.name&joins=host.address
460
461 You can request that all available joins are returned in the result set by using
462 the `all_joins` query parameter.
463
464     https://localhost:5665/v1/objects/services?all_joins=1
465
466 > **Note**
467 >
468 > For performance reasons you should only request attributes which your application
469 > requires.
470
471 The following joins are available:
472
473   Object Type  | Object Relations (`joins` prefix name)
474   -------------|------------------------------------------
475   Service      | host, check\_command, check\_period, event\_command, command\_endpoint
476   Host         | check\_command, check\_period, event\_command, command\_endpoint
477   Notification | host, service, command, period
478   Dependency   | child\_host, child\_service, parent\_host, parent\_service, period
479   User         | period
480   Zones        | parent
481
482 Here's an example that retrieves all service objects for hosts which have had their `os`
483 custom attribute set to `Linux`. The result set contains the `display_name` and `check_command`
484 attributes for the service. The query also returns the host's `name` and `address` attribute
485 via a join:
486
487     $ 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&pretty=1'
488
489     {
490         "results": [
491             {
492                 "attrs": {
493                     "check_command": "ping4",
494                     "display_name": "ping4"
495                 },
496                 "joins": {
497                     "host": {
498                         "address": "192.168.1.1",
499                         "name": "example.localdomain"
500                     }
501                 },
502                 "meta": {},
503                 "name": "example.localdomain!ping4",
504                 "type": "Service"
505             },
506             {
507                 "attrs": {
508                     "check_command": "ssh",
509                     "display_name": "ssh"
510                 },
511                 "joins": {
512                     "host": {
513                         "address": "192.168.1.1",
514                         "name": "example.localdomain"
515                     }
516                 },
517                 "meta": {},
518                 "name": "example.localdomain!ssh",
519                 "type": "Service"
520             }
521         ]
522     }
523
524 In case you want to fetch all [comments](09-object-types.md#objecttype-comment)
525 for hosts and services, you can use the following query URL (similar example
526 for downtimes):
527
528     https://localhost:5665/v1/objects/comments?joins=host&joins=service
529
530 This is another example for listing all service objects which are unhandled problems (state is not OK
531 and no downtime or acknowledgement set). We're using [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override)
532 here because we want to pass all query attributes in the request body.
533
534     $ curl -k -s -u root:icinga -H 'Accept: application/json' -H 'X-HTTP-Method-Override: GET' -X POST 'https://127.0.0.1:5665/v1/objects/services' \
535     -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", "pretty": true }'
536
537     {
538         "results": [
539             {
540                 "attrs": {
541                     "acknowledgement": 0.0,
542                     "downtime_depth": 0.0,
543                     "name": "10807-service",
544                     "state": 3.0
545                 },
546                 "joins": {
547                     "host": {
548                         "address": "",
549                         "name": "10807-host"
550                     }
551                 },
552                 "meta": {},
553                 "name": "10807-host!10807-service",
554                 "type": "Service"
555             }
556         ]
557     }
558
559 In order to list all acknowledgements without expire time, you query the `/v1/objects/comments`
560 URL endpoint with `joins` and `filter` request parameters using the [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override)
561 method:
562
563     $ curl -k -s -u root:icinga -H 'Accept: application/json' -H 'X-HTTP-Method-Override: GET' -X POST 'https://localhost:5665/v1/objects/comments' \
564     -d '{ "joins": [ "service.name", "service.acknowledgement", "service.acknowledgement_expiry" ], "attrs": [ "author", "text" ], "filter": "service.acknowledgement!=0 && service.acknowledgement_expiry==0", "pretty": true }'
565
566     {
567         "results": [
568             {
569                 "attrs": {
570                     "author": "icingaadmin",
571                     "text": "maintenance work"
572                 },
573                 "joins": {
574                     "service": {
575                         "__name": "example.localdomain!disk /",
576                         "acknowledgement": 1.0,
577                         "acknowledgement_expiry": 0.0
578                     }
579                 },
580                 "meta": {},
581                 "name": "example.localdomain!disk /!example.localdomain-1495457222-0",
582                 "type": "Comment"
583             }
584         ]
585     }
586
587 ### Creating Config Objects <a id="icinga2-api-config-objects-create"></a>
588
589 New objects must be created by sending a PUT request. The following
590 parameters need to be passed inside the JSON body:
591
592   Parameters | Type         | Description
593   -----------|--------------|--------------------------
594   templates  | 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)-
595   attrs      | Dictionary   | **Required.** Set specific object attributes for this [object type](09-object-types.md#object-types).
596
597 The object name must be specified as part of the URL path. For objects with composite names (e.g. services)
598 the full name (e.g. `example.localdomain!http`) must be specified.
599
600 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):
601
602     "attrs": { "vars.os": "Linux" }
603
604 Example for creating the new host object `example.localdomain`:
605
606     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X PUT 'https://localhost:5665/v1/objects/hosts/example.localdomain' \
607     -d '{ "templates": [ "generic-host" ], "attrs": { "address": "192.168.1.1", "check_command": "hostalive", "vars.os" : "Linux" }, "pretty": true }'
608     {
609         "results": [
610             {
611                 "code": 200.0,
612                 "status": "Object was created."
613             }
614         ]
615     }
616
617 If the configuration validation fails, the new object will not be created and the response body
618 contains a detailed error message. The following example is missing the `check_command` attribute
619 which is required for host objects:
620
621     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X PUT 'https://localhost:5665/v1/objects/hosts/example.localdomain' \
622     -d '{ "attrs": { "address": "192.168.1.1", "vars.os" : "Linux" }, "pretty": true }'
623     {
624         "results": [
625             {
626                 "code": 500.0,
627                 "errors": [
628                     "Error: Validation failed for object 'example.localdomain' of type 'Host'; Attribute 'check_command': Attribute must not be empty."
629                 ],
630                 "status": "Object could not be created."
631             }
632         ]
633     }
634
635 Service objects must be created using their full name ("hostname!servicename") referencing an existing host object:
636
637     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X PUT 'https://localhost:5665/v1/objects/services/example.localdomain!realtime-load' \
638     -d '{ "templates": [ "generic-service" ], "attrs": { "check_command": "load", "check_interval": 1,"retry_interval": 1 } }'
639
640
641 Example for a new CheckCommand object:
642
643     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X PUT 'https://localhost:5665/v1/objects/checkcommands/mytest' \
644     -d '{ "templates": [ "plugin-check-command" ], "attrs": { "command": [ "/usr/local/sbin/check_http" ], "arguments": { "-I": "$mytest_iparam$" } } }'
645
646
647 ### Modifying Objects <a id="icinga2-api-config-objects-modify"></a>
648
649 Existing objects must be modified by sending a `POST` request. The following
650 parameters need to be passed inside the JSON body:
651
652   Parameters | Type       | Description
653   -----------|------------|---------------------------
654   attrs      | Dictionary | **Required.** Set specific object attributes for this [object type](09-object-types.md#object-types).
655
656 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) should be provided.
657
658 > **Note**:
659 >
660 > Modified attributes do not trigger a re-evaluation of existing
661 > static [apply rules](03-monitoring-basics.md#using-apply) and [group assignments](03-monitoring-basics.md#group-assign-intro).
662 > Delete and re-create the objects if you require such changes.
663 >
664 > Furthermore you cannot modify templates which have already been resolved
665 > during [object creation](12-icinga2-api.md#icinga2-api-config-objects-create).
666 > There are attributes which can only be set for [PUT requests](12-icinga2-api.md#icinga2-api-config-objects-create) such as `groups`
667 > or `zone`. A complete list of `no_user_modify` attributes can be fetched from the [types](12-icinga2-api.md#icinga2-api-types) URL endpoint.
668
669 If attributes are of the Dictionary type, you can also use the indexer format:
670
671     "attrs": { "vars.os": "Linux" }
672
673 The following example updates the `address` attribute and the custom attribute `os` for the `example.localdomain` host:
674
675     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/objects/hosts/example.localdomain' \
676     -d '{ "attrs": { "address": "192.168.1.2", "vars.os" : "Windows" }, "pretty": true }'
677     {
678         "results": [
679             {
680                 "code": 200.0,
681                 "name": "example.localdomain",
682                 "status": "Attributes updated.",
683                 "type": "Host"
684             }
685         ]
686     }
687
688
689 ### Deleting Objects <a id="icinga2-api-config-objects-delete"></a>
690
691 You can delete objects created using the API by sending a `DELETE`
692 request.
693
694   Parameters | Type    | Description
695   -----------|---------|---------------
696   cascade    | Boolean |  **Optional.** Delete objects depending on the deleted objects (e.g. services on a host).
697
698 In addition to these parameters a [filter](12-icinga2-api.md#icinga2-api-filters) should be provided.
699
700 Example for deleting the host object `example.localdomain`:
701
702     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X DELETE 'https://localhost:5665/v1/objects/hosts/example.localdomain?cascade=1&pretty=1'
703     {
704         "results": [
705             {
706                 "code": 200.0,
707                 "name": "example.localdomain",
708                 "status": "Object was deleted.",
709                 "type": "Host"
710             }
711         ]
712     }
713
714 ## Config Templates <a id="icinga2-api-config-templates"></a>
715
716 Provides methods to manage configuration templates:
717
718 * [querying templates](12-icinga2-api.md#icinga2-api-config-templates-query)
719
720 Creation, modification and deletion of templates at runtime is not supported.
721
722 ### Querying Templates <a id="icinga2-api-config-templates-query"></a>
723
724 You can request information about configuration templates by sending
725 a `GET` query to the `/v1/templates/<type>` URL endpoint. `<type` has
726 to be replaced with the plural name of the object type you are interested
727 in:
728
729     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/templates/hosts'
730
731 A list of all available configuration types is available in the
732 [object types](09-object-types.md#object-types) chapter.
733
734 A [filter](12-icinga2-api.md#icinga2-api-filters) may be provided for this query type. The
735 template object can be accessed in the filter using the `tmpl` variable. In this
736 example the [match function](18-library-reference.md#global-functions-match) is used to
737 check a wildcard string pattern against `tmpl.name`.
738 The `filter` attribute is passed inside the request body thus requiring to use [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override)
739 here.
740
741     $ curl -k -s -u root:icinga -H 'Accept: application/json' -H 'X-HTTP-Method-Override: GET' -X POST 'https://localhost:5661/v1/templates/hosts' \
742     -d '{ "filter": "match(\"g*\", tmpl.name)" }'
743
744 Instead of using a filter you can optionally specify the template name in the
745 URL path when querying a single object:
746
747     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/templates/hosts/generic-host'
748
749 The result set contains the type, name as well as the location of the template.
750
751 ## Variables <a id="icinga2-api-variables"></a>
752
753 Provides methods to manage global variables:
754
755 * [querying variables](12-icinga2-api.md#icinga2-api-variables-query)
756
757 ### Querying Variables <a id="icinga2-api-variables-query"></a>
758
759 You can request information about global variables by sending
760 a `GET` query to the `/v1/variables/` URL endpoint:
761
762     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/variables'
763
764 A [filter](12-icinga2-api.md#icinga2-api-filters) may be provided for this query type. The
765 variable information object can be accessed in the filter using the `variable` variable.
766 The `filter` attribute is passed inside the request body thus requiring to use [X-HTTP-Method-Override](12-icinga2-api.md#icinga2-api-requests-method-override)
767 here.
768
769     $ curl -k -s -u root:icinga -H 'Accept: application/json' -H 'X-HTTP-Method-Override: GET' -X POST 'https://localhost:5661/v1/variables' \
770     -d '{ "filter": "variable.type in [ \"String\", \"Number\" ]" }'
771
772 Instead of using a filter you can optionally specify the variable name in the
773 URL path when querying a single variable:
774
775     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/variables/PrefixDir'
776
777 The result set contains the type, name and value of the global variable.
778
779 ## Actions <a id="icinga2-api-actions"></a>
780
781 There are several actions available for Icinga 2 provided by the `/v1/actions`
782 URL endpoint. You can run actions by sending a `POST` request.
783
784 In case you have been using the [external commands](14-features.md#external-commands)
785 in the past, the API actions provide a similar interface with filter
786 capabilities for some of the more common targets which do not directly change
787 the configuration.
788
789 All actions return a 200 `OK` or an appropriate error code for each
790 action performed on each object matching the supplied filter.
791
792 Actions which affect the Icinga Application itself such as disabling
793 notification on a program-wide basis must be applied by updating the
794 [IcingaApplication object](12-icinga2-api.md#icinga2-api-config-objects)
795 called `app`.
796
797     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/objects/icingaapplications/app' -d '{ "attrs": { "enable_notifications": false } }'
798
799 ### process-check-result <a id="icinga2-api-actions-process-check-result"></a>
800
801 Process a check result for a host or a service.
802
803 Send a `POST` request to the URL endpoint `/v1/actions/process-check-result`.
804
805   Parameter         | Type         | Description
806   ------------------|--------------|--------------
807   exit\_status      | Number       | **Required.** For services: 0=OK, 1=WARNING, 2=CRITICAL, 3=UNKNOWN, for hosts: 0=OK, 1=CRITICAL.
808   plugin\_output    | String       | **Required.** One or more lines of the plugin main output. Does **not** contain the performance data.
809   performance\_data | Array        | **Optional.** The performance data.
810   check\_command    | 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.
811   check\_source     | String       | **Optional.** Usually the name of the `command_endpoint`
812   execution\_start  | Timestamp    | **Optional.** The timestamp where a script/process started its execution.
813   execution\_end    | Timestamp    | **Optional.** The timestamp where a script/process ended its execution. This timestamp is used in features to determine e.g. the metric timestamp.
814
815 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`.
816
817 Example for the service `passive-ping6`:
818
819     $ 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' \
820     -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", "pretty": true }'
821
822     {
823         "results": [
824             {
825                 "code": 200.0,
826                 "status": "Successfully processed check result for object 'localdomain!passive-ping6'."
827             }
828         ]
829     }
830
831 Example for using the `Host` type and filter by the host name:
832
833     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/process-check-result' \
834     -d '{ "filter": "host.name==\"example.localdomain\"", "type": "Host", "exit_status": 1, "plugin_output": "Host is not available." }'
835
836 You can avoid URL encoding of white spaces in object names by using the `filter` attribute in the request body.
837
838 > **Note**
839 >
840 > Multi-line plugin output requires the following format: The first line is treated as `short` plugin output corresponding
841 > to the first line of the plugin output. Subsequent lines are treated as `long` plugin output. Please note that the
842 > performance data is separated from the plugin output and has to be passed as `performance_data` attribute.
843
844 ### reschedule-check <a id="icinga2-api-actions-reschedule-check"></a>
845
846 Reschedule a check for hosts and services. The check can be forced if required.
847
848 Send a `POST` request to the URL endpoint `/v1/actions/reschedule-check`.
849
850   Parameter    | Type      | Description
851   -------------|-----------|--------------
852   next\_check  | Timestamp | **Optional.** The next check will be run at this time. If omitted, the current time is used.
853   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.
854
855 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`.
856
857 The example reschedules all services with the name "ping6" to immediately perform a check
858 (`next_check` default), ignoring any time periods or whether active checks are
859 allowed for the service (`force_check=true`).
860
861     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/reschedule-check' \
862     -d '{ "type": "Service", "filter": "service.name==\"ping6\"", "force_check": true, "pretty": true }'
863
864     {
865         "results": [
866             {
867                 "code": 200.0,
868                 "status": "Successfully rescheduled check for object 'example.localdomain!ping6'."
869             }
870         ]
871     }
872
873
874 ### send-custom-notification <a id="icinga2-api-actions-send-custom-notification"></a>
875
876 Send a custom notification for hosts and services. This notification
877 type can be forced being sent to all users.
878
879 Send a `POST` request to the URL endpoint `/v1/actions/send-custom-notification`.
880
881   Parameter | Type    | Description
882   ----------|---------|--------------
883   author    | String  | **Required.** Name of the author, may be empty.
884   comment   | String  | **Required.** Comment text, may be empty.
885   force     | Boolean | **Optional.** Default: false. If true, the notification is sent regardless of downtimes or whether notifications are enabled or not.
886
887 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`.
888
889 Example for a custom host notification announcing a global maintenance to
890 host owners:
891
892     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/send-custom-notification' \
893     -d '{ "type": "Host", "author": "icingaadmin", "comment": "System is going down for maintenance", "force": true, "pretty": true }'
894
895     {
896         "results": [
897             {
898                 "code": 200.0,
899                 "status": "Successfully sent custom notification for object 'host0'."
900             },
901             {
902                 "code": 200.0,
903                 "status": "Successfully sent custom notification for object 'host1'."
904             }
905     }
906
907 ### delay-notification <a id="icinga2-api-actions-delay-notification"></a>
908
909 Delay notifications for a host or a service.
910 Note that this will only have an effect if the service stays in the same problem
911 state that it is currently in. If the service changes to another state, a new
912 notification may go out before the time you specify in the `timestamp` argument.
913
914 Send a `POST` request to the URL endpoint `/v1/actions/delay-notification`.
915
916   Parameter | Type      | Description
917   ----------|-----------|--------------
918   timestamp | Timestamp | **Required.** Delay notifications until this timestamp.
919
920 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`.
921
922 Example:
923
924     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/delay-notification' \
925     -d '{ "type": "Service", "timestamp": 1446389894, "pretty": true }'
926
927     {
928         "results": [
929             {
930                 "code": 200.0,
931                 "status": "Successfully delayed notifications for object 'host0!service0'."
932             },
933             {
934                 "code": 200.0,
935                 "status": "Successfully delayed notifications for object 'host1!service1'."
936             }
937     }
938
939 ### acknowledge-problem <a id="icinga2-api-actions-acknowledge-problem"></a>
940
941 Allows you to acknowledge the current problem for hosts or services. By
942 acknowledging the current problem, future notifications (for the same state if `sticky` is set to `false`)
943 are disabled.
944
945 Send a `POST` request to the URL endpoint `/v1/actions/acknowledge-problem`.
946
947   Parameter            | Type      | Description
948   ---------------------|-----------|--------------
949   author               | String    | **Required.** Name of the author, may be empty.
950   comment              | String    | **Required.** Comment text, may be empty.
951   expiry               | Timestamp | **Optional.** Whether the acknowledgement will be removed at the timestamp.
952   sticky               | Boolean   | **Optional.** Whether the acknowledgement will be set until the service or host fully recovers. Defaults to `false`.
953   notify               | Boolean   | **Optional.** Whether a notification of the `Acknowledgement` type will be sent. Defaults to `false`.
954   persistent           | Boolean   | **Optional.** When the comment is of type `Acknowledgement` and this is set to `true`, the comment will remain after the acknowledgement recovers or expires. Defaults to `false`.
955
956 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
958 The following example acknowledges all services which are in a hard critical state and sends out
959 a notification for them:
960
961     $ 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' \
962     -d '{ "author": "icingaadmin", "comment": "Global outage. Working on it.", "notify": true, "pretty": true }'
963
964     {
965         "results": [
966             {
967                 "code": 200.0,
968                 "status": "Successfully acknowledged problem for object 'example2.localdomain!ping4'."
969             },
970             {
971                 "code": 200.0,
972                 "status": "Successfully acknowledged problem for object 'example.localdomain!ping4'."
973             }
974     }
975
976
977 ### remove-acknowledgement <a id="icinga2-api-actions-remove-acknowledgement"></a>
978
979 Removes the acknowledgements for services or hosts. Once the acknowledgement has
980 been removed notifications will be sent out again.
981
982 Send a `POST` request to the URL endpoint `/v1/actions/remove-acknowledgement`.
983
984 A [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host` and `Service`.
985
986 The example removes all service acknowledgements:
987
988     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-acknowledgement?type=Service&pretty=1'
989
990     {
991         "results": [
992             {
993                 "code": 200.0,
994                 "status": "Successfully removed acknowledgement for object 'host0!service0'."
995             },
996             {
997                 "code": 200.0,
998                 "status": "Successfully removed acknowledgement for object 'example2.localdomain!aws-health'."
999             }
1000     }
1001
1002 ### add-comment <a id="icinga2-api-actions-add-comment"></a>
1003
1004 Adds a `comment` from an `author` to services or hosts.
1005
1006 Send a `POST` request to the URL endpoint `/v1/actions/add-comment`.
1007
1008   Parameter | Type   | Description
1009   ----------|--------|--------------
1010   author    | string | **Required.** Name of the author, may be empty.
1011   comment   | string | **Required.** Comment text, may be empty.
1012
1013 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`.
1014
1015 The following example adds a comment for all `ping4` services:
1016
1017     $ 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.", "pretty": true }'
1018     {
1019         "results": [
1020             {
1021                 "code": 200.0,
1022                 "legacy_id": 26.0,
1023                 "name": "example.localdomain!ping4!example.localdomain-1446824161-0",
1024                 "status": "Successfully added comment 'example.localdomain!ping4!example.localdomain-1446824161-0' for object 'example.localdomain!ping4'."
1025             },
1026             {
1027                 "code": 200.0,
1028                 "legacy_id": 27.0,
1029                 "name": "example2.localdomain!ping4!example.localdomain-1446824161-1",
1030                 "status": "Successfully added comment 'example2.localdomain!ping4!example.localdomain-1446824161-1' for object 'example2.localdomain!ping4'."
1031             }
1032         ]
1033     }
1034
1035 ### remove-comment <a id="icinga2-api-actions-remove-comment"></a>
1036
1037 Remove the comment using its `name` attribute , returns `OK` if the
1038 comment did not exist.
1039 **Note**: This is **not** the legacy ID but the comment name returned by
1040 Icinga 2 when [adding a comment](12-icinga2-api.md#icinga2-api-actions-add-comment).
1041
1042 Send a `POST` request to the URL endpoint `/v1/actions/remove-comment`.
1043
1044 A [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host`, `Service` and `Comment`.
1045
1046 Example for a simple filter using the `comment` URL parameter:
1047
1048     $ 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&pretty=1'
1049     {
1050         "results": [
1051             {
1052                 "code": 200.0,
1053                 "status": "Successfully removed comment 'example2.localdomain!ping4!mbmif.local-1446986367-0'."
1054             }
1055         ]
1056     }
1057
1058 Example for removing all service comments using a service name filter for `ping4`:
1059
1060     $ 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&pretty=1'
1061     {
1062         "results": [
1063             {
1064                 "code": 200.0,
1065                 "status": "Successfully removed all comments for object 'example2.localdomain!ping4'."
1066             },
1067             {
1068                 "code": 200.0,
1069                 "status": "Successfully removed all comments for object 'example.localdomain!ping4'."
1070             }
1071         ]
1072     }
1073
1074
1075 ### schedule-downtime <a id="icinga2-api-actions-schedule-downtime"></a>
1076
1077 Schedule a downtime for hosts and services.
1078
1079 Send a `POST` request to the URL endpoint `/v1/actions/schedule-downtime`.
1080
1081   Parameter     | Type      | Description
1082   --------------|-----------|--------------
1083   author        | String    | **Required.** Name of the author.
1084   comment       | String    | **Required.** Comment text.
1085   start\_time   | Timestamp | **Required.** Timestamp marking the beginning of the downtime.
1086   end\_time     | Timestamp | **Required.** Timestamp marking the end of the downtime.
1087   fixed         | Boolean   | **Optional.** Defaults to `true`. If true, the downtime is `fixed` otherwise `flexible`. See [downtimes](08-advanced-topics.md#downtimes) for more information.
1088   duration      | Number    | **Required for flexible downtimes.** Duration of the downtime in seconds if `fixed` is set to false.
1089   trigger\_name | String    | **Optional.** Sets the trigger for a triggered downtime. See [downtimes](08-advanced-topics.md#downtimes) for more information on triggered downtimes.
1090   child\_options | Number   | **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`.
1091
1092 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`.
1093
1094 Example:
1095
1096     $ 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", "pretty": true }'
1097     {
1098         "results": [
1099             {
1100                 "code": 200.0,
1101                 "legacy_id": 2.0,
1102                 "name": "example2.localdomain!ping4!example.localdomain-1446822004-0",
1103                 "status": "Successfully scheduled downtime 'example2.localdomain!ping4!example.localdomain-1446822004-0' for object 'example2.localdomain!ping4'."
1104             },
1105             {
1106                 "code": 200.0,
1107                 "legacy_id": 3.0,
1108                 "name": "example.localdomain!ping4!example.localdomain-1446822004-1",
1109                 "status": "Successfully scheduled downtime 'example.localdomain!ping4!example.localdomain-1446822004-1' for object 'example.localdomain!ping4'."
1110             }
1111         ]
1112     }
1113
1114 ### remove-downtime <a id="icinga2-api-actions-remove-downtime"></a>
1115
1116 Remove the downtime using its `name` attribute , returns `OK` if the
1117 downtime did not exist.
1118 **Note**: This is **not** the legacy ID but the downtime name returned by
1119 Icinga 2 when [scheduling a downtime](12-icinga2-api.md#icinga2-api-actions-schedule-downtime).
1120
1121 Send a `POST` request to the URL endpoint `/v1/actions/remove-downtime`.
1122
1123 A [filter](12-icinga2-api.md#icinga2-api-filters) must be provided. The valid types for this action are `Host`, `Service` and `Downtime`.
1124
1125 Example for a simple filter using the `downtime` URL parameter:
1126
1127     $ 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&pretty=1'
1128     {
1129         "results": [
1130             {
1131                 "code": 200.0,
1132                 "status": "Successfully removed downtime 'example.localdomain!ping4!mbmif.local-1446979168-6'."
1133             }
1134         ]
1135     }
1136
1137 Example for removing all host downtimes using a host name filter for `example.localdomain`:
1138
1139     $ 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&pretty=1'
1140     {
1141         "results": [
1142             {
1143                 "code": 200.0,
1144                 "status": "Successfully removed all downtimes for object 'example.localdomain'."
1145             }
1146         ]
1147     }
1148
1149 Example for removing a downtime from a host but not the services filtered by the author name. This example uses
1150 filter variables explained in the [advanced filters](12-icinga2-api.md#icinga2-api-advanced-filters) chapter.
1151
1152     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/remove-downtime' \
1153             -d $'{
1154       "type": "Downtime",
1155       "filter": "host.name == filterHost && !service && downtime.author == filterAuthor",
1156       "filter_vars": {
1157         "filterHost": "example.localdomain",
1158         "filterAuthor": "icingaadmin"
1159       },
1160       "pretty": true
1161     }'
1162
1163     {
1164         "results": [
1165             {
1166                 "code": 200.0,
1167                 "status": "Successfully removed downtime 'example.localdomain!mbmif.local-1463043129-3'."
1168             }
1169         ]
1170     }
1171
1172 ### shutdown-process <a id="icinga2-api-actions-shutdown-process"></a>
1173
1174 Shuts down Icinga2. May or may not return.
1175
1176 Send a `POST` request to the URL endpoint `/v1/actions/shutdown-process`.
1177
1178 This action does not support a target type or filter.
1179
1180 Example:
1181
1182     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/shutdown-process?pretty=1'
1183
1184     {
1185         "results": [
1186             {
1187                 "code": 200.0,
1188                 "status": "Shutting down Icinga 2."
1189             }
1190         ]
1191     }
1192
1193 ### restart-process <a id="icinga2-api-actions-restart-process"></a>
1194
1195 Restarts Icinga2. May or may not return.
1196
1197 Send a `POST` request to the URL endpoint `/v1/actions/restart-process`.
1198
1199 This action does not support a target type or filter.
1200
1201 Example:
1202
1203     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/restart-process?pretty=1'
1204
1205     {
1206         "results": [
1207             {
1208                 "code": 200.0,
1209                 "status": "Restarting Icinga 2."
1210             }
1211         ]
1212     }
1213
1214 ### generate-ticket <a id="icinga2-api-actions-generate-ticket"></a>
1215
1216 Generates a PKI ticket for [CSR auto-signing](06-distributed-monitoring.md#distributed-monitoring-setup-csr-auto-signing).
1217 This can be used in combination with satellite/client setups requesting this ticket number.
1218
1219 Send a `POST` request to the URL endpoint `/v1/actions/generate-ticket`.
1220
1221   Parameter     | Type      | Description
1222   --------------|-----------|--------------
1223   cn            | String    | **Required.** The host's common name for which the ticket should be geenerated.
1224
1225 Example:
1226
1227     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST 'https://localhost:5665/v1/actions/generate-ticket' \
1228     -d '{ "cn": "icinga2-client1.localdomain", "pretty": true }'
1229     {
1230         "results": [
1231             {
1232                 "code": 200.0,
1233                 "status": "Generated PKI ticket '4f75d2ecd253575fe9180938ebff7cbca262f96e' for common name 'icinga2-client1.localdomain'.",
1234                 "ticket": "4f75d2ecd253575fe9180938ebff7cbca262f96e"
1235             }
1236         ]
1237     }
1238
1239
1240 ## Event Streams <a id="icinga2-api-event-streams"></a>
1241
1242 You can subscribe to event streams by sending a `POST` request to the URL endpoint `/v1/events`.
1243 The following parameters need to be specified (either as URL parameters or in a JSON-encoded message body):
1244
1245   Parameter  | Type         | Description
1246   -----------|--------------|-------------
1247   types      | Array        | **Required.** Event type(s). Multiple types as URL parameters are supported.
1248   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.
1249   filter     | String       | **Optional.** Filter for specific event attributes using [filter expressions](12-icinga2-api.md#icinga2-api-filters).
1250
1251 ### Event Stream Types <a id="icinga2-api-event-streams-types"></a>
1252
1253 The following event stream types are available:
1254
1255   Type                   | Description
1256   -----------------------|--------------
1257   CheckResult            | Check results for hosts and services.
1258   StateChange            | Host/service state changes.
1259   Notification           | Notification events including notified users for hosts and services.
1260   AcknowledgementSet     | Acknowledgement set on hosts and services.
1261   AcknowledgementCleared | Acknowledgement cleared on hosts and services.
1262   CommentAdded           | Comment added for hosts and services.
1263   CommentRemoved         | Comment removed for hosts and services.
1264   DowntimeAdded          | Downtime added for hosts and services.
1265   DowntimeRemoved        | Downtime removed for hosts and services.
1266   DowntimeStarted        | Downtime started for hosts and services.
1267   DowntimeTriggered      | Downtime triggered for hosts and services.
1268
1269 Note: Each type requires [API permissions](12-icinga2-api.md#icinga2-api-permissions)
1270 being set.
1271
1272 Example for all downtime events:
1273
1274     &types=DowntimeAdded&types=DowntimeRemoved&types=DowntimeTriggered
1275
1276 #### <a id="icinga2-api-event-streams-type-checkresult"></a> Event Stream Type: CheckResult
1277
1278   Name          | Type          | Description
1279   --------------|---------------|--------------------------
1280   type          | String        | Event type `CheckResult`.
1281   timestamp     | Timestamp     | Unix timestamp when the event happened.
1282   host          | String        | [Host](09-object-types.md#objecttype-host) name.
1283   service       | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host check result.
1284   check\_result | CheckResult   | Serialized [CheckResult](08-advanced-topics.md#advanced-value-types-checkresult) value type.
1285
1286 #### <a id="icinga2-api-event-streams-type-statechange"></a> Event Stream Type: StateChange
1287
1288   Name          | Type          | Description
1289   --------------|---------------|--------------------------
1290   type          | String        | Event type `StateChange`.
1291   timestamp     | Timestamp     | Unix timestamp when the event happened.
1292   host          | String        | [Host](09-object-types.md#objecttype-host) name.
1293   service       | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host state change.
1294   state         | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state.
1295   state\_type   | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type.
1296   check\_result | CheckResult   | Serialized [CheckResult](08-advanced-topics.md#advanced-value-types-checkresult) value type.
1297
1298 #### <a id="icinga2-api-event-streams-type-notification"></a> Event Stream Type: Notification
1299
1300   Name          | Type          | Description
1301   --------------|---------------|--------------------------
1302   type          | String        | Event type `Notification`.
1303   timestamp     | Timestamp     | Unix timestamp when the event happened.
1304   host          | String        | [Host](09-object-types.md#objecttype-host) name.
1305   service       | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host notification.
1306   users         | Array         | List of notified [user](09-object-types.md#objecttype-user) names.
1307   notification\_type | String   | [$notification.type$](03-monitoring-basics.md#notification-runtime-macros) runtime macro value.
1308   author        | String        | [$notification.author$](03-monitoring-basics.md#notification-runtime-macros) runtime macro value.
1309   text          | String        | [$notification.comment$](03-monitoring-basics.md#notification-runtime-macros) runtime macro value.
1310   check\_result | CheckResult   | Serialized [CheckResult](08-advanced-topics.md#advanced-value-types-checkresult) value type.
1311
1312 #### <a id="icinga2-api-event-streams-type-flapping"></a> Event Stream Type: Flapping
1313
1314   Name              | Type          | Description
1315   ------------------|---------------|--------------------------
1316   type              | String        | Event type `Flapping`.
1317   timestamp         | Timestamp     | Unix timestamp when the event happened.
1318   host              | String        | [Host](09-object-types.md#objecttype-host) name.
1319   service           | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host flapping event.
1320   state             | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state.
1321   state\_type       | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type.
1322   is\_flapping      | Boolean       | Whether this object is flapping.
1323   current\_flapping | Number        | Current flapping value in percent (added in 2.8).
1324   threshold\_low    | Number        | Low threshold in percent (added in 2.8).
1325   threshold\_high   | Number        | High threshold in percent (added in 2.8).
1326
1327 #### <a id="icinga2-api-event-streams-type-acknowledgementset"></a> Event Stream Type: AcknowledgementSet
1328
1329   Name          | Type          | Description
1330   --------------|---------------|--------------------------
1331   type          | String        | Event type `AcknowledgementSet`.
1332   timestamp     | Timestamp     | Unix timestamp when the event happened.
1333   host          | String        | [Host](09-object-types.md#objecttype-host) name.
1334   service       | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host acknowledgement.
1335   state         | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state.
1336   state\_type   | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type.
1337   author        | String        | Acknowledgement author set via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action.
1338   comment       | String        | Acknowledgement comment set via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action.
1339   acknowledgement\_type | Number | 0 = None, 1 = Normal, 2 = Sticky. `sticky` can be set via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action.
1340   notify        | Boolean       | Notifications were enabled via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action.
1341   expiry        | Timestamp     | Acknowledgement expire time set via [acknowledge-problem](12-icinga2-api.md#icinga2-api-actions-acknowledge-problem) action.
1342
1343 #### <a id="icinga2-api-event-streams-type-acknowledgementcleared"></a> Event Stream Type: AcknowledgementCleared
1344
1345   Name          | Type          | Description
1346   --------------|---------------|--------------------------
1347   type          | String        | Event type `AcknowledgementCleared`.
1348   timestamp     | Timestamp     | Unix timestamp when the event happened.
1349   host          | String        | [Host](09-object-types.md#objecttype-host) name.
1350   service       | String        | [Service](09-object-types.md#objecttype-service) name. Optional if this is a host acknowledgement.
1351   state         | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state.
1352   state\_type   | Number        | [Host](09-object-types.md#objecttype-host) or [service](09-object-types.md#objecttype-service) state type.
1353
1354 #### <a id="icinga2-api-event-streams-type-commentadded"></a> Event Stream Type: CommentAdded
1355
1356   Name          | Type          | Description
1357   --------------|---------------|--------------------------
1358   type          | String        | Event type `CommentAdded`.
1359   timestamp     | Timestamp     | Unix timestamp when the event happened.
1360   comment       | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-comment) object.
1361
1362 #### <a id="icinga2-api-event-streams-type-commentremoved"></a> Event Stream Type: CommentRemoved
1363
1364   Name          | Type          | Description
1365   --------------|---------------|--------------------------
1366   type          | String        | Event type `CommentRemoved`.
1367   timestamp     | Timestamp     | Unix timestamp when the event happened.
1368   comment       | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-comment) object.
1369
1370 #### <a id="icinga2-api-event-streams-type-downtimeadded"></a> Event Stream Type: DowntimeAdded
1371
1372   Name          | Type          | Description
1373   --------------|---------------|--------------------------
1374   type          | String        | Event type `DowntimeAdded`.
1375   timestamp     | Timestamp     | Unix timestamp when the event happened.
1376   downtime      | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-downtime) object.
1377
1378 #### <a id="icinga2-api-event-streams-type-downtimeremoved"></a> Event Stream Type: DowntimeRemoved
1379
1380   Name          | Type          | Description
1381   --------------|---------------|--------------------------
1382   type          | String        | Event type `DowntimeRemoved`.
1383   timestamp     | Timestamp     | Unix timestamp when the event happened.
1384   downtime      | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-downtime) object.
1385
1386
1387 #### <a id="icinga2-api-event-streams-type-downtimestarted"></a> Event Stream Type: DowntimeStarted
1388
1389   Name          | Type          | Description
1390   --------------|---------------|--------------------------
1391   type          | String        | Event type `DowntimeStarted`.
1392   timestamp     | Timestamp     | Unix timestamp when the event happened.
1393   downtime      | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-downtime) object.
1394
1395
1396 #### <a id="icinga2-api-event-streams-type-downtimetriggered"></a> Event Stream Type: DowntimeTriggered
1397
1398   Name          | Type          | Description
1399   --------------|---------------|--------------------------
1400   type          | String        | Event type `DowntimeTriggered`.
1401   timestamp     | Timestamp     | Unix timestamp when the event happened.
1402   downtime      | Dictionary    | Serialized [Comment](09-object-types.md#objecttype-downtime) object.
1403
1404
1405 ### Event Stream Filter <a id="icinga2-api-event-streams-filter"></a>
1406
1407 Event streams can be filtered by attributes using the prefix `event.`.
1408
1409 Example for the `CheckResult` type with the `exit_code` set to `2`:
1410
1411     &types=CheckResult&filter=event.check_result.exit_status==2
1412
1413 Example for the `CheckResult` type with the service [matching](18-library-reference.md#global-functions-match)
1414 the string pattern "random\*":
1415
1416     &types=CheckResult&filter=match%28%22random*%22,event.service%29
1417
1418
1419 ### Event Stream Response <a id="icinga2-api-event-streams-response"></a>
1420
1421 The event stream response is separated with new lines. The HTTP client
1422 must support long-polling and HTTP/1.1. HTTP/1.0 is not supported.
1423
1424 Example:
1425
1426     $ 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'
1427
1428     {"check_result":{ ... },"host":"example.localdomain","service":"ping4","timestamp":1445421319.7226390839,"type":"CheckResult"}
1429     {"check_result":{ ... },"host":"example.localdomain","service":"ping4","timestamp":1445421324.7226390839,"type":"CheckResult"}
1430     {"check_result":{ ... },"host":"example.localdomain","service":"ping4","timestamp":1445421329.7226390839,"type":"CheckResult"}
1431
1432
1433 ## Status and Statistics <a id="icinga2-api-status"></a>
1434
1435 Send a `GET` request to the URL endpoint `/v1/status` to retrieve status information and statistics for Icinga 2.
1436
1437 Example:
1438
1439     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/status?pretty=1'
1440     {
1441         "results": [
1442             {
1443                 "name": "ApiListener",
1444                 "perfdata": [ ... ],
1445                 "status": [ ... ]
1446             },
1447             ...
1448             {
1449                 "name": "IcingaAplication",
1450                 "perfdata": [ ... ],
1451                 "status": [ ... ]
1452             },
1453             ...
1454         ]
1455     }
1456
1457 You can limit the output by specifying a status type in the URL, e.g. `IcingaApplication`:
1458
1459     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/status/IcingaApplication?pretty=1'
1460     {
1461         "results": [
1462             {
1463                 "perfdata": [],
1464                 "status": {
1465                     "icingaapplication": {
1466                         "app": {
1467                             "enable_event_handlers": true,
1468                             "enable_flapping": true,
1469                             "enable_host_checks": true,
1470                             "enable_notifications": true,
1471                             "enable_perfdata": true,
1472                             "enable_service_checks": true,
1473                             "node_name": "example.localdomain",
1474                             "pid": 59819.0,
1475                             "program_start": 1443019345.093372,
1476                             "version": "v2.3.0-573-g380a131"
1477                         }
1478                     }
1479                 }
1480             }
1481         ]
1482     }
1483
1484
1485 ## Configuration Management <a id="icinga2-api-config-management"></a>
1486
1487 The main idea behind configuration management is to allow external applications
1488 creating configuration packages and stages based on configuration files and
1489 directory trees. This replaces any additional SSH connection and whatnot to
1490 dump configuration files to Icinga 2 directly.
1491 In case you are pushing a new configuration stage to a package, Icinga 2 will
1492 validate the configuration asynchronously and populate a status log which
1493 can be fetched in a separated request.
1494
1495
1496 ### Creating a Config Package <a id="icinga2-api-config-management-create-package"></a>
1497
1498 Send a `POST` request to a new config package called `example-cmdb` in this example. This
1499 will create a new empty configuration package.
1500
1501     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST \
1502     'https://localhost:5665/v1/config/packages/example-cmdb?pretty=1'
1503     {
1504         "results": [
1505             {
1506                 "code": 200.0,
1507                 "package": "example-cmdb",
1508                 "status": "Created package."
1509             }
1510         ]
1511     }
1512
1513 Package names starting with an underscore are reserved for internal packages and must not be used.
1514
1515 ### Uploading configuration for a Config Package <a id="icinga2-api-config-management-create-config-stage"></a>
1516
1517 Configuration files in packages are managed in stages.
1518 Stages provide a way to maintain multiple configuration versions for a package.
1519
1520 Send a `POST` request to the URL endpoint `/v1/config/stages` and add the name of an existing
1521 configuration package to the URL path (e.g. `example-cmdb`).
1522 The request body must contain the `files` attribute with the value being
1523 a dictionary of file targets and their content. You can also specify an optional `reload` attribute
1524 that will tell icinga2 to reload after stage config validation. By default this is set to `true`.
1525
1526 The file path requires one of these two directories inside its path:
1527
1528   Directory   | Description
1529   ------------|------------------------------------
1530   conf.d      | Local configuration directory.
1531   zones.d     | Configuration directory for cluster zones, each zone must be put into its own zone directory underneath. Supports the [cluster config sync](06-distributed-monitoring.md#distributed-monitoring-top-down-config-sync).
1532
1533 Example for a local configuration in the `conf.d` directory:
1534
1535     "files": { "conf.d/host1.conf": "object Host \"local-host\" { address = \"127.0.0.1\", check_command = \"hostalive\" }" }
1536
1537 Example for a host configuration inside the `satellite` zone in the `zones.d` directory:
1538
1539     "files": { "zones.d/satellite/host2.conf": "object Host \"satellite-host\" { address = \"192.168.1.100\", check_command = \"hostalive\" }" }
1540
1541
1542 The example below will create a new file called `test.conf` in the `conf.d`
1543 directory. Note: This example contains an error (`chec_command`). This is
1544 intentional.
1545
1546     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X POST \
1547     -d '{ "files": { "conf.d/test.conf": "object Host \"cmdb-host\" { chec_command = \"dummy\" }" }, "pretty": true }' \
1548     'https://localhost:5665/v1/config/stages/example-cmdb'
1549     {
1550         "results": [
1551             {
1552                 "code": 200.0,
1553                 "package": "example-cmdb",
1554                 "stage": "example.localdomain-1441625839-0",
1555                 "status": "Created stage. Icinga2 will reload."
1556             }
1557         ]
1558     }
1559
1560 The Icinga 2 API returns the `package` name this stage was created for, and also
1561 generates a unique name for the `stage` attribute you'll need for later requests.
1562
1563 Icinga 2 automatically restarts the daemon in order to activate the new config stage. This
1564 can be disabled by setting `reload` to `false` in the request.
1565 If the validation for the new config stage failed, the old stage
1566 and its configuration objects will remain active.
1567
1568 > **Note**
1569 >
1570 > 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.
1571
1572 Icinga 2 will create the following files in the configuration package
1573 stage after configuration validation:
1574
1575   File        | Description
1576   ------------|--------------
1577   status      | Contains the [configuration validation](11-cli-commands.md#config-validation) exit code (everything else than 0 indicates an error).
1578   startup.log | Contains the [configuration validation](11-cli-commands.md#config-validation) output.
1579
1580 You can [fetch these files](12-icinga2-api.md#icinga2-api-config-management-fetch-config-package-stage-files)
1581 in order to verify that the new configuration was deployed successfully.
1582
1583
1584 ### List Configuration Packages and their Stages <a id="icinga2-api-config-management-list-config-packages"></a>
1585
1586 A list of packages and their stages can be retrieved by sending a `GET` request to the URL endpoint `/v1/config/packages`.
1587
1588 The following example contains one configuration package `example-cmdb`. The package does not currently
1589 have an active stage.
1590
1591     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/config/packages?pretty=1'
1592     {
1593         "results": [
1594             {
1595                 "active-stage": "",
1596                 "name": "example-cmdb",
1597                 "stages": [
1598                     "example.localdomain-1441625839-0"
1599                 ]
1600             }
1601         ]
1602     }
1603
1604
1605 ### List Configuration Packages and their Stages <a id="icinga2-api-config-management-list-config-package-stage-files"></a>
1606
1607 In order to retrieve a list of files for a stage you can send a `GET` request to
1608 the URL endpoint `/v1/config/stages`. You need to include
1609 the package name (`example-cmdb`) and stage name (`example.localdomain-1441625839-0`) in the URL:
1610
1611     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/config/stages/example-cmdb/example.localdomain-1441625839-0?pretty=1'
1612     {
1613         "results": [
1614     ...
1615             {
1616                 "name": "startup.log",
1617                 "type": "file"
1618             },
1619             {
1620                 "name": "status",
1621                 "type": "file"
1622             },
1623             {
1624                 "name": "conf.d",
1625                 "type": "directory"
1626             },
1627             {
1628                 "name": "zones.d",
1629                 "type": "directory"
1630             },
1631             {
1632                 "name": "conf.d/test.conf",
1633                 "type": "file"
1634             }
1635         ]
1636     }
1637
1638 ### Fetch Configuration Package Stage Files <a id="icinga2-api-config-management-fetch-config-package-stage-files"></a>
1639
1640 Send a `GET` request to the URL endpoint `/v1/config/files` and add
1641 the package name, the stage name and the relative path to the file to the URL path.
1642
1643 > **Note**
1644 >
1645 > The returned files are plain-text instead of JSON-encoded.
1646
1647 The following example fetches the configuration file `conf.d/test.conf`:
1648
1649     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/config/files/example-cmdb/example.localdomain-1441625839-0/conf.d/test.conf'
1650
1651     object Host "cmdb-host" { chec_command = "dummy" }
1652
1653 You can fetch a [list of existing files](12-icinga2-api.md#icinga2-api-config-management-list-config-package-stage-files)
1654 in a configuration stage and then specifically request their content.
1655
1656 ### Configuration Package Stage Errors <a id="icinga2-api-config-management-config-package-stage-errors"></a>
1657
1658 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),
1659 there must have been an error.
1660
1661 In order to check for validation errors you can fetch the `startup.log` file
1662 by sending a `GET` request to the URL endpoint `/v1/config/files`. You must include
1663 the package name, stage name and the `startup.log` in the URL path.
1664
1665     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/config/files/example-cmdb/example.localdomain-1441133065-1/startup.log'
1666     ...
1667
1668     critical/config: Error: Attribute 'chec_command' does not exist.
1669     Location:
1670     /var/lib/icinga2/api/packages/example-cmdb/example.localdomain-1441133065-1/conf.d/test.conf(1): object Host "cmdb-host" { chec_command = "dummy" }
1671                                                                                                            ^^^^^^^^^^^^^^^^^^^^^^
1672
1673     critical/config: 1 error
1674
1675 The output is similar to the manual [configuration validation](11-cli-commands.md#config-validation).
1676
1677 > **Note**
1678 >
1679 > The returned output is plain-text instead of JSON-encoded.
1680
1681
1682 ### Deleting Configuration Package Stage <a id="icinga2-api-config-management-delete-config-stage"></a>
1683
1684 You can send a `DELETE` request to the URL endpoint `/v1/config/stages`
1685 in order to purge a configuration stage. You must include the package and
1686 stage name inside the URL path.
1687
1688 The following example removes the failed configuration stage `example.localdomain-1441133065-1`
1689 in the `example-cmdb` configuration package:
1690
1691     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X DELETE \
1692     'https://localhost:5665/v1/config/stages/example-cmdb/example.localdomain-1441133065-1?pretty=1'
1693     {
1694         "results": [
1695             {
1696                 "code": 200.0,
1697                 "status": "Stage deleted."
1698             }
1699         ]
1700     }
1701
1702
1703 ### Deleting Configuration Package <a id="icinga2-api-config-management-delete-config-package"></a>
1704
1705 In order to completely purge a configuration package and its stages
1706 you can send a `DELETE` request to the URL endpoint `/v1/config/packages`
1707 with the package name in the URL path.
1708
1709 This example entirely deletes the configuration package `example-cmdb`:
1710
1711     $ curl -k -s -u root:icinga -H 'Accept: application/json' -X DELETE \
1712     'https://localhost:5665/v1/config/packages/example-cmdb?pretty=1'
1713     {
1714         "results": [
1715             {
1716                 "code": 200.0,
1717                 "package": "example-cmdb",
1718                 "status": "Deleted package."
1719             }
1720         ]
1721     }
1722
1723
1724 ## Types <a id="icinga2-api-types"></a>
1725
1726 You can retrieve the configuration object types by sending a `GET` request to URL
1727 endpoint `/v1/types`.
1728
1729 Each response entry in the results array contains the following attributes:
1730
1731   Attribute       | Type         | Description
1732   ----------------|--------------|---------------------
1733   name            | String       | The type name.
1734   plural\_name    | String       | The plural type name.
1735   fields          | Dictionary   | Available fields including details on e.g. the type and attribute accessibility.
1736   abstract        | Boolean      | Whether objects can be instantiated for this type.
1737   base            | Boolean      | The base type (e.g. `Service` inherits fields and prototype methods from `Checkable`).
1738   prototype\_keys | Array        | Available prototype methods.
1739
1740 In order to view a specific configuration object type specify its name inside the URL path:
1741
1742     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/types/Object?pretty=1'
1743     {
1744         "results": [
1745             {
1746                 "abstract": false,
1747                 "fields": {
1748                     "type": {
1749                         "array_rank": 0.0,
1750                         "attributes": {
1751                             "config": false,
1752                             "navigation": false,
1753                             "no_user_modify": false,
1754                             "no_user_view": false,
1755                             "required": false,
1756                             "state": false
1757                         },
1758                         "id": 0.0,
1759                         "type": "String"
1760                     }
1761                 },
1762                 "name": "Object",
1763                 "plural_name": "Objects",
1764                 "prototype_keys": [
1765                     "clone",
1766                     "notify_attribute",
1767                     "to_string"
1768                 ]
1769             }
1770         ]
1771     }
1772
1773
1774 ## Console <a id="icinga2-api-console"></a>
1775
1776 You can inspect variables and execute other expressions by sending a `POST` request to the URL endpoint `/v1/console/execute-script`.
1777 In order to receive auto-completion suggestions, send a `POST` request to the URL endpoint `/v1/console/auto-complete-script`.
1778
1779 The following parameters need to be specified (either as URL parameters or in a JSON-encoded message body):
1780
1781   Parameter  | Type         | Description
1782   -----------|--------------|-------------
1783   session    | String       | **Optional.** The session ID. Ideally this should be a GUID or some other unique identifier.
1784   command    | String       | **Required.** Command expression for execution or auto-completion.
1785   sandboxed  | Number       | **Optional.** Whether runtime changes are allowed or forbidden. Defaults to disabled.
1786
1787 The [API permission](12-icinga2-api.md#icinga2-api-permissions) `console` is required for executing
1788 expressions.
1789
1790 > **Note**
1791 >
1792 > Runtime modifications via `execute-script` calls are not validated and might cause the Icinga 2
1793 > daemon to crash or behave in an unexpected way. Use these runtime changes at your own risk.
1794
1795 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).
1796
1797 Example for fetching the command line from the local host's last check result:
1798
1799     $ 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&pretty=1'
1800     {
1801         "results": [
1802             {
1803                 "code": 200.0,
1804                 "result": [
1805                     "/usr/local/sbin/check_ping",
1806                     "-H",
1807                     "127.0.0.1",
1808                     "-c",
1809                     "5000,100%",
1810                     "-w",
1811                     "3000,80%"
1812                 ],
1813                 "status": "Executed successfully."
1814             }
1815         ]
1816     }
1817
1818 Example for fetching auto-completion suggestions for the `Host.` type. This works in a
1819 similar fashion when pressing TAB inside the [console CLI command](11-cli-commands.md#cli-command-console):
1820
1821     $ 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&pretty=1'
1822     {
1823         "results": [
1824             {
1825                 "code": 200.0,
1826                 "status": "Auto-completed successfully.",
1827                 "suggestions": [
1828                     "Host.type",
1829                     "Host.name",
1830                     "Host.prototype",
1831                     "Host.base",
1832                     "Host.register_attribute_handler",
1833                     "Host.clone",
1834                     "Host.notify_attribute",
1835                     "Host.to_string"
1836                 ]
1837             }
1838         ]
1839     }
1840
1841
1842 ## API Clients <a id="icinga2-api-clients"></a>
1843
1844 There are a couple of existing clients which can be used with the Icinga 2 API:
1845
1846 * [curl](https://curl.haxx.se/) or any other HTTP client really
1847 * [Icinga 2 console (CLI command)](12-icinga2-api.md#icinga2-api-clients-cli-console)
1848 * [Icinga Studio](12-icinga2-api.md#icinga2-api-clients-icinga-studio)
1849 * [Icinga Web 2 Director](https://www.icinga.com/products/icinga-web-2-modules/)
1850
1851 Demo cases:
1852
1853 * [Dashing](https://github.com/Icinga/dashing-icinga2)
1854 * [API examples](https://github.com/Icinga/icinga2-api-examples)
1855
1856 Additional [programmatic examples](12-icinga2-api.md#icinga2-api-clients-programmatic-examples)
1857 will help you getting started using the Icinga 2 API in your environment.
1858
1859 ### Icinga Studio <a id="icinga2-api-clients-icinga-studio"></a>
1860
1861 Icinga Studio is a graphical application to query configuration objects provided by the API.
1862
1863 ![Icinga Studio Connection](images/icinga2-api/icinga2_api_icinga_studio_connect.png)
1864
1865 ![Icinga Studio Overview](images/icinga2-api/icinga2_api_icinga_studio_overview.png)
1866
1867 Please check the package repository of your distribution for available
1868 packages.
1869
1870 > **Note**
1871 > Icinga Studio does not currently support SSL certificate verification.
1872
1873 The Windows installer already includes Icinga Studio. On Debian and Ubuntu the package
1874 `icinga2-studio` can be used to install Icinga Studio.
1875
1876 ### Icinga 2 Console <a id="icinga2-api-clients-cli-console"></a>
1877
1878 By default the [console CLI command](11-cli-commands.md#cli-command-console) evaluates
1879 expressions in a local interpreter, i.e. independently from your Icinga 2 daemon.
1880 Add the `--connect` parameter to debug and evaluate expressions via the API.
1881
1882 ### API Clients Programmatic Examples <a id="icinga2-api-clients-programmatic-examples"></a>
1883
1884 The programmatic examples use HTTP basic authentication and SSL certificate
1885 verification. The CA file is expected in `pki/icinga2-ca.crt`
1886 but you may adjust the examples for your likings.
1887
1888 The [request method](icinga2-api-requests) is `POST` using
1889 [X-HTTP-Method-Override: GET](12-icinga2-api.md#icinga2-api-requests-method-override)
1890 which allows you to send a JSON request body. The examples request
1891 specific service attributes joined with host attributes. `attrs`
1892 and `joins` are therefore specified as array.
1893 The `filter` attribute [matches](18-library-reference.md#global-functions-match)
1894 on all services with `ping` in their name.
1895
1896 #### Example API Client in Python <a id="icinga2-api-clients-programmatic-examples-python"></a>
1897
1898 The following example uses **Python** and the `requests` and `json` module:
1899
1900     # pip install requests
1901     # pip install json
1902
1903     $ vim icinga2-api-example.py
1904
1905     #!/usr/bin/env python
1906     
1907     import requests, json
1908     
1909     # Replace 'localhost' with your FQDN and certificate CN
1910     # for SSL verification
1911     request_url = "https://localhost:5665/v1/objects/services"
1912     headers = {
1913             'Accept': 'application/json',
1914             'X-HTTP-Method-Override': 'GET'
1915             }
1916     data = {
1917             "attrs": [ "name", "state", "last_check_result" ],
1918             "joins": [ "host.name", "host.state", "host.last_check_result" ],
1919             "filter": "match(\"ping*\", service.name)",
1920     }
1921     
1922     r = requests.post(request_url,
1923             headers=headers,
1924             auth=('root', 'icinga'),
1925             data=json.dumps(data),
1926             verify="pki/icinga2-ca.crt")
1927     
1928     print "Request URL: " + str(r.url)
1929     print "Status code: " + str(r.status_code)
1930     
1931     if (r.status_code == 200):
1932             print "Result: " + json.dumps(r.json())
1933     else:
1934             print r.text
1935             r.raise_for_status()
1936
1937     $ python icinga2-api-example.py
1938
1939
1940 #### Example API Client in Ruby <a id="icinga2-api-clients-programmatic-examples-ruby"></a>
1941
1942 The following example uses **Ruby** and the `rest_client` gem:
1943
1944     # gem install rest_client
1945
1946     $ vim icinga2-api-example.rb
1947
1948     #!/usr/bin/ruby
1949     
1950     require 'rest_client'
1951     
1952     # Replace 'localhost' with your FQDN and certificate CN
1953     # for SSL verification
1954     request_url = "https://localhost:5665/v1/objects/services"
1955     headers = {
1956             "Accept" => "application/json",
1957             "X-HTTP-Method-Override" => "GET"
1958     }
1959     data = {
1960             "attrs" => [ "name", "state", "last_check_result" ],
1961             "joins" => [ "host.name", "host.state", "host.last_check_result" ],
1962             "filter" => "match(\"ping*\", service.name)",
1963     }
1964     
1965     r = RestClient::Resource.new(
1966             URI.encode(request_url),
1967             :headers => headers,
1968             :user => "root",
1969             :password => "icinga",
1970             :ssl_ca_file => "pki/icinga2-ca.crt")
1971     
1972     begin
1973             response = r.post(data.to_json)
1974     rescue => e
1975             response = e.response
1976     end
1977     
1978     puts "Status: " + response.code.to_s
1979     if response.code == 200
1980             puts "Result: " + (JSON.pretty_generate JSON.parse(response.body))
1981     else
1982             puts "Error: " + response
1983     end
1984
1985     $ ruby icinga2-api-example.rb
1986
1987 A more detailed example can be found in the [Dashing demo](https://github.com/Icinga/dashing-icinga2).
1988
1989 #### Example API Client in PHP <a id="icinga2-api-clients-programmatic-examples-php"></a>
1990
1991 The following example uses **PHP** and its `curl` library:
1992
1993     $ vim icinga2-api-example.php
1994
1995     #!/usr/bin/env php
1996     <?php
1997     # Replace 'localhost' with your FQDN and certificate CN
1998     # for SSL verification
1999     $request_url = "https://localhost:5665/v1/objects/services";
2000     $username = "root";
2001     $password = "icinga";
2002     $headers = array(
2003             'Accept: application/json',
2004             'X-HTTP-Method-Override: GET'
2005     );
2006     $data = array(
2007             attrs => array('name', 'state', 'last_check_result'),
2008             joins => array('host.name', 'host.state', 'host.last_check_result'),
2009             filter => 'match("ping*", service.name)',
2010     );
2011     
2012     $ch = curl_init();
2013     curl_setopt_array($ch, array(
2014             CURLOPT_URL => $request_url,
2015             CURLOPT_HTTPHEADER => $headers,
2016             CURLOPT_USERPWD => $username . ":" . $password,
2017             CURLOPT_RETURNTRANSFER => true,
2018             CURLOPT_CAINFO => "pki/icinga2-ca.crt",
2019             CURLOPT_POST => count($data),
2020             CURLOPT_POSTFIELDS => json_encode($data)
2021     ));
2022     
2023     $response = curl_exec($ch);
2024     if ($response === false) {
2025             print "Error: " . curl_error($ch) . "(" . $response . ")\n";
2026     }
2027     
2028     $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
2029     curl_close($ch);
2030     print "Status: " . $code . "\n";
2031     
2032     if ($code == 200) {
2033             $response = json_decode($response, true);
2034             print_r($response);
2035     }
2036     ?>
2037
2038     $ php icinga2-api-example.php
2039
2040 #### Example API Client in Perl <a id="icinga2-api-clients-programmatic-examples-perl"></a>
2041
2042 The following example uses **Perl** and the `Rest::Client` module:
2043
2044     # perl -MCPAN -e 'install REST::Client'
2045     # perl -MCPAN -e 'install JSON'
2046     # perl -MCPAN -e 'install MIME::Base64'
2047     # perl -MCPAN -e 'install Data::Dumper'
2048
2049     $ vim icinga2-api-example.pl
2050
2051     #!/usr/bin/env perl
2052     
2053     use strict;
2054     use warnings;
2055     use REST::Client;
2056     use MIME::Base64;
2057     use JSON;
2058     use Data::Dumper;
2059     
2060     # Replace 'localhost' with your FQDN and certificate CN
2061     # for SSL verification
2062     my $request_host = "https://localhost:5665";
2063     my $userpass = "root:icinga";
2064     
2065     my $client = REST::Client->new();
2066     $client->setHost($request_host);
2067     $client->setCa("pki/icinga2-ca.crt");
2068     $client->addHeader("Accept", "application/json");
2069     $client->addHeader("X-HTTP-Method-Override", "GET");
2070     $client->addHeader("Authorization", "Basic " . encode_base64($userpass));
2071     my %json_data = (
2072             attrs => ['name', 'state', 'last_check_result'],
2073             joins => ['host.name', 'host.state', 'host.last_check_result'],
2074             filter => 'match("ping*", service.name)',
2075     );
2076     my $data = encode_json(\%json_data);
2077     $client->POST("/v1/objects/services", $data);
2078     
2079     my $status = $client->responseCode();
2080     print "Status: " . $status . "\n";
2081     my $response = $client->responseContent();
2082     if ($status == 200) {
2083             print "Result: " . Dumper(decode_json($response)) . "\n";
2084     } else {
2085             print "Error: " . $response . "\n";
2086     }
2087
2088     $ perl icinga2-api-example.pl
2089