反斜杠编码不正确
Backslashes are not correctly encoded
我已经无计可施了
我的情况是我正在使用 python 请求与 Icinga2 API 进行交互,并且我正在尝试安排停机时间。所以我知道它应该如何工作并且大部分时间都有效。但不幸的是,当我尝试将停机时间设置为名称中带有反斜杠的 Icinga2 服务时,我完全不走运。
我的测试环境:
- Icinga2 2.9.0
- Python 3.6.8 / Python 3.8.11
- 请求 2.27.0
先决条件:在 Icinga 中创建主机。使用“\”字符在 Icinga 中创建服务。
Python 复制代码:
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)
结果:
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
我很清楚这个错误消息表明 Icinga2 无法 find/match 服务。但是通过 curl 执行命令显然对我有用,我得到了适当的计划停机时间!
CURL 请求:
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 答案(成功):
{"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'."}]}
没有帮助的替代方法:
session.post(url, data=json.dumps(body), verify=False)
string_body = json.dumps(body)
session.post(url, data=string_body, verify=False)
您可以尝试在过滤键后的字符串前面加一个r。另外,我认为这个右括号是不必要的。
Python 将字符串中的反斜杠视为特殊字符,在字符串前添加 'r' 使其不将其视为特殊字符,而是将其视为反斜杠
'filter': r'host.name=="HOSTNAME" && service.name=="SERVICE\NAME"'),
https://www.journaldev.com/23598/python-raw-string
body1 = {
'comment': 'Downtime',
'author': ('icingaadmin',),
'start_time': 1605196800.0,
'filter': 'host.name==\"HOSTNAME\" && service.name==\"SERVICE\NAME\"',
'end_time': 1605286800.0,
'fixed': True,
'type': 'Service'}
body2 = {
'comment': 'Downtime',
'author': ('icingaadmin',),
'start_time': 1605196800.0,
'filter': r'host.name==\"HOSTNAME\" && service.name==\"SERVICE\NAME\"',
'end_time': 1605286800.0,
'fixed': True,
'type': 'Service'}
body1==body2 -> False
body1['filter'] = 'host.name=="HOSTNAME" && service.name=="SERVICE\NAME"'
body2['filter'] = 'host.name==\"HOSTNAME\" && service.name==\"SERVICE\\NAME\"'
非常感谢您的支持。我想到了。我能够使用 Leo Wotzak 击败我的以下命令成功设置停机时间。
body1 = {
'comment': 'Downtime',
'author': ('icingaadmin',),
'start_time': 1605196800.0,
'filter': 'host.name==\"HOSTNAME\" && service.name==\"SERVICE\\NAME\"',
'end_time': 1605286800.0,
'fixed': True,
'type': 'Service'}
我不知道为什么我没有早点 运行 用 4 个反斜杠进行测试。
并为情况添加一些背景信息。最初的问题是,我正在读取可用的 icinga 服务的输出,这给了我:
>>>> resp.json()['results'][1]['name']
'MSSQLSERVER!SERVICE\NAME'
如果我将该答案放入正文中,它将失败,因为 json 转换器不会将 2 个反斜杠转换为 4 个反斜杠。问题是,告诉 json 2 个反斜杠需要 4 个反斜杠的最佳方法是什么?我的想法是使用编码:
svc_name = resp.json()['results'][1]['name'].encode("unicode-escape").decode("utf-8")
我不知道这是否是最好的方法,但它确实有效。
我已经无计可施了
我的情况是我正在使用 python 请求与 Icinga2 API 进行交互,并且我正在尝试安排停机时间。所以我知道它应该如何工作并且大部分时间都有效。但不幸的是,当我尝试将停机时间设置为名称中带有反斜杠的 Icinga2 服务时,我完全不走运。
我的测试环境:
- Icinga2 2.9.0
- Python 3.6.8 / Python 3.8.11
- 请求 2.27.0
先决条件:在 Icinga 中创建主机。使用“\”字符在 Icinga 中创建服务。
Python 复制代码:
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)
结果:
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
我很清楚这个错误消息表明 Icinga2 无法 find/match 服务。但是通过 curl 执行命令显然对我有用,我得到了适当的计划停机时间!
CURL 请求:
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 答案(成功):
{"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'."}]}
没有帮助的替代方法:
session.post(url, data=json.dumps(body), verify=False)
string_body = json.dumps(body)
session.post(url, data=string_body, verify=False)
您可以尝试在过滤键后的字符串前面加一个r。另外,我认为这个右括号是不必要的。
Python 将字符串中的反斜杠视为特殊字符,在字符串前添加 'r' 使其不将其视为特殊字符,而是将其视为反斜杠 'filter': r'host.name=="HOSTNAME" && service.name=="SERVICE\NAME"'),
https://www.journaldev.com/23598/python-raw-string
body1 = {
'comment': 'Downtime',
'author': ('icingaadmin',),
'start_time': 1605196800.0,
'filter': 'host.name==\"HOSTNAME\" && service.name==\"SERVICE\NAME\"',
'end_time': 1605286800.0,
'fixed': True,
'type': 'Service'}
body2 = {
'comment': 'Downtime',
'author': ('icingaadmin',),
'start_time': 1605196800.0,
'filter': r'host.name==\"HOSTNAME\" && service.name==\"SERVICE\NAME\"',
'end_time': 1605286800.0,
'fixed': True,
'type': 'Service'}
body1==body2 -> False
body1['filter'] = 'host.name=="HOSTNAME" && service.name=="SERVICE\NAME"'
body2['filter'] = 'host.name==\"HOSTNAME\" && service.name==\"SERVICE\\NAME\"'
非常感谢您的支持。我想到了。我能够使用 Leo Wotzak 击败我的以下命令成功设置停机时间。
body1 = {
'comment': 'Downtime',
'author': ('icingaadmin',),
'start_time': 1605196800.0,
'filter': 'host.name==\"HOSTNAME\" && service.name==\"SERVICE\\NAME\"',
'end_time': 1605286800.0,
'fixed': True,
'type': 'Service'}
我不知道为什么我没有早点 运行 用 4 个反斜杠进行测试。
并为情况添加一些背景信息。最初的问题是,我正在读取可用的 icinga 服务的输出,这给了我:
>>>> resp.json()['results'][1]['name']
'MSSQLSERVER!SERVICE\NAME'
如果我将该答案放入正文中,它将失败,因为 json 转换器不会将 2 个反斜杠转换为 4 个反斜杠。问题是,告诉 json 2 个反斜杠需要 4 个反斜杠的最佳方法是什么?我的想法是使用编码:
svc_name = resp.json()['results'][1]['name'].encode("unicode-escape").decode("utf-8")
我不知道这是否是最好的方法,但它确实有效。