Repository: ansible/ansible

Issue:
parse_cli returns wrong results when extracting a single item into a list
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
parse_cli

##### ANSIBLE VERSION
<!--- Paste verbatim output from “ansible --version” between quotes below -->
```
ansible-playbook 2.5.0 (devel 6d27ac60cb) last updated 2017/09/18 08:48:12 (GMT +000)
  config file = None
  configured module search path = [u'/home/vagrant/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /home/vagrant/ansible/lib/ansible
  executable location = /home/vagrant/ansible/bin/ansible-playbook
  python version = 2.7.6 (default, Oct 26 2016, 20:30:19) [GCC 4.8.4]
```

##### OS / ENVIRONMENT
Linux nms 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

##### SUMMARY
parse_cli returns the first character of the matched string instead of the whole string when there's a single match group in the pattern.

##### STEPS TO REPRODUCE
playbook
```---
- hosts: localhost
  gather_facts: false
  vars:
    p: |
      Neighbor ID     Pri   State
      192.168.0.4       0   FULL/
      192.168.0.1       0   FULL/
  tasks:
  - debug: msg={{ p | parse_cli('cf_one.yml') }}
  - debug: msg={{ p | parse_cli('cf_many.yml') }}
```
cf_one.yml
```---
vars:
  neighbor:
    id: "{{ item.id }}"

keys:
  neighbors:
    type: list
    value: "{{ neighbor }}"
    items: "^(?P<id>\\d+\\.\\d+\\.\\d+\\.\\d+)"
```
cf_many.yml
```---
vars:
  neighbor:
    id: "{{ item.id }}"
    state: "{{ item.state }}"
    up: "{{ item.state == 'FULL' }}"

keys:
  neighbors:
    type: list
    value: "{{ neighbor }}"
    items: "^(?P<id>\\d+\\.\\d+\\.\\d+\\.\\d+)[ 0-9]+(?P<state>[A-Z0-9-]+)"
```
##### EXPECTED RESULTS
```
PLAY [localhost] ***********************************************************************************

TASK [debug] ***************************************************************************************
ok: [localhost] => {
    "msg": {
        "neighbors": [
            {
                "id": "192.168.0.4"
            },
            {
                "id": "192.168.0.1"
            }
        ]
    }
}

TASK [debug] ***************************************************************************************
ok: [localhost] => {
    "msg": {
        "neighbors": [
            {
                "id": "192.168.0.4",
                "state": "FULL",
                "up": true
            },
            {
                "id": "192.168.0.1",
                "state": "FULL",
                "up": true
            }
        ]
    }
}
```

##### ACTUAL RESULTS
```
PLAY [localhost] ***********************************************************************************

TASK [debug] ***************************************************************************************
ok: [localhost] => {
    "msg": {
        "neighbors": [
            {
                "id": 1
            },
            {
                "id": 1
            }
        ]
    }
}

TASK [debug] ***************************************************************************************
ok: [localhost] => {
    "msg": {
        "neighbors": [
            {
                "id": "192.168.0.4",
                "state": "FULL",
                "up": true
            },
            {
                "id": "192.168.0.1",
                "state": "FULL",
                "up": true
            }
        ]
    }
}
```



Discussion:

Resolving patch:
diff --git a/lib/ansible/plugins/filter/network.py b/lib/ansible/plugins/filter/network.py
--- a/lib/ansible/plugins/filter/network.py
+++ b/lib/ansible/plugins/filter/network.py
@@ -56,7 +56,10 @@ def re_matchall(regex, value):
         obj = {}
         if regex.groupindex:
             for name, index in iteritems(regex.groupindex):
-                obj[name] = match[index - 1]
+                if len(regex.groupindex) == 1:
+                    obj[name] = match
+                else:
+                    obj[name] = match[index - 1]
             objects.append(obj)
     return objects
 


Test patch: