PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, July 20, 2022

[FIXED] How to change var type to integer?

 July 20, 2022     ansible, casting, integer     No comments   

Issue

I am reading from a CSV file, register a variable and loop through the variable's list. It's as easy as below example:

---
- 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 }}"

Now let's get into the issue. When triggering the last task, integers are required for an_integer and another_integer. Otherwise the API below will fail.

The problem: the Jinja2 template engine will ALWAYS return a string. an_integer: "{{ item.val | int }}", for example, won't change that behavior.

As you can see from the output of task 3 (debug), the values are already string when read from csv / registered.

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

How can I force a module parameter to be set as integer?


Solution

Thanks to Vladimir for his answer, on which this solution is based on.

Working example

Instead of passing each parameter on its own, the solution is to build a dictionary and pass it directly to extra_vars like below.

    - 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 }}"

This keeps the dictionaries' value types and the API is happy.


Not working example

The below example will not work!

    - 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 }}"

As the debug output shows it converts the values into strings, even if you add the int filter.

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


Answered By - jay
Answer Checked By - Cary Denson (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing