如何将var类型更改为整数?

How to change var type to integer?

我正在读取 CSV 文件,注册一个变量并循环遍历变量列表。就像下面的例子一样简单:

---
- hosts: localhost
  vars:
    csv: |
      some;val;ues
      string;1;2
  tasks:
        
    - name: copy
      copy:
        content: "{{csv}}"
        dest: "vm.csv"
        
    - name: read csv
      community.general.read_csv:
        path: "vm.csv"
        delimiter: ";"
      register: vms
        
    - name: debug
      debug:
        var: vms

    - name: Trigger AWX
      awx.awx.workflow_launch:
        name: "Do the job!"
        extra_vars:
          some_string: "{{ item.some }}"
          an_integer: "{{ item.val }}"
          another_integer: "{{ item.ues }}"
      with_items: "{{ vms.list }}"

现在让我们进入正题。触发最后一个任务时,需要 an_integeranother_integer 整数。否则下面的API会失败。

问题:Jinja2 模板引擎总是 return 一个字符串。 an_integer: "{{ item.val | int }}",例如,不会改变该行为。

正如您从任务 3(调试)的输出中看到的那样,从 csv/registered 读取时,值已经是字符串。

ok: [localhost] => {
    "vms": {
        "changed": false,
        "dict": {},
        "failed": false,
        "list": [
            {
                "some": "string",
                "ues": "2",
                "val": "1"
            }
        ]
    }
}

如何强制将模块参数设置为整​​数?

列表中的项目是字符串。例如

    - debug:
        msg: |
          vms.list.0.val: {{ vms.list.0.val }} {{ vms.list.0.val|type_debug }}

给出(使用 yaml 回调插件。参见 shell> ansible-doc -t callback yaml

  msg: |-
    vms.list.0.val: 1 AnsibleUnicode

将列表项转换为整数。首先创建列表,例如

    - set_fact:
        _list: "{{ _list|d([]) + [item|combine(_item)] }}"
      loop: "{{ vms.list }}"
      vars:
        _item: "{{ {'ues': item.ues|int, 'val': item.val|int} }}"

给予

  _list:
  - some: string
    ues: 2
    val: 1

然后更新字典中的列表

    - set_fact:
        vms: "{{ vms|combine({'list': _list}) }}"

给予

  vms:
    changed: false
    dict: {}
    failed: false
    list:
    - some: string
      ues: 2
      val: 1

调试任务现在将显示类型为整数

  msg: |-
    vms.list.0.val: 1 int

感谢 Vladimir 的回答,此解决方案基于此。

工作示例

与其单独传递每个参数,不如构建一个字典并将其直接传递给 extra_vars,如下所示。

    - set_fact:
        vm_list: "{{ vm_list|d([]) + [vm] }}"
      loop: "{{ vms.list }}"
      vars:
        vm: "{{ {
          'some_string': item.some,
          'val': item.val|int,
          'ues': item.ues|int
          } }}"

    - name: Trigger AWX
      awx.awx.workflow_launch:
        name: "Do the job!"
        extra_vars: "{{ item }}"
      with_items: "{{ vm_list }}"

这保留了字典的值类型并且 API 很高兴。


示例无效

下面的例子将不起作用

    - set_fact:
        vm_list: "{{ vm_list|d([]) + [vm] }}"
      loop: "{{ vms.list }}"
      vars:
        vm: "{{ {
          'some': item.some,
          'val': item.val|int,
          'ues': item.ues|int
          } }}"

    - name: Trigger AWX
      awx.awx.workflow_launch:
        name: "Do the job!"
        extra_vars:
          some_string: "{{ item.some }}"
          val: "{{ item.val|int }}"
          ues: "{{ item.ues|int }}"
      with_items: "{{ vm_list }}"

如调试输出所示,它会将值转换为字符串,即使您添加了 int 过滤器。

[...]
            "extra_vars": {
                "some_string": "string",
                "ues": "2",
                "val": "1"
[...]
    },
    "item": {
        "some": "string",
        "ues": 2,
        "val": 1
    },
[...]