shlex.split and spaces in the value of a key=value pair

219 views
Skip to first unread message

Stanley Karunditu

unread,
Jun 10, 2014, 8:07:30 AM6/10/14
to ansibl...@googlegroups.com
Hello,

Building new modules. Having problem when creating a key=value pair where "value" is an array.
I get the following error with the below config..

failed: [sw3] => (item={'value': {'ipv4': ['10.100.1.1/24', '10.200.1.1/24']}, 'key': 'swp2'}) => {"failed": true, "item": {"key": "swp2", "value": {"ipv4": ["10.100.1.1/24", "10.200.1.1/24"]}}}
msg: this module requires key=value arguments (['name=swp2', 'ipv4=[10.100.1.1/24,', '10.200.1.1/24]', 'applyconfig=yes'])


This is my variables file.
======== doesn't work ======
interfaces:
  sw3:
    swp2:
       ipv4:
          - 10.100.1.1/24
          - 10.200.1.1/24

If I change the variables file to say what is below.. it works
===== this works =====
interfaces:
  sw3:
    swp2:
       ipv4: "10.100.1.1/24,10.200.1.1/24"

    
I notice the problem is that the first configuration puts a space between the 2 elements in the array of IPs, and 'shlex.split' splits it at the space between the array elements. Any way around this? I like the first format much better. Plus now have to be super careful of white spaces in values with arrays. Find this kinda brittle.

My AnsibleModule argument call is like so, maybe I'm doing something wrong there?

module = AnsibleModule(
        argument_spec=dict(
            name=dict(required=True, type='str'),
            bridgemems=dict(type='list'),
            bondmems=dict(type='list'),
            ipv4=dict(type='list'),
            ipv6=dict(type='list'),
            applyconfig=dict(required=True, type='str')
        ),
        mutually_exclusive=[
            ['bridgemems', 'bondmems']
        ]
    )

Thanks

James Cammarata

unread,
Jun 10, 2014, 10:30:52 AM6/10/14
to Stanley Karunditu, ansibl...@googlegroups.com
It looks like this is due to the way you're passing the variable into the module. If you want to maintain the datastructure, you need to use "complex args", which means specifying the variables as follows:

- name: do something
  module:
    foo: bar
    var2: "something"
    my_list: "{{var.sub_list}}"

It appears though, that you're trying to call the module with regular args, which means they are passed through shlex.split():

- name: do something
  module: foo=bar var2="something" my_list="{{var.sub_list}}"

As you noted, the solution is to either use the simple variable syntax (specifying lists as comma-separated items) or use the complex variable form for specifying your parameters.




--
You received this message because you are subscribed to the Google Groups "Ansible Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-deve...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Petros Moisiadis

unread,
Jun 10, 2014, 10:58:46 AM6/10/14
to ansibl...@googlegroups.com
On 06/10/14 17:30, James Cammarata wrote:
It looks like this is due to the way you're passing the variable into the module. If you want to maintain the datastructure, you need to use "complex args", which means specifying the variables as follows:

- name: do something
  module:
    foo: bar
    var2: "something"
    my_list: "{{var.sub_list}}"

It appears though, that you're trying to call the module with regular args, which means they are passed through shlex.split():

- name: do something
  module: foo=bar var2="something" my_list="{{var.sub_list}}"

As you noted, the solution is to either use the simple variable syntax (specifying lists as comma-separated items) or use the complex variable form for specifying your parameters.



With little help from jinja one can use simple variable syntax and still keep his variable as a YAML list:

- name: do something
  module: foo=bar var2="something" my_list="{{ var.sub_list|join(',') }}"

Michael DeHaan

unread,
Jun 10, 2014, 12:17:14 PM6/10/14
to Petros Moisiadis, ansibl...@googlegroups.com
For those that don't know you can use complex vars here and not deal with any of the string ops:

- module:
     foo: bar
     var2: baz
     my_list: var.sub_list

etc



Reply all
Reply to author
Forward
0 new messages