I'm trying to send a dict with labels to the check_mk web-api - however the web-api uses python2 - and the devs have insisted on validating that the labels are Unicode.
My example dict in p3:
"": [
{
"condition": {
"service_description": [
{
"$regex": "Callcentre Queue: OTU"
}
]
},
"value": {
u"max_check_attempts": u"3"
},
"options": {
"description": "Label - max_check_attempts\nService - Callcentre Queue: OTU"
}
}]
but when sent, I get the label max_check_attempts must be unicode type
error.
Traceback (most recent call last):
File "./cmk_import.py", line 415, in <module>
process_service_rulelist()
File "./cmk_import.py", line 309, in process_service_rulelist
api().set_ruleset('service_label_rules', total_lbl_ruleset)
File "/usr/local/lib/python3.6/dist-packages/check_mk_web_api/__init__.py", line 724, in set_ruleset
return self.make_request('set_ruleset', data=data, query_params={'request_format': 'python'})
File "/usr/local/lib/python3.6/dist-packages/check_mk_web_api/__init__.py", line 164, in make_request
raise CheckMkWebApiException(result)
check_mk_web_api.exception.CheckMkWebApiException: Check_MK exception: ERROR: The label ID 'max_check_attempts' is of type <type 'str'>, but should be unicode. Affected Rule {'value': {'max_check_attempts': '3'}, 'condition': {'service_description': [{'$regex': 'Callcentre Queue: OTU'}]}, 'options': {'description': 'Label - max_check_attempts\nService - Callcentre Queue: OTU'}}
Error is from checkMK itself issued by the check_mk web-api. As the listening agent is Python2 - it's trying to validate type()
as unicode
I know that P3 has incorporated unicode
into str
- but wondering if there is a way to override and keep the dict unicode chars without rewriting the affected parts in python2
.
Web request is handled by this lib - https://github.com/brennerm/check-mk-web-api
request = urllib.request(self._build_request_path(query_params),WebApi._build_request_data(data, request_format))
The contents of which are: Arg1:
http://localhost/preprod/check_mk/webapi.py?effective_attributes=0&action=get_all_hosts&_username=automation&_secret=foobar
And Snippet:
{%27condition%27: {%27service_description%27: [
{%27%24regex%27: %27VPN: Premier Ping - 1.1.1.1%27}
]}, %27value%27:
{%27check_interval%27: %275%27, %27max_check_attempts%27: %273%27, %27retry_interval%27: %271%27, %27check_period%27: %2724x7%27, %27notification_period%27: %2724x7%27, %27notification_interval%27: %27120%27, %27notifications_enabled%27: %271%27, %27active_checks_enabled%27: %271%27, %27check_freshness%27: %270%27, %27event_handler_enabled%27: %271%27, %27flap_detection_enabled%27: %271%27, %27is_volatile%27: %270%27, %27obsess_over_service%27: %271%27, %27passive_checks_enabled%27: %271%27, %27process_perf_data%27: %271%27, %27retain_nonstatus_information%27: %271%27, %27retain_status_information%27: %271%27}
, %27options%27: {%27description%27: %27Labels for Service - VPN: Premier Ping - 1.1.1.1%27}}
The API client sends the data in what it terms "python" format which is basically a dict that has had
str()
called on it. The intention is that the server will callast.literal_eval()
on this dictionary string. The client does the same with the body of the response. converting it back to a Python dict.Throughout the API there are places where it does support JSON for request/response processing, and this can be set in the query params for some functions. Unfortunately, for the particular request that is failing here (set_ruleset) JSON is not an option.
It's not obvious why the server is failing to process this request. I have tried unquoting the body of the message and running that through
literal_eval()
in Python 2, and it seems to work.One thing that I did notice is the embedded new line character in the request dict
"Label - max_check_attempts\nService - Callcentre Queue: OTU"
. It's probably what the server is complaining about when it mentions "label ID 'max_check_attempts'".Further problem tracing would require looking at the server logs and possibly the code to see what's going on there.