Checkmk / ansible-collection-checkmk.general

The official Checkmk Ansible collection - brought to you by the Checkmk company.
https://galaxy.ansible.com/checkmk/general
GNU General Public License v3.0
118 stars 55 forks source link

[BUG] value_raw set to a variable #186

Open clagio opened 1 year ago

clagio commented 1 year ago

Describe the bug I'm trying to set the value of value_raw to a variable instead of hardcoding it in the task, so I can reuse the same task for multiple rules. Unfortunately I get the error "Unsupported type. Field must be string". The same task with the value_raw explicitly set works fine. Seems to be an escaping issue, and I'm not 100% the issue is with the collection honestly.. but I'm banging my head on this so any help is appreciated.

Component Name tribe29.checkmk.rule

Ansible Version

$ ansible --version
ansible 2.10.8
python version = 3.9.2 (default, Feb 28 2021, 17:03:44) [GCC 10.2.1 20210110]

Checkmk Version

Checkmk Raw Edition 2.1.0p13

Collection Version

$ ansible-galaxy collection list
tribe29.checkmk   0.11.0

To Reproduce Steps to reproduce the behavior: Execute this task:

    - name: "Create a rule."
      tribe29.checkmk.rule:
        server_url: "{{ hostvars['checkmk'].checkmk_url }}"
        site: "{{checkmk_site}}"
        automation_user: "{{ hostvars['checkmk'].checkmk_user }}"
        automation_secret: "{{ hostvars['checkmk'].checkmk_secret }}"
        ruleset: "checkgroup_parameters:memory_percentage_used"
        rule:
            properties: {
                "comment": "Warning at 80%\nCritical at 90%\n",
                "description": "Allow higher memory usage",
                "disabled": false
            }
            value_raw: "{{ myvariable }}"
        state: "present"
      vars:
        - myvariable: "{'levels': (80.0, 90.0)}"

If I replace value_raw: "{{ myvariable }}" to value_raw: "{'levels': (80.0, 90.0)}" the task works fine.

Expected behavior Rule to be created using the value in "myvariable"

Actual behavior The following error is printed:

"msg": "Error calling API. HTTP code 400. Details: b'{\"title\": \"Bad Request\", \"status\": 400, \"detail\": \"These fields have problems: value_raw\", \"fields\": {\"value_raw\": [\"Unsupported type. Field must be string.\"]}}', "

Additional context I suspect the issue is caused by the curly bracket required by the API which make ansible interpret the variable's value as a dictionary instead of a string. But I couldn't find a way to escape that and make it works with the API.

robin-checkmk commented 8 months ago

@pandvan the second issue you are mentioning is out of the scope of this issue. But you can control, where rules are created and if you want to be 100% certain of their position, you can look up the existing rules with the new lookup plugins, which we just released. Anyway, regarding this specific aspect, please open a dedicated issue, if you feel like this is something we should discuss.

Regarding the main discussion, I have no update yet.

Mik3yZ commented 8 months ago

in issue #523 I described the issue we are facing, which is in fact the same issue as described here. Characters get replaced in value_raw when using ansible.

While using the exact same value_raw via Swagger UI, it works as expected. I did read this entire issue, however not really sure what the exact issue is now, or what a workaround for the issue is.

in regards of the main discussion, i am not into API/ansible enough to provide any valuable input there.

Mik3yZ commented 8 months ago

So i have fixed the conversion issue by just passing the value_raw as a string to the ansible module:

  checkmk.general.rule:
    automation_secret: "{{ automation_secret }}"
    automation_user: "{{ automation_user }}"
    rule:
      conditions: "{{ item.rule.conditions }}"
      properties:
        description: "{{ item.rule.properties.description }}"
        comment: "{{ item.rule.properties.comment | default() }}"
        disabled: "{{ item.rule.properties.disabled | default(False) }}"
        documentation_url: "{{ documentation_url }}"
      value_raw: "{{ item.rule.value_raw|string }}"
      location: "{{ item.rule.location }}"
    ruleset: "{{ item.ruleset }}"
    server_url: "{{ master_site_baseurl }}"
    site: "{{ master_site }}"
  loop: "{{ rulesets | flatten(levels=1) }}"
  loop_control:
    label: "{{ item.ruleset }} [{{ item.rule.properties.description | default() }}]"

reading through all the comments above i see this has been provided as a workaround more often, it just disappeared in the amount of comments in this bug.

muehlings commented 8 months ago

I have given up on this. The API is not consistent and the module logic is not consistent.

3 examples:

I work around this with deleting rules.mk and writing the rulesets with ansible again.

Without a full compare (ansible module task) and a reliable source of the real rule content (API task) there will be no solution to this problem.