]> granicus.if.org Git - icinga2/blob - doc/9-icinga2-api.md
Fix incorrect variable type in ApiListener::ConfigUpdateObjectAPIHandler
[icinga2] / doc / 9-icinga2-api.md
1 # <a id="icinga2-api"></a> Icinga 2 API
2
3 ## <a id="icinga2-api-introduction"></a> Introduction
4
5 The Icinga 2 API allows you to manage configuration objects
6 and resources in a simple, programmatic way using HTTP requests.
7
8 The endpoints are logically separated allowing you to easily
9 make calls to
10
11 * run [actions](9-icinga2-api.md#icinga2-api-actions) (reschedule checks, etc.)
12 * query, create, modify and delete [config objects](9-icinga2-api.md#icinga2-api-config-objects)
13 * [manage configuration packages](9-icinga2-api.md#icinga2-api-config-management)
14 * subscribe to [event streams](9-icinga2-api.md#icinga2-api-event-streams)
15
16 This chapter will start with a general overview followed by
17 detailed information about specific endpoints.
18
19 ### <a id="icinga2-api-requests"></a> Requests
20
21 Any tool capable of making HTTP requests can communicate with
22 the API, for example [curl](http://curl.haxx.se).
23
24 Requests are only allowed to use the HTTPS protocol so that
25 traffic remains encrypted.
26
27 By default the Icinga 2 API listens on port `5665` sharing this
28 port with the cluster communication protocol. This can be changed
29 by setting the `bind_port` attribute in the [ApiListener](6-object-types.md#objecttype-apilistener)
30 configuration object in the `/etc/icinga2/features-available/api.conf`
31 file.
32
33 Supported request methods:
34
35   Method        | Usage
36   --------------|------------------------------------------------------
37   GET           | Retrieve information about configuration objects. Any request using the GET method is read-only and does not affect any objects.
38   POST          | Update attributes of a specified configuration object.
39   PUT           | Create a new object. The PUT request must include all attributes required to create a new object.
40   DELETE        | Remove an object created by the API. The DELETE method is idempotent and does not require any check if the object actually exists.
41
42 ### <a id="icinga2-api-http-statuses"></a> HTTP Statuses
43
44 The API will return standard [HTTP statuses](https://www.ietf.org/rfc/rfc2616.txt)
45 including error codes.
46
47 When an error occurs, the response body will contain additional information
48 about the problem and its source.
49
50 A status in the range of 200 generally means that the request was succesful
51 and no error was encountered.
52
53 Return codes within the 400 range indicate that there was a problem with the
54 request. Either you did not authenticate correctly, you are missing the authorization
55 for your requested action, the requested object does not exist or the request
56 was malformed.
57
58 A status in the range of 500 generally means that there was a server-side problem
59 and Icinga 2 is unable to process your request currently.
60
61 Ask your Icinga 2 system administrator to check the `icinga2.log` file for further
62 troubleshooting.
63
64
65 ### <a id="icinga2-api-responses"></a> Responses
66
67 Succesful requests will send back a response body containing a `results`
68 list. Depending on the number of affected objects in your request, the
69 results may contain one or more entries.
70
71 The [output](9-icinga2-api.md#icinga2-api-output) will be sent back as JSON object:
72
73
74     {
75         "results": [
76             {
77                 "code": 200.0,
78                 "status": "Object was created."
79             }
80         ]
81     }
82
83
84 ### <a id="icinga2-api-authentication"></a> Authentication
85
86 There are two different ways for authenticating against the Icinga 2 API:
87
88 * username and password using HTTP basic auth
89 * X.509 certificate with client CN
90
91 In order to configure a new API user you'll need to add a new [ApiUser](6-object-types.md#objecttype-apiuser)
92 configuration object. In this example `root` will be the basic auth username
93 and the `password` attribute contains the basic auth password.
94
95     vim /etc/icinga2/conf.d/api-users.conf
96
97     object ApiUser "root" {
98       password = icinga"
99     }
100
101 Alternatively you can use X.509 client certificates by specifying the `client_cn`
102 the API should trust.
103
104     vim /etc/icinga2/conf.d/api-users.conf
105
106     object ApiUser "api-clientcn" {
107       password = "CertificateCommonName"
108     }
109
110 An `ApiUser` object can have both methods configured. Sensitive information
111 such as the password will not be exposed through the API itself.
112
113 New installations of Icinga 2 will automatically generate a new `ApiUser`
114 named `root` with a generated password in the `/etc/icinga2/conf.d/api-users.conf`
115 file.
116 You can manually invoke the cli command `icinga2 api setup` which will generate
117 a new local CA, self-signed certificate and a new API user configuration.
118
119 Once the API user is configured make sure to restart Icinga 2:
120
121     # service icinga2 restart
122
123 Now pass the basic auth information to curl and send a GET request to the API:
124
125     $ curl -u root:icinga -k -s 'https://localhost:5665/v1/status'
126
127 In case you will get an error message make sure to check the API user credentials.
128
129 ### <a id="icinga2-api-permissions"></a> Permissions
130
131 By default an api user does not have any permissions to perform
132 actions on the [url endpoints](9-icinga2-api.md#icinga2-api-url-endpoints).
133
134 Permissions for api users must be specified in the `permissions` attribute
135 as array. The array items can be a list of permission strings with wildcard
136 matches.
137
138 Example for an api user with all permissions:
139
140     permissions = [ "*" ]
141
142 A yet more sophisticated approach is to specify additional permissions
143 and their filters. The latter must be defined as [lamdba function](20-language-reference.md#nullary-lambdas)
144 returning a boolean expression.
145
146 The `permission` attribute contains the action and the specific capitalized
147 object type name. Instead of the type name it is also possible to use a wildcard
148 match.
149
150 The following example allows the api user to query all hosts and services with
151 the custom host attribute `os` matching the regular expression `^Linux`.
152
153     permissions = [
154       {
155         permission = "objects/query/Host"
156         filter = {{ regex("^Linux", host.vars.os)  }}
157       },
158       {
159         permission = "objects/query/Service"
160         filter = {{ regex("^Linux", host.vars.os)  }}
161       },
162     ]
163
164
165 Available permissions for specific url endpoints:
166
167   Permissions                           | Url Endpoint
168   --------------------------------------|------------------------
169   actions/;&lt;action;&gt;              | /v1/actions
170   config/query                          | /v1/config
171   config/modify                         | /v1/config
172   objects/query/;&lt;type;&gt;          | /v1/objects
173   objects/create/;&lt;type;&gt;         | /v1/objects
174   objects/modify`/;&lt;type;&gt;        | /v1/objects
175   objects/delete/;&lt;type;&gt;         | /v1/objects
176   status/query                          | /v1/status
177
178 The required actions or types can be replaced by using a wildcard match ("*").
179
180 ### <a id="icinga2-api-parameters"></a> Parameters
181
182 Depending on the request method there are two ways of
183 passing parameters to the request:
184
185 * JSON body (`POST`, `PUT`)
186 * Query string (`GET`, `DELETE`)
187
188 Reserved characters by the HTTP protocol must be passed url-encoded as query string, e.g. a
189 space becomes `%20`.
190
191 Example for query string:
192
193     /v1/objects/hosts?filter=match(%22nbmif*%22,host.name)&attrs=host.name&attrs=host.state
194
195 Example for JSON body:
196
197     { "attrs": { "address": "8.8.4.4", "vars.os" : "Windows" } }
198
199
200 #### <a id="icinga2-api-filters"></a> Filters
201
202 Use the same syntax as for apply rule expressions
203 for filtering specific objects.
204
205 Example for all services in NOT-OK state:
206
207     https://localhost:5665/v1/objects/services?filter=service.state!=0
208
209 Example for matching all hosts by name (**Note**: `"` are url-encoded as `%22`):
210
211     https://localhost:5665/v1/objects/hosts?filter=match(%22nbmif*%22,host.name)
212
213
214 ### <a id="icinga2-api-output-format"></a>Output Format
215
216 The request and reponse body contain a JSON encoded string.
217
218 ### <a id="icinga2-api-version"></a>Version
219
220 Each url contains the version string as prefix (currently "/v1").
221
222 ### <a id="icinga2-api-url-endpoints"></a>Url Endpoints
223
224 The Icinga 2 API provides multiple url endpoints:
225
226   Url Endpoints | Description
227   --------------|----------------------------------------------------
228   /v1/actions   | Endpoint for running specific [API actions](9-icinga2-api.md#icinga2-api-actions).
229   /v1/config    | Endpoint for [managing configuration modules](9-icinga2-api.md#icinga2-api-config-management).
230   /v1/events    | Endpoint for subscribing to [API events](9-icinga2-api.md#icinga2-api-actions).
231   /v1/objects   | Endpoint for querying, creating, modifying and deleting [config objects](9-icinga2-api.md#icinga2-api-config-objects).
232   /v1/status    | Endpoint for receiving icinga2 [status and statistics](9-icinga2-api.md#icinga2-api-status).
233   /v1/types     | Endpoint for listing Icinga 2 configuration object types and their attributes.
234
235 Please check the respective sections for detailed urls and parameters.
236
237
238 ## <a id="icinga2-api-actions"></a> Actions
239
240 There are several actions available for Icinga 2 provided by the `actions` url endpoint.
241
242 In case you have been using the [external commands](5-advanced-topics.md#external-commands)
243 in the past, the API actions provide a yet more powerful interface with
244 filters and even more functionality.
245
246 Actions require specific target types (e.g. `type=Host`) and a [filter expression](9-icinga2-api.md#icinga2-api-filters).
247
248 **TODO** Figure out the final names.
249
250 Action name                            | Parameters                        | Target types             | Notes
251 ---------------------------------------|-----------------------------------|--------------------------|-----------------------
252 process-check-result                   | exit_status; plugin_output; check_source; performance_data[]; check_command[]; execution_end; execution_start; schedule_end; schedule_start | Service; Host | -
253 reschedule-check                       | {next_check}; {(force_check)} | Service; Host | -
254 acknowledge-problem                    | author; comment; {timestamp}; {(sticky)}; {(notify)} | Service; Host | -
255 remove-acknowledgement                 | - | Service; Host | -
256 add-comment                            | author; comment | Service; Host | -
257 remove-comment                         | - | Service;Host | -
258 remove-comment-by-id                   | comment_id | - | -
259 delay-notifications                    | timestamp | Service;Host | -
260 add-downtime                           | start_time; end_time; duration; author; comment; {trigger_id}; {(fixed)} | Service; Host; ServiceGroup; HostGroup | Downtime for all services on host x?
261 remove-downtime                        | - | Service; Host | -
262 remove-downtime-by-id                  | downtime_id | - | -
263 send-custom-notification               | options[]; author; comment | Service; Host | -
264
265 enable-passive-checks                  | - | Service; Host; ServiceGroup; HostGroup | "System" as target?
266 disable-passive-checks                 | - | Service; Host; ServiceGroup; HostGroup | diable all passive checks for services of hosts y in hostgroup x?
267 enable-active-checks                   | - | Host; HostGroup | -
268 disable-active-checks                  | - | Host; HostGroup | -
269 enable-notifications                   | - | Service; Host; ServiceGroup; HostGroup | Enable all notifications for services of host x?
270 disable-notifications                  | - | Service; Host; ServiceGroup; HostGroup | -
271 enable-flap-detection                  | - | Service; Host; ServiceGroup; HostGroup | -
272 disable-flap-detection                 | - | Service; Host; ServiceGroup; HostGroup | -
273 enable-event-handler                   | - | Service; Host | -
274 disable-event-handler                  | - | Service; Host | -
275
276 enable-global-notifications            | - | - | -
277 disable-global-notifications           | - | - | -
278 enable-global-flap-detection           | - | - | -
279 disable-global-flap-detection          | - | - | -
280 enable-global-event-handlers           | - | - | -
281 disable-global-event-handlers          | - | - | -
282 enable-global-performance-data         | - | - | -
283 disable-global-performance-data        | - | - | -
284 start-global-executing-svc-checks      | - | - | -
285 stop-global-executing-svc-checks       | - | - | -
286 start-global-executing-host-checks     | - | - | -
287 stop-global-executing-host-checks      | - | - | -
288 shutdown-process                       | - | - | -
289 restart-process                        | - | - | -
290
291
292 Examples:
293
294 Reschedule a service check for all services in NOT-OK state:
295
296     $ curl -u root:icinga -k -s 'https://localhost:5665/v1/actions/reschedule-check?filter=service.state!=0&type=Service' -X POST | python -m json.tool
297     {
298         "results": [
299             {
300                 "code": 200.0,
301                 "status": "Successfully rescheduled check for icinga.org!http."
302             },
303             {
304                 "code": 200.0,
305                 "status": "Successfully rescheduled check for icinga.org!disk."
306             },
307             {
308                 "code": 200.0,
309                 "status": "Successfully rescheduled check for icinga.org!disk /."
310             }
311         ]
312     }
313
314
315
316
317 ## <a id="icinga2-api-event-streams"></a> Event Streams
318
319 **TODO** https://dev.icinga.org/issues/9078
320
321 ## <a id="icinga2-api-status"></a> Status and Statistics
322
323 Contains a list of sub url endpoints which provide the status and statistics
324 of available and enabled features. Any filters are ignored.
325
326 Example for the main url endpoint `/v1/status`:
327
328     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/status' | python -m json.tool
329     {
330         "results": [
331             {
332                 "name": "ApiListener",
333                                 "perfdata": [ ... ],
334                                 "status": [ ... ]
335             },
336             ...
337             {
338                 "name": "IcingaAplication",
339                                 "perfdata": [ ... ],
340                                 "status": [ ... ]
341             },
342             ...
343         ]
344     }
345
346 `/v1/status` is always available as virtual status url endpoint.
347 It provides all feature status information into a collected overview.
348
349 Example for the icinga application url endpoint `/v1/status/IcingaApplication`:
350
351     $ curl -k -s -u root:icinga 'https://localhost:5665/v1/status/IcingaApplication' | python -m json.tool
352     {
353         "results": [
354             {
355                 "perfdata": [],
356                 "status": {
357                     "icingaapplication": {
358                         "app": {
359                             "enable_event_handlers": true,
360                             "enable_flapping": true,
361                             "enable_host_checks": true,
362                             "enable_notifications": true,
363                             "enable_perfdata": true,
364                             "enable_service_checks": true,
365                             "node_name": "icinga.org",
366                             "pid": 59819.0,
367                             "program_start": 1443019345.093372,
368                             "version": "v2.3.0-573-g380a131"
369                         }
370                     }
371                 }
372             }
373         ]
374     }
375
376
377 ## <a id="icinga2-api-config-objects"></a> Config Objects
378
379 Provides functionality for all configuration object url endpoints
380 provided by [config object types](6-object-types.md#object-types):
381
382   Url Endpoints                         | Description
383   --------------------------------------|----------------------------------------------------
384   /v1/objects/hosts                     | Endpoint for retreiving and updating [Host](6-object-types.md#objecttype-host) objects.
385   /v1/objects/services                  | Endpoint for retreiving and updating [Service](6-object-types.md#objecttype-service) objects.
386   /v1/objects/notifications             | Endpoint for retreiving and updating [Notification](6-object-types.md#objecttype-notification) objects.
387   /v1/objects/dependencies              | Endpoint for retreiving and updating [Dependency](6-object-types.md#objecttype-dependency) objects.
388   /v1/objects/users                     | Endpoint for retreiving and updating [User](6-object-types.md#objecttype-user) objects.
389   /v1/objects/checkcommands             | Endpoint for retreiving and updating [CheckCommand](6-object-types.md#objecttype-checkcommand) objects.
390   /v1/objects/eventcommands             | Endpoint for retreiving and updating [EventCommand](6-object-types.md#objecttype-eventcommand) objects.
391   /v1/objects/notificationcommands      | Endpoint for retreiving and updating [NotificationCommand](6-object-types.md#objecttype-notificationcommand) objects.
392   /v1/objects/hostgroups                | Endpoint for retreiving and updating [HostGroup](6-object-types.md#objecttype-hostgroup) objects.
393   /v1/objects/servicegroups             | Endpoint for retreiving and updating [ServiceGroup](6-object-types.md#objecttype-servicegroup) objects.
394   /v1/objects/usergroups                | Endpoint for retreiving and updating [UserGroup](6-object-types.md#objecttype-usergroup) objects.
395   /v1/objects/zones                     | Endpoint for retreiving and updating [Zone](6-object-types.md#objecttype-zone) objects.
396   /v1/objects/endpoints                 | Endpoint for retreiving and updating [Endpoint](6-object-types.md#objecttype-endpoint) objects.
397   /v1/objects/timeperiods               | Endpoint for retreiving and updating [TimePeriod](6-object-types.md#objecttype-timeperiod) objects.
398
399 All object attributes are prefixed with their respective object type.
400
401 Example:
402
403     host.address
404
405 Output listing and url parameters use the same syntax.
406
407 ### <a id="icinga2-api-config-objects-joins"></a> API Objects and Joins
408
409 Icinga 2 knows about object relations, e.g. when querying a service object
410 the query handler will automatically add the referenced host object and its
411 attributes to the result set. If the object reference is null (e.g. no event_command
412 defined), the joined results not added to the result set.
413
414 **Note**: Select your required attributes beforehand by passing them to your
415 request. The default result set might get huge.
416
417 Each joined object will use its own attribute name as prefix for the attribute.
418 There is an exception for multiple objects used in dependencies and zones.
419
420 Objects with optional relations (e.g. a host notification does not have services)
421 will not be joined.
422
423   Object Type   | Object Relations (prefix name)
424   --------------|---------------------------------
425   Service       | host, notification, check_command, event_command
426   Host          | notification, check_command, event_command
427   Notification  | host, service, command, period
428   Dependency    | child_host, child_service, parent_host, parent_service, period
429   User          | period
430   Zones         | parent
431
432
433 ### <a id="icinga2-api-config-objects-cluster-sync"></a> API Objects and Cluster Config Sync
434
435 Newly created or updated objects can be synced throughout your
436 Icinga 2 cluster. Set the `zone` attribute to the zone this object
437 belongs to and let the API and cluster handle the rest.
438
439 If you add a new cluster instance, or boot an instance beeing offline
440 for a while, Icinga 2 takes care of the initial object sync for all
441 objects created by the API.
442
443 More information about distributed monitoring, cluster and its
444 configuration can be found [here](13-distributed-monitoring-ha.md#distributed-monitoring-high-availability).
445
446
447 ### <a id="icinga2-api-config-objects-list"></a> List All Objects
448
449 Send a `GET` request to `/v1/objects/hosts` to list all host objects and
450 their attributes.
451
452     $ curl -u root:icinga -k -s 'https://localhost:5665/v1/objects/hosts'
453
454 This works in a similar fashion for other [config objects](9-icinga2-api.md#icinga2-api-config-objects).
455
456
457 #### <a id="icinga2-api-objects-create"></a> Create New Config Object
458
459 New objects must be created by sending a PUT request. The following
460 parameters need to be passed inside the JSON body:
461
462   Parameters    | Description
463   --------------|------------------------------------
464   name          | **Required.** Name of the newly created config object.
465   templates     | **Optional.** Import existing configuration templates for this object type.
466   attrs         | **Required.** Set specific object attributes for this [object type](6-object-types.md#object-types).
467
468
469 If attributes are of the Dictionary type, you can also use the indexer format:
470
471     "attrs": { "vars.os": "Linux" }
472
473 Example fo creating the new host object `google.com`:
474
475     $ curl -u root:icinga -k -s 'https://localhost:5665/v1/objects/hosts/google.com' \
476     -X PUT \
477     -d '{ "templates": [ "generic-host" ], "attrs": { "address": "8.8.8.8", "check_command": "hostalive", "vars.os" : "Linux" } }' \
478     | python -m json.tool
479     {
480         "results": [
481             {
482                 "code": 200.0,
483                 "status": "Object was created."
484             }
485         ]
486     }
487
488 **Note**: Host objects require the `check_command` attribute.
489
490 If the configuration validation fails, the new object will not be created and the response body
491 contains a detailed error message. The following example omits the `check_command` attribute required
492 by the host object.
493
494     $ curl -u root:icinga -k -s 'https://localhost:5665/v1/objects/hosts/google.com' \
495     -X PUT \
496     -d '{ "attrs": { "address": "8.8.8.8", "vars.os" : "Linux" } }' \
497     | python -m json.tool
498     {
499         "results": [
500             {
501                 "code": 500.0,
502                 "errors": [
503                     "Error: Validation failed for object 'google.com' of type 'Host'; Attribute 'check_command': Attribute must not be empty."
504                 ],
505                 "status": "Object could not be created."
506             }
507         ]
508     }
509
510 #### <a id="icinga2-api-object-query"></a> Query Object
511
512 Send a `GET` request including the object name inside the url.
513
514 Example for the host `google.com`:
515
516     $ curl -u root:icinga -k -s 'https://localhost:5665/v1/objects/hosts/google.com'
517
518 You can select specific attributes by adding them as url parameters using `?attrs=...`. Multiple
519 attributes must be added one by one, e.g. `?attrs=host.address&attrs=host.name`.
520
521     $ curl -u root:icinga -k -s 'https://localhost:5665/v1/objects/hosts/google.com?attrs=host.name&attrs=host.address' | python -m json.tool
522     {
523         "results": [
524             {
525                 "attrs": {
526                     "host.address": "8.8.8.8",
527                     "host.name": "google.com"
528                 }
529             }
530         ]
531     }
532
533 #### <a id="icinga2-api-objects-modify"></a> Modify Object
534
535 Existing objects must be modifed by sending a `POST` request. The following
536 parameters need to be passed inside the JSON body:
537
538   Parameters    | Description
539   --------------|------------------------------------
540   name          | **Optional.** If not specified inside the url, this is **required**.
541   templates     | **Optional.** Import existing object configuration templates.
542   attrs         | **Required.** Set specific object attributes for this [object type](6-object-types.md#object-types).
543
544
545 If attributes are of the Dictionary type, you can also use the indexer format:
546
547     "attrs": { "vars.os": "Linux" }
548
549
550 Example for existing object `google.com`:
551
552     $ curl -u root:icinga -k -s 'https://localhost:5665/v1/objects/hosts/google.com' \
553     -X POST \
554     -d '{ "attrs": { "address": "8.8.4.4", "vars.os" : "Windows" } }' \
555     | python -m json.tool
556     {
557         "results": [
558             {
559                 "code": 200.0,
560                 "name": "google.com",
561                 "status": "Attributes updated.",
562                 "type": "Host"
563             }
564         ]
565     }
566
567 #### <a id="icinga2-api-hosts-delete"></a> Delete Host
568
569 You can delete objects created using the API by sending a `DELETE`
570 request. Specify the object name inside the url.
571
572   Parameters    | Description
573   --------------|------------------------------------
574   cascade       | **Optional.** Delete objects depending on the deleted objects (e.g. services on a host).
575
576 **Note**: Objects created by apply rules (services, notifications, etc) will implicitely require
577 to pass the `cascade` parameter on host object deletion.
578
579 Example for deleting the host object `google.com`:
580
581     $ curl -u root:icinga -k -s 'https://localhost:5665/v1/objects/hosts/google.com?cascade=1' -X DELETE | python -m json.tool
582     {
583         "results": [
584             {
585                 "code": 200.0,
586                 "name": "google.com",
587                 "status": "Object was deleted.",
588                 "type": "Host"
589             }
590         ]
591     }
592
593
594 ## <a id="icinga2-api-config-management"></a> Configuration Management
595
596 The main idea behind configuration management is to allow external applications
597 creating configuration packages and stages based on configuration files and
598 directory trees. This replaces any additional SSH connection and whatnot to
599 dump configuration files to Icinga 2 directly.
600 In case you are pushing a new configuration stage to a package, Icinga 2 will
601 validate the configuration asynchronously and populate a status log which
602 can be fetched in a separated request.
603
604 ### <a id="icinga2-api-config-management-create-package"></a> Create Config Package
605
606 Send a `POST` request to a new config package called `puppet` in this example. This
607 will create a new empty configuration package.
608
609     $ curl -k -s -u root:icinga -X POST https://localhost:5665/v1/config/packages/puppet | python -m json.tool
610     {
611         "results": [
612             {
613                 "code": 200.0,
614                 "package": "puppet",
615                 "status": "Created package."
616             }
617         ]
618     }
619
620 ### <a id="icinga2-api-config-management-create-config-stage"></a> Create Configuration to Package Stage
621
622 Send a `POST` request to the url endpoint `/v1/config/stages` including an existing
623 configuration package, e.g. `puppet`.
624 The request body must contain the `files` attribute with the value being
625 a dictionary of file targets and their content.
626
627 The example below will create a new file called `test.conf` underneath the `conf.d`
628 directory populated by the sent configuration.
629 The Icinga 2 API returns the `package` name this stage was created for, and also
630 generates a unique name for the `package` attribute you'll need for later requests.
631
632 Note: This example contains an error (`chec_command`), do not blindly copy paste it.
633
634     $ curl -k -s -u root:icinga -X POST -d '{ "files": { "conf.d/test.conf": "object Host \"cfg-mgmt\" { chec_command = \"dummy\" }" } }' https://localhost:5665/v1/config/stages/puppet | python -m json.tool
635     {
636         "results": [
637             {
638                 "code": 200.0,
639                 "package": "puppet",
640                 "stage": "nbmif-1441625839-0",
641                 "status": "Created stage."
642             }
643         ]
644     }
645
646 If the configuration fails, the old active stage will remain active.
647 If everything is successful, the new config stage is activated and live.
648 Older stages will still be available in order to have some sort of revision
649 system in place.
650
651 Icinga 2 automatically creates the following files in the main configuration package
652 stage:
653
654   File          | Description
655   --------------|---------------------------
656   status        | Contains the [configuration validation](8-cli-commands.md#config-validation) exit code (everything else than 0 indicates an error).
657   startup.log   | Contains the [configuration validation](8-cli-commands.md#config-validation) output.
658
659 You can [fetch these files](9-icinga2-api.md#icinga2-api-config-management-fetch-config-package-stage-files) via API call
660 after creating a new stage.
661
662 ### <a id="icinga2-api-config-management-list-config-packages"></a> List Configuration Packages and their Stages
663
664 List all config packages, their active stage and other stages.
665 That way you may iterate of all of them programmatically for
666 older revisions and their requests.
667
668 The following example contains one configuration package `puppet`.
669 The latter already has a stage created, but it is not active.
670
671     $ curl -k -s -u root:icinga https://localhost:5665/v1/config/packages | python -m json.tool
672     {
673         "results": [
674             {
675                 "active-stage": "",
676                 "name": "puppet",
677                 "stages": [
678                     "nbmif-1441625839-0"
679                 ]
680             }
681         ]
682     }
683
684 ### <a id="icinga2-api-config-management-list-config-package-stage-files"></a> List Configuration Packages and their Stages
685
686 Sent a `GET` request to the url endpoint `/v1/config/stages` including the package
687 (`puppet`) and stage (`nbmif-1441625839-0`) name.
688
689     $ curl -k -s -u root:icinga https://localhost:5665/v1/config/stages/puppet/nbmif-1441625839-0 | python -m json.tool
690     {
691         "results": [
692     ...
693             {
694                 "name": "startup.log",
695                 "type": "file"
696             },
697             {
698                 "name": "status",
699                 "type": "file"
700             },
701             {
702                 "name": "conf.d",
703                 "type": "directory"
704             },
705             {
706                 "name": "zones.d",
707                 "type": "directory"
708             },
709             {
710                 "name": "conf.d/test.conf",
711                 "type": "file"
712             }
713         ]
714     }
715
716
717 ### <a id="icinga2-api-config-management-fetch-config-package-stage-files"></a> Fetch Configuration Package Stage Files
718
719 Send a `GET` request to the url endpoint `/v1/config/files` including
720 the package name, the stage name and the relative path to the file.
721 Note: You cannot use dots in paths.
722
723 You can fetch a [list of existing files](9-icinga2-api.md#icinga2-api-config-management-list-config-package-stage-files)
724 in a configuration stage and then specifically request their content.
725
726 The following example fetches the faulty configuration inside `conf.d/test.conf`
727 for further analysis.
728
729     $ curl -k -s -u root:icinga https://localhost:5665/v1/config/files/puppet/nbmif-1441625839-0/conf.d/test.conf
730     object Host "cfg-mgmt" { chec_command = "dummy" }
731
732 Note: The returned files are plain-text instead of JSON-encoded.
733
734 ### <a id="icinga2-api-config-management-config-package-stage-errors"></a> Configuration Package Stage Errors
735
736 Now that we don’t have an active stage for `puppet` yet seen [here](9-icinga2-api.md#icinga2-api-config-management-list-config-packages),
737 there must have been an error.
738
739 Fetch the `startup.log` file and check the config validation errors:
740
741     $ curl -k -s -u root:icinga https://localhost:5665/v1/config/files/puppet/imagine-1441133065-1/startup.log
742     ...
743
744     critical/config: Error: Attribute 'chec_command' does not exist.
745     Location:
746     /var/lib/icinga2/api/packages/puppet/imagine-1441133065-1/conf.d/test.conf(1): object Host "cfg-mgmt" { chec_command = "dummy" }
747                                                                                                            ^^^^^^^^^^^^^^^^^^^^^^
748
749     critical/config: 1 error
750
751 The output is similar to the manual [configuration validation](8-cli-commands.md#config-validation).
752