Comparing part of a string as an integer

31 views
Skip to first unread message

Jameson

unread,
Aug 23, 2018, 11:11:07 AM8/23/18
to ansible...@googlegroups.com
I'm trying to write a conditional to only act on members of a list of strings when two characters in the string are less than a given number. Does anyone know if this is possible? What I'm trying now looks like:
set_fact:
  interfaces:
    - TenGigabitEthernet 0/32
    - TenGigabitEthernet 0/33

debug: var={{ interfaces }}
  loop: "{{ facts }}"
  when: item[21:22]|int <= 32

When I attempt this, I get, "template error while templating string: expected token 'end of print statement', got 'integer'. String: {{TenGigabitEthernet 0/32}}"

Any thoughts how how to achieve this are appreciated.

Thanks,
Jameson

Jean-Yves LENHOF

unread,
Aug 23, 2018, 11:41:12 AM8/23/18
to ansible...@googlegroups.com, Jameson
Le 2018-08-23 17:10, Jameson a écrit :
> I'm trying to write a conditional to only act on members of a list of
> strings when two characters in the string are less than a given
> number. Does anyone know if this is possible? What I'm trying now
> looks like:
> set_fact:
> interfaces:
> - TenGigabitEthernet 0/32
> - TenGigabitEthernet 0/33
>
> debug: var={{ interfaces }}
> loop: "{{ facts }}"
> when: item[21:22]|int <= 32

Hi,

Does'nt sound good... Explain a little bit what you want if you want
some good help.

To be able to test item against an integer, use something like this (not
tested, but you should have the idea)
item|regex_replace('^.* 0/','')|int

Regards,

JYL

Kai Stian Olstad

unread,
Aug 23, 2018, 12:02:11 PM8/23/18
to ansible...@googlegroups.com
On Thursday, 23 August 2018 17.10.45 CEST Jameson wrote:
> I'm trying to write a conditional to only act on members of a list of
> strings when two characters in the string are less than a given number.
> Does anyone know if this is possible? What I'm trying now looks like:
> set_fact:
> interfaces:
> - TenGigabitEthernet 0/32
> - TenGigabitEthernet 0/33

Your set_fact is missing a dash in front


> debug: var={{ interfaces }}
> loop: "{{ facts }}"
> when: item[21:22]|int <= 32

The same does this debug.
And loop and when is indented to far in.

var= takes a variable name and not the content of one, a valid expression would be var=interfaces

Why are you using {{ facts }} it doesn't exist anywhere else in your code.

Slicing in Python is [from and including:up to but not including] so your [21:22] need to be [21:23] or just [21:] which is to the end of the line.


> When I attempt this, I get, "template error while templating string:
> expected token 'end of print statement', got 'integer'. String:
> {{TenGigabitEthernet 0/32}}"

Because of all errors you get this message.
So this should work

- set_fact:
interfaces:
- TenGigabitEthernet 0/32
- TenGigabitEthernet 0/33

- debug: var=item
loop: "{{ interfaces }}"
when: item[21:23]|int <= 32


--
Kai Stian Olstad


Jameson

unread,
Aug 23, 2018, 1:23:23 PM8/23/18
to ansible...@googlegroups.com
I apologize, guys. There were some typeos in my example. This isn't the actual code I'm using because I tried to simplify the example to only include the problem I'm having. This is a copy of the playbook that includes on this scenario. Obviously, production playbook I'm putting this in will have the variable for the interfaces pulled from the device:

---
- hosts: "{{ target }}"
  connection: network_cli
  gather_facts: no
  tasks:


  - set_fact:
      interfaces:
        - TenGigabitEthernet 0/32
        - TenGigabitEthernet 0/33

  - debug: var={{ item }}
    loop: "{{ interfaces }}"
    when: item[21:]|int <= 32

My goal is to have this only output the first string in the list of interfaces as it is equal to or less than 32. In production, this will be a much larger list, and I will have other filters, so that it only includes my 10 gig interfaces, but the rest of it is already working for me. Thanks.

Jameson

unread,
Aug 23, 2018, 1:27:18 PM8/23/18
to ansible...@googlegroups.com
On Thu, Aug 23, 2018 at 1:22 PM Jameson <imnt...@gmail.com> wrote:

My goal is to have this only output the first string in the list of interfaces as it is equal to or less than 32. In production, this will be a much larger list, and I will have other filters, so that it only includes my 10 gig interfaces, but the rest of it is already working for me. Thanks.

Also, I should mention, that I am trying to specifically test the last two characters in the string, so there is no need for filtering the /.

flowerysong

unread,
Aug 23, 2018, 2:26:16 PM8/23/18
to Ansible Project
There's nothing wrong with your condition, you're just using debug incorrectly. 'var' expects a var name, so you're double-interpolating and telling it to look up the value of the variable named 'TenGigabitEthernet 0/32', which fails.

Jameson

unread,
Aug 23, 2018, 3:14:27 PM8/23/18
to ansible...@googlegroups.com
Gotcha, so debug can't be used to debug the output of a loop. Thanks.

Jameson

unread,
Aug 23, 2018, 3:22:46 PM8/23/18
to ansible...@googlegroups.com
Thanks for helping me sort my debug procedure. It turns out, this is actually what I was going for in the end:

---
- name: "Get facts"
  dellos9_facts:
  register: facts

- name: "Configure all internal interfaces with VLANs"
  dellos9_config:
    parents: "{{ item }}"
    lines:
      - vlan tagged 2,25,100,104,108,160,202,204,210,212,214,238,600-604,2001-2008,2111,2121-2122,2211,2500-2515,3011-3012,3111-3112,3121-3122,3211-3212,3311-3312,3711
      - vlan untagged 1
  loop: "{{ facts.ansible_facts.ansible_net_interfaces | flatten }}"
  when:
    - item[21:23]|int <= 32
    - item is search("TenGig")

flowerysong

unread,
Aug 23, 2018, 4:08:36 PM8/23/18
to Ansible Project
Yes, it can. You can do "msg={{ item }}" or "var=item". You just can't do what you did. Because it's wrong.
Reply all
Reply to author
Forward
0 new messages