简体   繁体   中英

Passing a Dictionary Variable to a Custom Module

I have a custom module for Ansible written in Python that I maintain, and I need to be able to pass in all detected Ansible facts as a dictionary into this module.

Currently, I'm attempting to do this like so:

- name: run tests
  degoss:
    # ...
    facts: "{{ ansible_facts }}"

My module's argument spec looks like this:

AnsibleModule(argument_spec=dict(
  # ...
  facts=dict(required=False, default={}),
), ...)

My module documentation also specifies this:

DOCUMENTATION="""
# ...
options:
  facts:
    required: false
    default: empty dictionary
    description: A dictionary of Ansible facts.
"""

However, as I do input sanitization and validation, I receive a str instead of a dictionary:

if not isinstance(self.facts, dict):
    self.fail("The 'facts' parameter to this module must be a dictionary, not a {}".format(type(self.facts)))

This is thrown at runtime:

The 'facts' parameter to this module must be a dictionary, not a <type 'str'>

Is there a specific syntax I need to use to pass a value as a dictionary, or do I need to treat dictionary variables as JSON and attempt to deserialize them?

As described here , you can specify what type ansible can expect.

AnsibleModule(argument_spec=dict(
  # ...
  facts=dict(required=False, default={}, type=dict),
), ...)

Then 'facts' will be a dictionary

This works:

  1. Pass ansible_facts piping it to to_json filter in your play.

     - name: run tests degoss: #... facts: "{{ ansible_facts | to_json }}"
  2. In your python module decode the json using either json.loads or ast.literal_eval

     import json import ast... facts = json.loads(module.params.get('facts')) facts = ast.literal_eval(module.params.get('facts'))...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM