How to assign service (template) to host (template) using Icinga director CLI or REST API


(Dmitry) #1

Hello everyone.

This post is related to: How to employ applyrules using director via CLI or REST API?, as a one another way how to make a fully automated deployment of the system.

Within a deployment, I need to be able to assign service templates to host templates via Director API. Unfortunately, provided description of API is limited to dealing with hosts objects. Fair enough, it is reasonably easy to understand how to create and work with other types of objects (except applyrules, as it is pointed in the issue above).

Terra incognita for me remains how to assign already existing service template to an already existing host template.
Using WUI it is relatively easy to do. But how to do that using API or CLI?
Looking at the behavior of the WUI when I’m doing so, I found that to add a service to the host, it makes POST request on the following URL:


with the following content:

__FORM_NAME    IcingaModuleDirectorFormsIcingaAddServiceForm
__FORM_CSRF    xxx
imports     apt_service_t
object_name    apt_service_t
Add         Add  

where linux_host_t is a host template:

template Host "linux_host_t" {
    display_name = "Linux Host"
    check_command = "ping"

and apt_service_t is a service template:

  template Service "apt_service_t" {
    check_command = "apt"
    command_endpoint = host_name

As I understood, adding services to the hosts employs applyrules as well. So, in the result of adding service to the host via WUI, it creates the following object:

apply Service "apt_service_t" {
    import "apt_service_t"

    assign where "linux_host_t" in host.templates

    import DirectorOverrideTemplate

My attempts to employ mentioned URL via API to achieve assignment of service to host is not succeeded.

Parameters __FORM_NAME, __FORM_CSRF, and Add are WUI oriented, and moreover, REST API does not allow to use them. In this issue it is mentioned that CSRF is used only for WUI, and it must not affect API users. I can only assume that routing inside of an application in some parts repeats itself for both WUI users and API users.

Reducing parameters to only import and object_name gives me an error when I execute the POST request:

./ POST director/host/service?name=linux_host_t '{"imports":"apt_service_t", "object_name":"apt_service_t"}'
HTTP/1.1 404 Not Found
Date: Wed, 09 Jan 2019 15:37:49 GMT
Server: Apache/2.4.29 (Ubuntu)
X-Powered-By: PHP/7.2.10-0ubuntu0.18.04.1
Content-Length: 64
Content-Type: application/json

    "error": "Failed to load icinga_host \"apt_service_t\""

Obviously, it attempts to find host template to put it in the filed "imports" of object linux_host_t (host template).

If to get rid of field import, the result of POST will be successful… but it will just change field object_name of the object linux_host_t, so form this moment we do not have object linux_host_t but we have two object apt_service_t, one is host template and another is service template.

So, my assumption that WUI users and API users have the same routes is not correct.

Further plays with URI and body haven’t given me the result I wanted to achieve.

My question to the community:
Is there any way how to assign service (template) to the host (template) using API or CLI?

Thanks in advance.

What do we need to automate for Icinga?
(Emmanuel Gos) #2

My first post on this forum and yet it was of great help till now. Thx to the icinga team for that.

May I suggest :

  • instead of using this condition. which clearly use internal mechanic of the product.

You might want to use the groups option.
So on the hosts, it’s quite easy to handle groups. It’s even in the API documentation.

And than the condition become
assign where “linux” in host.groups

That way you’ll be able to assign services to actual system services whatever the host they are running on.

My 2 cents.