Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

with_sequence should provide int (not unicode) values #17852

Closed
candlerb opened this issue Oct 1, 2016 · 8 comments · Fixed by #53275
Closed

with_sequence should provide int (not unicode) values #17852

candlerb opened this issue Oct 1, 2016 · 8 comments · Fixed by #53275
Assignees
Labels
affects_2.1 This issue/PR affects Ansible v2.1 bug This issue/PR relates to a bug. docs This issue/PR relates to or includes documentation. support:core This issue/PR relates to code supported by the Ansible Engineering Team.

Comments

@candlerb
Copy link
Contributor

candlerb commented Oct 1, 2016

ISSUE TYPE
  • Bug Report
COMPONENT NAME

with_sequence

ANSIBLE VERSION
ansible 2.1.0.0
  config file =
  configured module search path = Default w/o overrides
CONFIGURATION

No changes

OS / ENVIRONMENT

N/A

SUMMARY

with_sequence sets item to a series of unicode values instead of integer values. This makes it impossible to do arithmetic with them.

STEPS TO REPRODUCE

This fails:

- hosts: localhost
  tasks:
    - debug: msg="hello {{10+item}}"
      with_sequence: start=1 end=9

This works:

- hosts: localhost
  tasks:
    - debug: msg="hello {{10+item}}"
      with_items: [1, 2, 3, 4, 5, 6, 7, 8, 9]
EXPECTED RESULTS

"hello 11" to "hello 19"

ACTUAL RESULTS
TASK [debug] *******************************************************************
fatal: [localhost]: FAILED! => {"failed": true, "msg": "Unexpected templating type error occurred on (hello {{10+item}}): unsupported operand type(s) for +: 'int' and 'unicode'"}

But using with_items instead of with_sequence it's fine:

ok: [localhost] => (item=1) => {
    "item": 1,
    "msg": "hello 11"
}
ok: [localhost] => (item=2) => {
    "item": 2,
    "msg": "hello 12"
}
... etc
@ansibot ansibot added bug_report affects_2.1 This issue/PR affects Ansible v2.1 labels Oct 1, 2016
@bcoca
Copy link
Member

bcoca commented Oct 3, 2016

This should do what you want:

- debug: msg="hello {{10+item|int}}"

Im not sure sequence should return an int as the most common use case is to create cloud servers and append the sequence to the name:

cloud: name="{{ 'stuff_' + item}}"

@candlerb
Copy link
Contributor Author

candlerb commented Oct 3, 2016

Yes, that works, thank you.

Since the documentation section is headed "Looping over Integer Sequences" I was surprised to get strings rather than integers.

You provide this use case:

cloud: name="{{ 'stuff_' + item}}"

This could alternatively be done as:

cloud: name="stuff_{{item}}"

which actually is the approach used in the documentation example:

- group: name=group{{ item }} state=present
      with_sequence: count=4

...rather than name={{"group" + item}}.

However: you probably don't want to break users of the first case. Also I notice the format parameter, which when used would force a string anyway.

Maybe just clarify in the documentation that the item values are always provided as strings, and you can use the |int filter if you want them turned back into integers?

(P.S. For count=4 it would be good to document whether the starting value is 0 or 1 )

@jhawkesworth
Copy link
Contributor

Interesting discussion. Its tricky to know where to document this exactly. I believe its really jinja2 that 'wants' to output strings by default, so this is going to be true throught playbooks and templates. I guess in the context of jinja2's origins (as a templating engine for generating html) it makes sense to output strings by default.

I hit something like your issue a little while back and in the end settled on using
with_indexed_items on a an inventory group.

@candlerb
Copy link
Contributor Author

candlerb commented Oct 3, 2016

I believe its really jinja2 that 'wants' to output strings by default

Only in the sense that {{ item }} is a string. This expansion works if item is either an integer or a string. There is no requirement for item itself to be a string.

What I'm actually doing is building IP addresses: e.g. 10.10.0.{{220 + item}}; I don't want 10.10.0.22{{item}} because that only works up to 9.

I use arithmetic inside a jinja2 expansion quite a lot.

