Sanitize labels. (#985) (#986)

(cherry picked from commit 1e10834905)

Co-authored-by: Felix Fontein <felix@fontein.de>
This commit is contained in:
patchback[bot] 2024-11-10 00:30:40 +01:00 committed by GitHub
parent c0dbbe102f
commit cc80ff227e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 68 additions and 6 deletions

View File

@ -0,0 +1,9 @@
bugfixes:
- "docker_compose_v2_run - make sure to sanitize ``labels`` before sending them to the Docker Daemon (https://github.com/ansible-collections/community.docker/pull/985)."
- "docker_config - make sure to sanitize ``labels`` before sending them to the Docker Daemon (https://github.com/ansible-collections/community.docker/pull/985)."
- "docker_network - make sure to sanitize ``labels`` before sending them to the Docker Daemon (https://github.com/ansible-collections/community.docker/pull/985)."
- "docker_node - make sure to sanitize ``labels`` before sending them to the Docker Daemon (https://github.com/ansible-collections/community.docker/pull/985)."
- "docker_secret - make sure to sanitize ``labels`` before sending them to the Docker Daemon (https://github.com/ansible-collections/community.docker/pull/985)."
- "docker_swarm - make sure to sanitize ``labels`` before sending them to the Docker Daemon (https://github.com/ansible-collections/community.docker/pull/985)."
- "docker_swarm_service - make sure to sanitize ``labels`` and ``container_labels`` before sending them to the Docker Daemon (https://github.com/ansible-collections/community.docker/pull/985)."
- "docker_volume - make sure to sanitize ``labels`` before sending them to the Docker Daemon (https://github.com/ansible-collections/community.docker/pull/985)."

View File

@ -22,6 +22,7 @@ from ansible_collections.community.docker.plugins.module_utils.util import (
compare_generic, compare_generic,
normalize_healthcheck, normalize_healthcheck,
omit_none_from_dict, omit_none_from_dict,
sanitize_labels,
) )
from ansible_collections.community.docker.plugins.module_utils._platform import ( from ansible_collections.community.docker.plugins.module_utils._platform import (
@ -651,6 +652,17 @@ def _preprocess_mounts(module, values):
return values return values
def _preprocess_labels(module, values):
result = {}
if 'labels' in values:
labels = values['labels']
if labels is not None:
labels = dict(labels)
sanitize_labels(labels, 'labels', module=module)
result['labels'] = labels
return result
def _preprocess_log(module, values): def _preprocess_log(module, values):
result = {} result = {}
if 'log_driver' not in values: if 'log_driver' not in values:
@ -978,7 +990,7 @@ OPTION_KERNEL_MEMORY = (
) )
OPTION_LABELS = ( OPTION_LABELS = (
OptionGroup() OptionGroup(preprocess=_preprocess_labels)
.add_option('labels', type='dict', needs_no_suboptions=True) .add_option('labels', type='dict', needs_no_suboptions=True)
) )

View File

@ -12,7 +12,9 @@ from datetime import timedelta
from ansible.module_utils.basic import env_fallback from ansible.module_utils.basic import env_fallback
from ansible.module_utils.common.collections import is_sequence from ansible.module_utils.common.collections import is_sequence
from ansible.module_utils.six import string_types
from ansible.module_utils.six.moves.urllib.parse import urlparse from ansible.module_utils.six.moves.urllib.parse import urlparse
from ansible.module_utils.common.text.converters import to_text
DEFAULT_DOCKER_HOST = 'unix:///var/run/docker.sock' DEFAULT_DOCKER_HOST = 'unix:///var/run/docker.sock'
@ -283,6 +285,28 @@ class DifferenceTracker(object):
return result return result
def sanitize_labels(labels, labels_field, client=None, module=None):
def fail(msg):
if client is not None:
client.module.fail(msg)
if module is not None:
module.fail_json(msg=msg)
raise ValueError(msg)
if labels is None:
return
for k, v in list(labels.items()):
if not isinstance(k, string_types):
fail(
"The key {key!r} of {field} is not a string!".format(
field=labels_field, key=k))
if isinstance(v, (bool, float)):
fail(
"The value {value!r} for {key!r} of {field} is not a string or something than can be safely converted to a string!".format(
field=labels_field, key=k, value=v))
labels[k] = to_text(v)
def clean_dict_booleans_for_docker_api(data, allow_sequences=False): def clean_dict_booleans_for_docker_api(data, allow_sequences=False):
''' '''
Go doesn't like Python booleans 'True' or 'False', while Ansible is just Go doesn't like Python booleans 'True' or 'False', while Ansible is just

View File

@ -248,6 +248,8 @@ from ansible_collections.community.docker.plugins.module_utils.compose_v2 import
common_compose_argspec_ex, common_compose_argspec_ex,
) )
from ansible_collections.community.docker.plugins.module_utils.util import sanitize_labels
class ExecManager(BaseComposeManager): class ExecManager(BaseComposeManager):
def __init__(self, client): def __init__(self, client):
@ -416,6 +418,7 @@ def main():
needs_api_version=False, needs_api_version=False,
**argspec_ex **argspec_ex
) )
sanitize_labels(client.module.params['labels'], 'labels', client)
try: try:
manager = ExecManager(client) manager = ExecManager(client)

