Skip to content

Commit

Permalink
docker_host_info - Allow filters which are passed as lists (#160)
Browse files Browse the repository at this point in the history
* Initial Commit

* Adding integration tests

* Adding example in docs

* Adding changelog fragment

* Applying initial review suggestions
  • Loading branch information
Ajpantuso authored Jun 22, 2021
1 parent af2b3b0 commit 49c8fd0
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
minor_changes:
- docker_host_info - allow values for keys in ``containers_filters``, ``images_filters``, ``networks_filters``, and
``volumes_filters`` to be passed as YAML lists (https://github.com/ansible-collections/community.docker/pull/160).
23 changes: 14 additions & 9 deletions plugins/module_utils/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@


from ansible.module_utils.basic import AnsibleModule, env_fallback, missing_required_lib
from ansible.module_utils.common.collections import is_sequence
from ansible.module_utils.common._collections_compat import Mapping, Sequence
from ansible.module_utils.six import string_types
from ansible.module_utils.six.moves.urllib.parse import urlparse
Expand Down Expand Up @@ -927,23 +928,27 @@ def get_legacy_docker_diffs(self):
return result


def clean_dict_booleans_for_docker_api(data):
def clean_dict_booleans_for_docker_api(data, allow_sequences=False):
'''
Go doesn't like Python booleans 'True' or 'False', while Ansible is just
fine with them in YAML. As such, they need to be converted in cases where
we pass dictionaries to the Docker API (e.g. docker_network's
driver_options and docker_prune's filters).
driver_options and docker_prune's filters). When `allow_sequences=True`
YAML sequences (lists, tuples) are converted to [str] instead of str([...])
which is the expected format of filters which accept lists such as labels.
'''
def sanitize(value):
if value is True:
return 'true'
elif value is False:
return 'false'
else:
return str(value)

result = dict()
if data is not None:
for k, v in data.items():
if v is True:
v = 'true'
elif v is False:
v = 'false'
else:
v = str(v)
result[str(k)] = v
result[str(k)] = [sanitize(e) for e in v] if allow_sequences and is_sequence(v) else sanitize(v)
return result


Expand Down
19 changes: 18 additions & 1 deletion plugins/modules/docker_host_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
description:
- A dictionary of filter values used for selecting containers to list.
- "For example, C(until: 24h)."
- C(label) is a special case of filter which can be a string C(<key>) matching when a label is present, a string
C(<key>=<value>) matching when a label has a particular value, or a list of strings C(<key>)/C(<key>=<value).
- See L(the docker documentation,https://docs.docker.com/engine/reference/commandline/container_prune/#filtering)
for more information on possible filters.
type: dict
Expand All @@ -45,6 +47,8 @@
description:
- A dictionary of filter values used for selecting images to list.
- "For example, C(dangling: true)."
- C(label) is a special case of filter which can be a string C(<key>) matching when a label is present, a string
C(<key>=<value>) matching when a label has a particular value, or a list of strings C(<key>)/C(<key>=<value).
- See L(the docker documentation,https://docs.docker.com/engine/reference/commandline/image_prune/#filtering)
for more information on possible filters.
type: dict
Expand All @@ -56,6 +60,8 @@
networks_filters:
description:
- A dictionary of filter values used for selecting networks to list.
- C(label) is a special case of filter which can be a string C(<key>) matching when a label is present, a string
C(<key>=<value>) matching when a label has a particular value, or a list of strings C(<key>)/C(<key>=<value).
- See L(the docker documentation,https://docs.docker.com/engine/reference/commandline/network_prune/#filtering)
for more information on possible filters.
type: dict
Expand All @@ -67,6 +73,8 @@
volumes_filters:
description:
- A dictionary of filter values used for selecting volumes to list.
- C(label) is a special case of filter which can be a string C(<key>) matching when a label is present, a string
C(<key>=<value>) matching when a label has a particular value, or a list of strings C(<key>)/C(<key>=<value).
- See L(the docker documentation,https://docs.docker.com/engine/reference/commandline/volume_prune/#filtering)
for more information on possible filters.
type: dict
Expand Down Expand Up @@ -126,6 +134,15 @@
disk_usage: yes
register: result
- name: Get info on docker host and list containers matching the filter
community.docker.docker_host_info:
containers: yes
containers_filters:
label:
- key1=value1
- key2=value2
register: result
- ansible.builtin.debug:
var: result.host_info
Expand Down Expand Up @@ -223,7 +240,7 @@ def __init__(self, client, results):
if self.client.module.params[docker_object]:
returned_name = docker_object
filter_name = docker_object + "_filters"
filters = clean_dict_booleans_for_docker_api(client.module.params.get(filter_name))
filters = clean_dict_booleans_for_docker_api(client.module.params.get(filter_name), True)
self.results[returned_name] = self.get_docker_items_list(docker_object, filters)

def get_docker_host_info(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
image: "{{ docker_test_image_alpine }}"
command: '/bin/sh -c "sleep 10m"'
name: "{{ cname }}"
labels:
key1: value1
key2: value2
state: started
register: container_output

Expand Down Expand Up @@ -63,6 +66,44 @@
- 'output.containers[0].Image is string'
- 'output.containers[0].ImageID is not defined'

- name: Get info on Docker host and list containers matching filters (single label)
docker_host_info:
containers: yes
containers_filters:
label: key1=value1
register: output

- name: assert container is returned when filters are matched (single label)
assert:
that: "{{ output.containers | length }} == 1"

- name: Get info on Docker host and list containers matching filters (multiple labels)
docker_host_info:
containers: yes
containers_filters:
label:
- key1=value1
- key2=value2
register: output

- name: assert container is returned when filters are matched (multiple labels)
assert:
that: "{{ output.containers | length }} == 1"

- name: Get info on Docker host and do not list containers which do not match filters
docker_host_info:
containers: yes
containers_filters:
label:
- key1=value1
- key2=value2
- key3=value3
register: output

- name: assert no container is returned when filters are not matched
assert:
that: "{{ output.containers | length }} == 0"

- name: Get info on Docker host and list containers with verbose output
docker_host_info:
containers: yes
Expand Down

0 comments on commit 49c8fd0

Please sign in to comment.