From fd32760d7a1c42573e09055b822f0958f60a3874 Mon Sep 17 00:00:00 2001 From: Rich Wareham Date: Mon, 14 Jan 2019 11:00:34 +0000 Subject: [PATCH] docker_swarm_service: use exact name match when finding services (#50665) * docker_swarm_service: use exact name match when finding services The Docker API's filtering support allows filtering for substring matches which means that when we filter the list of running services we may accidentally match a service called "foobar" when looking for a service named "foo". Fix this by filtering the list of services returned from the Docker API so that name matches are exact. It is still worth passing the filter parameter to the Docker API because it reduces the number of results passed back which may be important for remote Docker connections. Closes 50654. * add changelog fragment for #50654 --- .../50654-docker-swarm-service-docker-api-fix.yaml | 2 ++ .../modules/cloud/docker/docker_swarm_service.py | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 changelogs/fragments/50654-docker-swarm-service-docker-api-fix.yaml diff --git a/changelogs/fragments/50654-docker-swarm-service-docker-api-fix.yaml b/changelogs/fragments/50654-docker-swarm-service-docker-api-fix.yaml new file mode 100644 index 00000000000..3664fe8b92d --- /dev/null +++ b/changelogs/fragments/50654-docker-swarm-service-docker-api-fix.yaml @@ -0,0 +1,2 @@ +bugfixes: + - "docker_swarm_service - fix use of Docker API so that services are not detected as present if there is an existing service whose name is a substring of the desired service" diff --git a/lib/ansible/modules/cloud/docker/docker_swarm_service.py b/lib/ansible/modules/cloud/docker/docker_swarm_service.py index 0294abc8ce9..3045fdbc6b4 100644 --- a/lib/ansible/modules/cloud/docker/docker_swarm_service.py +++ b/lib/ansible/modules/cloud/docker/docker_swarm_service.py @@ -875,7 +875,16 @@ class DockerServiceManager(): return [{'name': n['Name'], 'id': n['Id']} for n in self.client.networks()] def get_service(self, name): - raw_data = self.client.services(filters={'name': name}) + # The Docker API allows filtering services by name but the filter looks + # for a substring match, not an exact match. (Filtering for "foo" would + # return information for services "foobar" and "foobuzz" even if the + # service "foo" doesn't exist.) Avoid incorrectly determining that a + # service is present by filtering the list of services returned from the + # Docker API so that the name must be an exact match. + raw_data = [ + service for service in self.client.services(filters={'name': name}) + if service['Spec']['Name'] == name + ] if len(raw_data) == 0: return None