Its tricky to know where to document this exactly

I think this behaviour is specific to with_sequence, and the only documentation I have found for that construct is here

@bcoca
Copy link
Member

bcoca commented Oct 3, 2016

If you want to submit a pull request we'll be happy to review it

@jamesjuran2
Copy link

This may not be specific to with_sequence. I'm doing an assignment out of another variable (and thus invoking jinja2), and it is similarly giving me a string when I am expecting an integer. The workaround of using |int on the arithmetic also works here.

Here's my test playbook, showing that the arithmetic works on a simple direct-assigned variable, but fails when the variable is assigned via jinja2:

[james.juran@localhost ansible-tests]$ cat datacenter.yml

  • name: Datacenter Variable Test
    any_errors_fatal: yes
    gather_facts: no
    hosts: localhost
    vars:
    • datacenter: sfo2
    • datacenter_ids:
      nyc1: 0
      sfo2: 1
    • datacenter_id: "{{datacenter_ids[datacenter]}}"
    • direct_assigned: 1
    • new_id: "{{100+datacenter_id}}"
    • new_id_direct: "{{100+direct_assigned}}"
      tasks:
    • debug: var=datacenter
    • debug: var=datacenter_ids
    • debug: var=datacenter_id
    • debug: var=new_id_direct
    • debug: var=new_id

[james.juran@localhost ansible-tests]$ ansible-playbook --version
ansible-playbook 2.3.0 (devel b339d4c) last updated 2016/11/16 14:50:18 (GMT -400)
lib/ansible/modules/core: (detached HEAD a4cddac) last updated 2016/11/16 14:50:24 (GMT -400)
lib/ansible/modules/extras: (detached HEAD 19c7d5b) last updated 2016/11/16 14:50:29 (GMT -400)
config file = /etc/ansible/ansible.cfg
configured module search path = Default w/o overrides
[james.juran@localhost ansible-tests]$ ansible-playbook -v -c local datacenter.yml
Using /etc/ansible/ansible.cfg as config file
[WARNING]: provided hosts list is empty, only localhost is available

PLAY [Datacenter Variable Test] **************************************************************************************************************************************************

TASK [debug] *********************************************************************************************************************************************************************
ok: [localhost] => {
"datacenter": "sfo2"
}

TASK [debug] *********************************************************************************************************************************************************************
ok: [localhost] => {
"datacenter_ids": {
"nyc1": 0,
"sfo2": 1
}
}

TASK [debug] *********************************************************************************************************************************************************************
ok: [localhost] => {
"datacenter_id": "1"
}

TASK [debug] *********************************************************************************************************************************************************************
ok: [localhost] => {
"new_id_direct": "101"
}

TASK [debug] *********************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"failed": true, "msg": "{{100+datacenter_id}}: Unexpected templating type error occurred on ({{100+datacenter_id}}): unsupported operand type(s) for +: 'int' and 'unicode'"}

I expected the last statement to also produce "101".

@alikins
Copy link
Contributor

alikins commented Jan 5, 2017

(Mentioning #17992 here to keep track of related issues)

@ansibot ansibot added the support:core This issue/PR relates to code supported by the Ansible Engineering Team. label Jun 29, 2017
@dagwieers
Copy link
Member

There is a light at the end of the tunnel. We made a change to Jinja2 so we don't see all variable types changed into strings. See: pallets/jinja#708

@ansibot ansibot added docs This issue/PR relates to or includes documentation. bug This issue/PR relates to a bug. and removed docs_report labels Mar 1, 2018
@mkrizek mkrizek self-assigned this Mar 1, 2019
mkrizek added a commit to mkrizek/ansible that referenced this issue Mar 4, 2019
bcoca pushed a commit that referenced this issue Mar 4, 2019
* Clarify return value of the sequence lookup

Fixes #17852

* Mention range filter
@ansible ansible locked and limited conversation to collaborators Jul 25, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.1 This issue/PR affects Ansible v2.1 bug This issue/PR relates to a bug. docs This issue/PR relates to or includes documentation. support:core This issue/PR relates to code supported by the Ansible Engineering Team.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants