Set and delete downtime with REST API

Hi,

I have a hook which creates and deletes hosts from check_mk, it should set and remove downtime when stopping or starting the instance in our virtualization environment. With the HTTP API it was working without any problems in a distributed monitoring environment.

Now when using the REST API, setting a downtime only works for hosts monitored by the master, when trying it with hosts monitored by a slave, i still get the resp.status_code 204, but the downtime is not set.

I tried it with multiple hosts monitored by the master and hosts monitored by different slaves, the downtime was only set to those monitored by the master.

Any idea how to make it work?

I am running check-mk-raw-2.0.0p5 as a distributed monitoring environment.

Thanks

As far as i know - you have to sent the downtime API request to the host the machine is monitored on.
But this can also be a bug or a design problem. I think someone has already tested this with a enterprise edition to say that it is also the same way there or that it is working. If it working inside the enterprise then it is a bug/limitation of the raw.
But i cannot say at the moment if it is this way. Normally it should be possible over the master as most times the single slaves are not reachable for every user.

Well, I hope it is not a limitation problem pf the RAW, since setting downtime is possible with the HTTP API up to 2.0.0.p5, which I am currently using. Hope it is just s bug.
It doesn’t make a sense sending API requests to the respective slave for these operations, I always thought using the API for some actions is a as good as using WATO as long as the API supports it, so this shouldn’t be a new limitation of the RAW. But who knows.

Thanks @andreas-doehler

then probably it should work as it was with the web url, i.e. https://monitor.master/master/check_mk/view.py

I’ll use the respective slave. Thanks Andreas.

did you find a way to schedule a service downtime using web API?

host downtime works fine but i just cannot find a way to do service. not sure which view it will be

Yes, you need to use a different url for downtimes:

url = https://monitoring.server/master/check_mk/view.py

Then you need to figure out if a downtime already set, maybe something like this:

params = {
    '_username': 'automation',
    '_secret': 'secret',
    'output_format': 'JSON',
    'host_regex': 'host01',
    'view_name': 'downtimes'
}
response = requests.get(url, params=params).txt
response_json = json.loads(response)
if len(response_json) == 1:
    host_is_down = False
else:
    host_is_down = True

If no downtime is set, you can set one:

params = {
     '_do_confirm': 'yes',
     '_do_actions': 'yes',
     '_transid': '-1',
     '_username': 'automation',
     '_secret': 'secret',
     'output_format': 'JSON'
     'view_name': 'host',
     'host': 'host01',
     '_on_hosts': 'on',
     '_downrange__next_year': 'This+year',
     '_down_comment': 'my comment'
}

response = requests.post(url, params=params)

I hope this help

Thanks I managed to find that out myself not long after I asked.

I have the one for a host downtime but not a service previously.

Hi, you can start with /opt/omd/versions/2.0.0p5.cre/share/doc/check_mk/treasures/downtime.py script. It has all you need.

1 Like

Thanks.

I am aware of this script but it relies on Literal which is only available on python 3.8+. We are running RHEL7, the latest on it is still 3.6.8.

you can just refactor the code fragment you need without the Literal, so Literal basically ensures that some expression has literally a specific value, this code for instance ensures that mode is one of the list members:

DowntimeMode = Literal[
    "host",
    "service",
    "hostgroup",
    "servicegroup",
]  # yapf: disable

but it can be written this way and ensure that mode is a member of DowntimeMode::

DowntimeMode = [
    "host",
    "service",
    "hostgroup",
    "servicegroup",
]  # yapf: disable

if mode not in DowntimeMode:
    raise RuntimeError("Unsupported downtime mode: {}".format(mode))

Anyways you still have the option to use the old script as well, it can be found here

I definitely suggest you to use the downtime example in the REST API documentation:

#!/usr/bin/env python3
import pprint
import requests

HOST_NAME = "localhost"
SITE_NAME = "production"
API_URL = f"http://{HOST_NAME}/{SITE_NAME}/check_mk/api/1.0"

USERNAME = "automation"
PASSWORD = "test123"

session = requests.session()
session.headers['Authorization'] = f"Bearer {USERNAME} {PASSWORD}"
session.headers['Accept'] = 'application/json'

resp = session.post(
    f"{API_URL}/domain-types/downtime/collections/service",
    headers={
        "Content-Type": 'application/json',  # (required) A header specifying which type of content is in the request/response body.
    },
    # This schema has multiple variations. Please refer to
    # the 'Payload' section for details.
    json={
        'start_time': '2017-07-21T17:32:28Z',
        'end_time': '2017-07-21T17:32:28Z',
        'recur': 'hour',
        'duration': 3600,
        'comment': 'Security updates',
        'downtime_type': 'service',
        'host_name': 'example.com',
        'service_descriptions': [
            'CPU utilization', 'Memory'
        ]
    },
)
if resp.status_code == 200:
    pprint.pprint(resp.json())
elif resp.status_code == 204:
    print("Done")
else:
    raise RuntimeError(pprint.pformat(resp.json()))

more examples can be found in your check_mk installation → Help → REST API documentation

1 Like

Yep referring to that script was exactly what I did to get that resolved.

Thanks.

1 Like

Hi all,

i am using 2.0.0p9 (CEE) and i can not create a host-related downtimes via rest api. I also get a status-code 204. It does not matter which site the host belongs to. It neither works on the master site nor a slave one. I would realy like to use it in ansible-playbooks. I would be very grateful for a suggested solution.

I have solved my problem, i did not gave a duration, because i thought i would be calculated. but it might be not calculated. So if i set the duration correctly in the json request data. it works.

Kind regards
Oliver