字典键中的 Ansible 变量

aka*_*kin 11 ansible

我正在尝试执行用于设置戴尔服务器的剧本,但 module 中的字典存在一些问题idrac_redfish_config。我需要为特定用户启用 SOL,但为此我想使用字典中带有变量的键,因为用户 ID 可能因服务器而异。

我如何尝试将变量添加到字典键中,如下所示:

    - name: Store id test-user
      set_fact:
        ID: "{{ result.redfish_facts.user.entries | json_query(\"[?UserName=='test-user'].Id\") }}"
    - name: Enable SOL for test-user
      community.general.idrac_redfish_config:
        category: Manager
        command: SetManagerAttributes
        resource_id: iDRAC.Embedded.1
        manager_attributes:
          Users.{{ ID[0] }}.SolEnable: "Enabled" <---
          Users.{{ ID[0] }}.IpmiLanPrivilege: "Administrator" <---
        baseuri: "testhost"
        username: "admin"
        password: "admin"
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

TASK [Store id test-user] **************************************************************************************************************************************************************************************
ok: [localhost] => {
    "ansible_facts": {
        "ID": [
            "8"
        ]
    },
    "changed": false
}

TASK [Enable SOL for test-user] ********************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {
    "changed": false,
    "invocation": {
        "module_args": {
            "baseuri": "testhost",
            "category": "Manager",
            "command": [
                "SetManagerAttributes"
            ],
            "manager_attribute_name": null,
            "manager_attribute_value": null,
            "manager_attributes": {
                "Users.{{ ID[0] }}.IpmiLanPrivilege": "Administrator",
                "Users.{{ ID[0] }}.SolEnable": "Enabled"
            },
            "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "resource_id": "iDRAC.Embedded.1",
            "timeout": 10,
            "username": "admin"
        }
    },
    "msg": "SetManagerAttributes: Manager attribute Users.{{ ID[0] }}.SolEnable not found"
}
Run Code Online (Sandbox Code Playgroud)

如果我这样做:

        manager_attributes: "{
          'Users.{{ ID[0] }}.SolEnable': Enabled
          'Users.{{ ID[0] }}.IpmiLanPrivilege': Administrator
        }"
Run Code Online (Sandbox Code Playgroud)

我得到:

fatal: [localhost]: FAILED! => {
    "changed": false,
    "invocation": {
        "module_args": {
            "baseuri": "testhost",
            "category": "Manager",
            "command": [
                "SetManagerAttributes"
            ],
            "manager_attributes": "{ 'Users.8.SolEnable': Enabled 'Users.8.IpmiLanPrivilege': Administrator }",
            "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "resource_id": "iDRAC.Embedded.1",
            "timeout": 10,
            "username": "admin"
        }
    },
    "msg": "argument manager_attributes is of type <class 'str'> and we were unable to convert to dict: unable to evaluate string as dictionary"
}
Run Code Online (Sandbox Code Playgroud)

我在 Ansible文档中没有找到如何正确执行此操作。

Zei*_*tor 15

根据文档,manager_attributes应该是要在设备上设置的键/值对的字典。这些键的名称中带有点,您无法像上面尝试的那样“静态”创建动态键名称(即,"prefix{{ dynamic_value }}suffix": "some content"由于键名称不经过 jinja2 模板,因此无法像您自己体验的那样工作)。

下面是一个解决方案。它远不是唯一的,但这是我想到的第一个,我可以很快为您设置一个例子。在本例中,我创建一个{key: X, value: Y}以动态名称作为键的字典列表,并使用items2dict过滤器将其转换回字典本身。

我没有网络设备来玩这个游戏,所以我无法验证最终结果是否确实被模块接受。我的示例只是使用输入数据进行调试来说明并输出模块期望的字典。如果它们是错误的,您将必须调整确切的键名称,但至少您应该能够继续前进。

- name: Dynamic dict
  hosts: localhost
  gather_facts: false

  vars:
    ID:
      - "8"

    my_attributes:
      - key: "Users.{{ ID[0] }}.IpmiLandPrivilege"
        value: Administrator
      - key: "Users.{{ ID[0] }}.SolEnable"
        value: Enabled

  tasks:
    - name: construct a dynamic dict and debug
      vars:
        manager_attributes: "{{ my_attributes | items2dict }}"
      debug:
        var: manager_attributes
Run Code Online (Sandbox Code Playgroud)

这使:

PLAY [Dynamic dict demo] ***************************************************************************************************************************************************************************************************************

TASK [construct a dynamic dict and debug] **********************************************************************************************************************************************************************************************
ok: [localhost] => {
    "manager_attributes": {
        "Users.8.IpmiLandPrivilege": "Administrator",
        "Users.8.SolEnable": "Enabled"
    }
}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
Run Code Online (Sandbox Code Playgroud)

编辑:另一个(在许多其他示例中)实现相同目标的示例。输出与上面完全相同:

PLAY [Dynamic dict demo] ***************************************************************************************************************************************************************************************************************

TASK [construct a dynamic dict and debug] **********************************************************************************************************************************************************************************************
ok: [localhost] => {
    "manager_attributes": {
        "Users.8.IpmiLandPrivilege": "Administrator",
        "Users.8.SolEnable": "Enabled"
    }
}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 
Run Code Online (Sandbox Code Playgroud)