HW/SW inventory rules in RestAPI

Hi,
This is another one of these “Python dict in JSON response” madness.

I’m trying to create a default SW/HW inventory rule. I created one manually (Like I normally do) in the GUI and do a GET request to find the parameters in the correct format using the RestAPI.

For this rule the value raw contains an empty dict like {}
This is not that normal, normally the value_raw is “False” in these cases…

This makes it hard (impossible) to use Ansible to create Inventory rules. Anyone have an idea?

I’m hoping 2.4 could have a true RestAPI that’s not broken, please… :slight_smile:

The value in value_raw is always a string.
However the implementation is bizarre.

You can do things like this (as you indicated already).

value_raw = 'True'
value_raw = '42'

But the handling of a dict is really bizarre, you do not process it as json at all, in fact, if you try that you get a whole bunch of errors.

These two functions below worked for me, but ymmv.

import ast

def value_raw_to_dict(value_raw: str) -> dict:
    return ast.literal_eval(raw)

def dict_to_value_raw(value: dict) -> str:
   return value.__str__()

If you need strings in the value, for example agent in a host_check_command rule.
Then you must set it like this:

value_raw = "'agent'"

While you can set numbers like shown above, there is one more peculiarity that i have found which is absolute bonkers.
This is if the number is to indicate the index value of a dropdown box.
If there is a dropdown involved, you must follow the same rule as for strings, so to select the first item from a dropdown box you must do:

value_raw = "'0'"

Otherwise it will return with an error that sends you on a wild goose chase.

These are things that i found out arbitrarily. (Check mk version 2.1.0p44 and some earlier versions, so ymmv if you have a different version).

I have not tested this, but perhaps if the value raw needs to be empty, you can get away by setting its value to None in Python?

Btw, i’m using requests as the basis for the API calls as per the examples in REDOC, which for the most part seem to work.

I found that the REST API itself is inconsistent in places.

According to the chapter ‘JSON envelope attributes for objects’ in the Redoc documentation, in the example of the envelope it shows that the unique identifier is: ‘instanceId’.

However i have found that throughout various CRUD API calls it can be one of these keys: ‘id’, ‘ident’, ‘title’, ‘name’, ‘description’, ‘alias’
These are all used in one call or another, ‘instanceId’ on the other hand is not used anywhere as far as i can find.

Like you i also hope that in 2.4 they will revisit the API, and make a 2.0 version that is consistent across the board, and does handle value_raw and many other things in a consistent and more logical way that is also in-line with terminology that is used in the user interface.

I learned a lot about the API by writing an API client in Python for it, but i’m sure i haven’t found all the strange things yet.

Thats not true, in multiple cases its experts a DICT (but wrapped as a string obviously as you can’t have a python dict in JSON)

Nothing I have tried have worked for the HW inventory ruleset.

(To be fair, i may have updated my original reply before you posted because i found an issue with it, but i did not see your reply when i did that).

As per the REDOC documentation:

value_raw	
string
The raw parameter value for this rule. To create the correct structure, for now use the 'export for API' menu item in the Rule Editor of the GUI. The value is expected to be a valid Python type.

In other words, value_raw must be a string, whatever the contents you put into it.

Also, there is no JSON involved.

json.dumps() and json.loads() don’t work for value_raw, they bug out under some circumstances.
(That’s why i changed my initial reply, i was actively working on code that used it.)

you can set the value of value_raw to variable.__str__() in almost all cases
However in case of boolean, integer or float values, you cannot. But when the integer value needs to represent the index of a dropdown box, then again you must do that. So it’s a bit weird.

I’m not so much into how Checkmk handle this, I’m interested in the JSON encoded Rest API endpoint. Ansible will escape strings containing structure that can be treated as DICT or LIST when using the correct content-encoding.

Some rules expects the string to be a LIST (for example deploy local files with agent) and some expects the string to contain a DICT (for example the above rule)

The problem with this rule it seems it expects an empty DICT (as seen on my example) and there is no way to re-produce that in Ansible. it will be escaped and as such the string will no longer be valid.

Ok, i see the problem.
In that case, i would suggest that you just take one of the examples from the REDOC documentation for “requests” and put that in a separate python module and have ansible install & execute that module.
For simplicity you could just 1 on 1 copy the code from the examples and adapt the values as needed. That’s where i started when building my checkmk api client. This way you have full control over everything, and you can still have ansible do all the work.

I managed to solve the problem, value_raw should contain data, it was just that the rule I used as a reference when using GET did not have one.

One I populated the value_raw it worked fine, it just seems its hard to impossible to create a rule without value_raw for SW/HW inventory.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed. Contact an admin if you think this should be re-opened.