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