I am at wits end.
My scenario is that I am using python requests to interact with Icinga2 API and I am trying to schedule a downtime. So I know how that is supposed to works and it works most of time. But unfortunately I am totally out of luck when the Icinga2 service I try to set a downtime to has name with a backslash in it.
My test environment:
- Icinga2 2.9.0
- Python 3.6.8 / Python 3.8.11
- requests 2.27.0
Prerequisite: Create a host in Icinga. Create a service in Icinga with a "\"-character.
Python Code for Reproduction:
import requests
session = requests.Session()
session.hooks = {
"response": lambda r, *args, **kwargs: r.raise_for_status()
}
session.headers.update(
{
"Accept": "application/json",
"Content-Type": "application/json",
"cache-control": "no-cache",
}
)
session.auth = requests.auth.HTTPBasicAuth("user","password")
url = "https://icinga2-server.com:5665/v1/actions/schedule-downtime"
body = {
'comment': 'Downtime',
'author': ('icingaadmin',),
'start_time': 1605196800.0,
'filter': 'host.name==\"HOSTNAME\" && service.name==\"SERVICE\\NAME\"',
'end_time': 1605286800.0,
'fixed': True,
'type': 'Service'}
session.post(url, json=body, verify=False)
Result:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/root/.pyenv/versions/3.8.11/lib/python3.8/site-packages/requests/sessions.py", line 590, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "/root/.pyenv/versions/3.8.11/lib/python3.8/site-packages/requests/sessions.py", line 542, in request
resp = self.send(prep, **send_kwargs)
File "/root/.pyenv/versions/3.8.11/lib/python3.8/site-packages/requests/sessions.py", line 662, in send
r = dispatch_hook('response', hooks, r, **kwargs)
File "/root/.pyenv/versions/3.8.11/lib/python3.8/site-packages/requests/hooks.py", line 31, in dispatch_hook
_hook_data = hook(hook_data, **kwargs)
File "<stdin>", line 2, in <lambda>
File "/root/.pyenv/versions/3.8.11/lib/python3.8/site-packages/requests/models.py", line 953, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://icinga2-server.com:5665/v1/actions/schedule-downtime
I know very well that this error message indicates that Icinga2 could not find/match a service. But executing the command via curl is clearly working for me and I get a proper scheduled downtime!
CURL Request:
curl -k -s -u user:password -H 'Accept: application/json' -X POST 'https://icinga2-server.com:5665/v1/actions/schedule-downtime' -d '{"comment": "Downtime", "author": ["icingaadmin"], "start_time": 1605196800.0, "filter": "host.name==\"MSSQLSERVER\" && service.name==\"MSSQLSERVER\\\\INSTANCE2\"", "end_time": 1605286800.0, "fixed": true, "type": "Service"}'
CURL Answer (SUCCESS):
{"results":[{"code":200.0,"legacy_id":8.0,"name":"MSSQLSERVER!MSSQLSERVER\\INSTANCE2!137c9ef9-3150-4e57-ba0b-a22ddc6611d4","status":"Successfully scheduled downtime 'MSSQLSERVER!MSSQLSERVER\\INSTANCE2!137c9ef9-3150-4e57-ba0b-a22ddc6611d4' for object 'MSSQLSERVER!MSSQLSERVER\\INSTANCE2'."}]}
Alternate approaches that did not help:
session.post(url, data=json.dumps(body), verify=False)
string_body = json.dumps(body)
session.post(url, data=string_body, verify=False)