REST API v2.2 host labels

It has been fun to find out the hard way, that reading & writing/updating host labels via the API has some issues.

How to get/post/put host labels is explained in this video starting around minute 10. Working with the Checkmk REST API
What this video forgets to mention, is when writing host properties this way, all host properties NOT fed via the json will be dropped! Seems like a massive flaw/bug.

via the swagger ui (http://yourmkserver/yoursite/check_mk/api/1.0/ui/#) you can test and reproduce easily

GET /objects/host/config/{host_name} will return a json and etag in the response headers.

if you now want to add 1 host label, using PUT /objects/host/config/{host_name} you need to feed the entire attributes block, minus the meta-data.
Nothing like this is explained in the aforementioned video.

If you don’t do that, you only lose all properties, like the host ip. and every other tag & label under attributes.

Yes, I agree it is quite the surprising behavior and has been that way since the introduction of the rest-api. I honestly feel tags/labels need their own CREATE/MODIFY/DELETE calls. The way it is today it is basically going under the hood and updating the host object db directly with the attendant flaws you found.

With 2.3 this is not the case anymore.
You can update single attributes with a call like this.

    resp = session.put(
        f"{API_URL}/objects/host_config/{hostname}",
        headers={
            "If-Match": etag,
            "Content-Type": 'application/json',
        },
        json={
            'update_attributes': {
                'ipaddress': ip
            },
        },
    )

This will only change the IP and keep all other attributes as they are.
The same you can do with the labels. It is true that all the labels need to be included in the update statement as all the labels are only one attribute.
But you don’t need to write the whole host configuration every time you need to change one attribute.

2 Likes

I tested this with v2.2:

In your example the attribute ‘ipaddress’ gets updated, and all other attributes are left alone. This is actually working the same in v2.2 from what i have tested.

Host labels are in the “labels” attribute. And you can update labels without changing any other attribute within the host object using your example, that also works in v2.2.

Given is a host with labels: {“label1”: “1”, “label2”, “2”}.

Given the example code below which follows your example, Logically as per your description, you could assume that after executing the api call, the host would have a new label “label3”.

While there is indeed a new label label3 on the host, the labels 1 and 2 were removed.

This is because the API call does a literal overwrite of the value that is provided. And since the “labels” attribute is a dict, it overwrites the entire dict, not just a part of it. And this is the fact that the original poster means with you having to provide everything in the API call.

And i do not think that this behavior has changed in Check Mk 2.3.

The documentation for update host has not changed between 2.2 and 2.3.

The other poster mentioned host tags.

These work differently. There is no “tags” dictionary, rather each host tag is in its own attribute and has the prefix “tag_”. So with the example code, only a single host tag would be changed on the host if, all others would remain the same.

/—————————————————————-/

resp = session.put(
f"{API_URL}/objects/host_config/{hostname}",
headers={
“If-Match”: etag,
“Content-Type”: ‘application/json’,
},
json={
‘update_attributes’: {
‘labels’: {“label3”: “3”}
},
},
)