How to create a ServiceGroup dynamically?

I have recently discovered how useful servicegroups are to me, and since I create all my host and service objects dynamically through the REST API, I would like to also create the servicegroups that way. The reason for this that when I create a new servicegroup in /etc/icinga2/zones.d/global-templates/groups.conf and restart the service, all my services disappear until the passive checks get run - I’d like to avoid that.

I feel pretty sure it can be done - ServiceGroup is just another object - but I am not sure how to specify this:

object ServiceGroup "CPU-throttle" {
    display_name = "CPU-throttle"
    assign where service.display_name == "CPU-throttle"
}

Where do I put the assign?

You mean, in which file? It doesn’t matter as long as the file is available on the host where you need the Servicegroup, so normally in a *.conf file within /etc/icinga2/zones.d/master.

I’m not totally sure but it could be that the apply rules are only evaluated on a reload/restart but now when you add an object via API.

1 Like

No, I mean, I’d like to create a ServiceGroup through the REST API - similar to this example (from https://itgix.com/blog/post/icinga2-api-and-passive-checks/)

curl -k -s -u root:icinga -H 'Accept: application/json' -X PUT 'https://localhost:5665/v1/objects/hosts/example.localdomain' -d '{ "templates": [ "generic-host" ], "attrs": { "address": "192.168.1.1", "check_command": "hostalive", "vars.os" : "Linux" } }' 

although I would do it in python. The thing is, the first time I report from a passive check, I first check that the service object exists, and create it if it doesn’t - and the same for the host object. And since I am going to write several new, passive checks in the future, and I want to have a service group to summarise each of them, it would be good to be able to create them on the fly. As far as I can see, it ought to be possible - a ServiceGroup is an object, after all, but I’m not sure where to put the assign where ... bit.

You don’t have to use apply rules for assigning groups. If you are using the API you can have all your logic for adding objects to groups in your external tool which talks to the API. In this case you can still use the “old” approach of defining groups with all of their members.

I think, you can’t add apply rules by API nonetheless, but I’m not sure about that.

1 Like

Hmm, so in order to add members to a service group, I would have to first get the object through the API, then modify it and PUT the modified ServiceObject back through the API? But there does not actually seem to be any way to add members to a ServiceGroup object, since it does contain anything that refers to its membership:

[root@zenoss ~]# curl -k -s -u summat:other 'https://zenoss.hpc.imperial.ac.uk:5665/v1/objects/servicegroups/checkmem' | python -m json.tool
{
    "results": [
        {
            "attrs": {
                "__name": "checkmem",
                "action_url": "",
                "active": true,
                "display_name": "checkmem",
                "groups": null,
                "ha_mode": 0.0,
                "name": "checkmem",
                "notes": "",
                "notes_url": "",
                "original_attributes": null,
                "package": "_etc",
                "paused": false,
                "source_location": {
                    "first_column": 1.0,
                    "first_line": 45.0,
                    "last_column": 30.0,
                    "last_line": 45.0,
                    "path": "/etc/icinga2/zones.d/global-templates/groups.conf"
                },
                "templates": [
                    "checkmem"
                ],
                "type": "ServiceGroup",
                "vars": null,
                "version": 0.0,
                "zone": "global-templates"
            },
            "joins": {},
            "meta": {},
            "name": "checkmem",
            "type": "ServiceGroup"
        }
    ]
}

This ServiceGroup object was specified in the .conf as:

object ServiceGroup "checkmem" {
    display_name = "checkmem"
    assign where service.display_name == "checkmem"
}

You can not create an object twice. Either use the API or the config file.

For using the API you have 2 options:

  • Use bulk mode where you upload full configuration files. You will have to always put the whole file up, not only the changes
  • Create the object via API as a single object. You can then modify it via API

Sorry, I wasn’t clear - this ServiceGroup was defined in the config file, and I used the API to get it from the server; I was looking for clues as to how I could add services as members to the servicegroup, but it isn’t obvious.

I haven’t come across bulk mode in the documentation - is it documented somewhere?

Yes, what I called “bulk mode” is this:

https://icinga.com/docs/icinga2/latest/doc/12-icinga2-api/#configuration-management

There you just upload configuration as a whole and don’t bother with creating single objects. This is what Director uses and ist mostly suitable if you are managing big blocks of configuration within an external tool.

I don’t think you can add services via API to a service group that was created by configfile. Either completely via API or completely in a file.

1 Like

This may be workable - I’ll investigate further.

1 Like