View File

@ -212,6 +212,7 @@ from ansible_collections.community.docker.plugins.module_utils.common import (
from ansible_collections.community.docker.plugins.module_utils.util import ( from ansible_collections.community.docker.plugins.module_utils.util import (
DockerBaseClass, DockerBaseClass,
compare_generic, compare_generic,
sanitize_labels,
) )
from ansible.module_utils.common.text.converters import to_native, to_bytes from ansible.module_utils.common.text.converters import to_native, to_bytes
@ -414,6 +415,7 @@ def main():
min_docker_api_version='1.30', min_docker_api_version='1.30',
option_minimal_versions=option_minimal_versions, option_minimal_versions=option_minimal_versions,
) )
sanitize_labels(client.module.params['labels'], 'labels', client)
try: try:
results = dict( results = dict(

View File

@ -284,6 +284,7 @@ from ansible_collections.community.docker.plugins.module_utils.util import (
DockerBaseClass, DockerBaseClass,
DifferenceTracker, DifferenceTracker,
clean_dict_booleans_for_docker_api, clean_dict_booleans_for_docker_api,
sanitize_labels,
) )
from ansible_collections.community.docker.plugins.module_utils._api.errors import DockerException from ansible_collections.community.docker.plugins.module_utils._api.errors import DockerException
@ -698,6 +699,7 @@ def main():
# "The docker server >= 1.10.0" # "The docker server >= 1.10.0"
option_minimal_versions=option_minimal_versions, option_minimal_versions=option_minimal_versions,
) )
sanitize_labels(client.module.params['labels'], 'labels', client)
try: try:
cm = DockerNetworkManager(client) cm = DockerNetworkManager(client)

View File

@ -153,6 +153,7 @@ from ansible_collections.community.docker.plugins.module_utils.common import (
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible_collections.community.docker.plugins.module_utils.swarm import AnsibleDockerSwarmClient from ansible_collections.community.docker.plugins.module_utils.swarm import AnsibleDockerSwarmClient
from ansible_collections.community.docker.plugins.module_utils.util import sanitize_labels
class TaskParameters(DockerBaseClass): class TaskParameters(DockerBaseClass):
@ -172,6 +173,8 @@ class TaskParameters(DockerBaseClass):
for key, value in client.module.params.items(): for key, value in client.module.params.items():
setattr(self, key, value) setattr(self, key, value)
sanitize_labels(self.labels, "labels", client)
class SwarmNodeManager(DockerBaseClass): class SwarmNodeManager(DockerBaseClass):

View File

@ -204,6 +204,7 @@ from ansible_collections.community.docker.plugins.module_utils.common import (
from ansible_collections.community.docker.plugins.module_utils.util import ( from ansible_collections.community.docker.plugins.module_utils.util import (
DockerBaseClass, DockerBaseClass,
compare_generic, compare_generic,
sanitize_labels,
) )
from ansible.module_utils.common.text.converters import to_native, to_bytes from ansible.module_utils.common.text.converters import to_native, to_bytes
@ -384,6 +385,7 @@ def main():
mutually_exclusive=mutually_exclusive, mutually_exclusive=mutually_exclusive,
min_docker_version='2.1.0', min_docker_version='2.1.0',
) )
sanitize_labels(client.module.params['labels'], 'labels', client)
try: try:
results = dict( results = dict(

View File

@ -324,6 +324,7 @@ from ansible_collections.community.docker.plugins.module_utils.common import (
) )
from ansible_collections.community.docker.plugins.module_utils.util import ( from ansible_collections.community.docker.plugins.module_utils.util import (
DifferenceTracker, DifferenceTracker,
sanitize_labels,
) )
from ansible_collections.community.docker.plugins.module_utils.swarm import AnsibleDockerSwarmClient from ansible_collections.community.docker.plugins.module_utils.swarm import AnsibleDockerSwarmClient
@ -714,6 +715,7 @@ def main():
min_docker_version='1.10.0', min_docker_version='1.10.0',
option_minimal_versions=option_minimal_versions, option_minimal_versions=option_minimal_versions,
) )
sanitize_labels(client.module.params['labels'], 'labels', client)
try: try:
results = dict( results = dict(

View File

@ -954,6 +954,7 @@ from ansible_collections.community.docker.plugins.module_utils.util import (
convert_duration_to_nanosecond, convert_duration_to_nanosecond,
parse_healthcheck, parse_healthcheck,
clean_dict_booleans_for_docker_api, clean_dict_booleans_for_docker_api,
sanitize_labels,
) )
from ansible.module_utils.basic import human_to_bytes from ansible.module_utils.basic import human_to_bytes
@ -1531,10 +1532,9 @@ class DockerService(DockerBaseClass):
secret_ids, secret_ids,
config_ids, config_ids,
network_ids, network_ids,
docker_api_version, client,
docker_py_version,
): ):
s = DockerService(docker_api_version, docker_py_version) s = DockerService(client.docker_api_version, client.docker_py_version)
s.image = image_digest s.image = image_digest
s.args = ap['args'] s.args = ap['args']
s.endpoint_mode = ap['endpoint_mode'] s.endpoint_mode = ap['endpoint_mode']
@ -1546,7 +1546,9 @@ class DockerService(DockerBaseClass):
s.hosts = ap['hosts'] s.hosts = ap['hosts']
s.tty = ap['tty'] s.tty = ap['tty']
s.labels = ap['labels'] s.labels = ap['labels']
sanitize_labels(s.labels, 'labels', client)
s.container_labels = ap['container_labels'] s.container_labels = ap['container_labels']
sanitize_labels(s.container_labels, 'container_labels', client)
s.sysctls = ap['sysctls'] s.sysctls = ap['sysctls']
s.mode = ap['mode'] s.mode = ap['mode']
s.stop_signal = ap['stop_signal'] s.stop_signal = ap['stop_signal']
@ -2488,8 +2490,7 @@ class DockerServiceManager(object):
secret_ids, secret_ids,
config_ids, config_ids,
network_ids, network_ids,
self.client.docker_api_version, self.client,
self.client.docker_py_version
) )
except Exception as e: except Exception as e:
return self.client.fail( return self.client.fail(

View File

@ -127,6 +127,7 @@ from ansible_collections.community.docker.plugins.module_utils.common_api import
from ansible_collections.community.docker.plugins.module_utils.util import ( from ansible_collections.community.docker.plugins.module_utils.util import (
DockerBaseClass, DockerBaseClass,
DifferenceTracker, DifferenceTracker,
sanitize_labels,
) )
from ansible_collections.community.docker.plugins.module_utils._api.errors import ( from ansible_collections.community.docker.plugins.module_utils._api.errors import (
APIError, APIError,
@ -296,6 +297,7 @@ def main():
supports_check_mode=True, supports_check_mode=True,
# "The docker server >= 1.9.0" # "The docker server >= 1.9.0"
) )
sanitize_labels(client.module.params['labels'], 'labels', client)
try: try:
cm = DockerVolumeManager(client) cm = DockerVolumeManager(client)