Repository: ansible/ansible

Issue:
docker_container not applying a list of links
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
docker_container

##### ANSIBLE VERSION
```
ansible 2.2.1.0
  config file = /Users/alebedev/projects/ansible/ansible.cfg
  configured module search path = Default w/o overrides
```

##### CONFIGURATION
<!---
Mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->

##### OS / ENVIRONMENT
N/A

##### SUMMARY
docker_container module is not accepting a list of the links

##### STEPS TO REPRODUCE
run a docker_container module with a list of the links and the only the last one will be in the list

```yaml
- name: Starting nginx container
  docker_container:
    name: nginx
    image: nginx
    links:
     - app:app
     - app:app1
     - app:app2
     - app:app3
    detach: true
    privileged: true
    restart_policy: on-failure
    interactive: true
    state: started
```
```
docker inspect -f "{{ .HostConfig.Links }}" nginx
[/app:/nginx/app3]
```

##### EXPECTED RESULTS
```
docker inspect -f "{{ .HostConfig.Links }}" nginx
[/app:/nginx/app /app:/nginx/app1 /app:/nginx/app2 /app:/nginx/app3]
```
##### ACTUAL RESULTS
```
TASK [nginx : Starting nginx container] ****************************************
changed: [app] => {
    "ansible_facts": {},
    "changed": true,
    "invocation": {
        "module_args": {
            "api_version": null,
            "blkio_weight": null,
            "cacert_path": null,
            "capabilities": null,
            "cert_path": null,
            "cleanup": false,
            "command": null,
            "cpu_period": null,
            "cpu_quota": null,
            "cpu_shares": null,
            "cpuset_cpus": null,
            "cpuset_mems": null,
            "debug": false,
            "detach": true,
            "devices": null,
            "dns_opts": null,
            "dns_search_domains": null,
            "dns_servers": null,
            "docker_host": null,
            "entrypoint": null,
            "env": null,
            "env_file": null,
            "etc_hosts": null,
            "exposed_ports": [
                "80:80",
                "443:443"
            ],
            "filter_logger": false,
            "force_kill": false,
            "groups": null,
            "hostname": null,
            "ignore_image": false,
            "image": "nginx",
            "interactive": true,
            "ipc_mode": null,
            "keep_volumes": true,
            "kernel_memory": null,
            "key_path": null,
            "kill_signal": null,
            "labels": null,
            "links": [
                "app:app",
                "app:app1",
                "app:app2",
                "app:app3"
            ],
            "log_driver": null,
            "log_options": null,
            "mac_address": null,
            "memory": "0",
            "memory_reservation": null,
            "memory_swap": null,
            "memory_swappiness": null,
            "name": "nginx",
            "network_mode": null,
            "networks": null,
            "oom_killer": null,
            "oom_score_adj": null,
            "paused": false,
            "pid_mode": null,
            "privileged": true,
            "published_ports": [
                "80:80",
                "443:443"
            ],
            "pull": false,
            "purge_networks": false,
            "read_only": false,
            "recreate": false,
            "restart": false,
            "restart_policy": "on-failure",
            "restart_retries": null,
            "security_opts": null,
            "shm_size": null,
            "ssl_version": null,
            "state": "started",
            "stop_signal": null,
            "stop_timeout": null,
            "timeout": null,
            "tls": null,
            "tls_hostname": null,
            "tls_verify": null,
            "trust_image_content": false,
            "tty": false,
            "ulimits": null,
            "user": null,
            "uts": null,
            "volume_driver": null,
            "volumes": null,
            "volumes_from": null
        },
        "module_name": "docker_container"
    }
}
```



Discussion:

Resolving patch:
diff --git a/lib/ansible/modules/cloud/docker/docker_container.py b/lib/ansible/modules/cloud/docker/docker_container.py
--- a/lib/ansible/modules/cloud/docker/docker_container.py
+++ b/lib/ansible/modules/cloud/docker/docker_container.py
@@ -1094,13 +1094,13 @@ def _parse_links(links):
         if links is None:
             return None
 
-        result = {}
+        result = []
         for link in links:
             parsed_link = link.split(':', 1)
             if len(parsed_link) == 2:
-                result[parsed_link[0]] = parsed_link[1]
+                result.append((parsed_link[0], parsed_link[1]))
             else:
-                result[parsed_link[0]] = parsed_link[0]
+                result.append((parsed_link[0], parsed_link[0]))
         return result
 
     def _parse_ulimits(self):
@@ -1451,7 +1451,7 @@ def has_network_differences(self):
                     diff = True
                 if network.get('links') and connected_networks[network['name']].get('Links'):
                     expected_links = []
-                    for link, alias in network['links'].items():
+                    for link, alias in network['links']:
                         expected_links.append("%s:%s" % (link, alias))
                     for link in expected_links:
                         if link not in connected_networks[network['name']].get('Links', []):
@@ -1552,7 +1552,7 @@ def _get_expected_links(self):
         self.log('parameter links:')
         self.log(self.parameters.links, pretty_print=True)
         exp_links = []
-        for link, alias in self.parameters.links.items():
+        for link, alias in self.parameters.links:
             exp_links.append("/%s:%s/%s" % (link, ('/' + self.parameters.name), alias))
         return exp_links
 


Test patch: