mirror of
https://github.com/ansible-collections/community.docker.git
synced 2025-12-16 11:58:43 +00:00
Rewrite the docker_containers inventory plugin (#413)
* Rewrite the docker_containers inventory plugin. * Improve error messages.
This commit is contained in:
parent
c3a76007d0
commit
23a90668c9
4
changelogs/fragments/413-docker-api.yml
Normal file
4
changelogs/fragments/413-docker-api.yml
Normal file
@ -0,0 +1,4 @@
|
||||
major_changes:
|
||||
- "docker_containers inventory plugin - no longer uses the Docker SDK for Python. It requires ``requests`` to be installed,
|
||||
and depending on the features used has some more requirements. If the Docker SDK for Python is installed,
|
||||
these requirements are likely met (https://github.com/ansible-collections/community.docker/pull/413)."
|
||||
@ -17,12 +17,9 @@ short_description: Ansible dynamic inventory plugin for Docker containers.
|
||||
version_added: 1.1.0
|
||||
author:
|
||||
- Felix Fontein (@felixfontein)
|
||||
requirements:
|
||||
- L(Docker SDK for Python,https://docker-py.readthedocs.io/en/stable/) >= 1.10.0
|
||||
extends_documentation_fragment:
|
||||
- ansible.builtin.constructed
|
||||
- community.docker.docker
|
||||
- community.docker.docker.docker_py_1_documentation
|
||||
- community.docker.docker.api_documentation
|
||||
description:
|
||||
- Reads inventories from the Docker API.
|
||||
- Uses a YAML configuration file that ends with C(docker.[yml|yaml]).
|
||||
@ -154,23 +151,18 @@ from ansible.errors import AnsibleError
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable
|
||||
|
||||
from ansible_collections.community.docker.plugins.module_utils.common import (
|
||||
from ansible_collections.community.docker.plugins.module_utils.common_api import (
|
||||
RequestException,
|
||||
)
|
||||
from ansible_collections.community.docker.plugins.module_utils.util import (
|
||||
DOCKER_COMMON_ARGS_VARS,
|
||||
)
|
||||
from ansible_collections.community.docker.plugins.plugin_utils.common import (
|
||||
from ansible_collections.community.docker.plugins.plugin_utils.common_api import (
|
||||
AnsibleDockerClient,
|
||||
)
|
||||
|
||||
try:
|
||||
from docker.errors import DockerException, APIError
|
||||
except Exception:
|
||||
# missing Docker SDK for Python handled in ansible_collections.community.docker.plugins.module_utils.common
|
||||
pass
|
||||
from ansible_collections.community.docker.plugins.module_utils._api.errors import APIError, DockerException
|
||||
|
||||
MIN_DOCKER_PY = '1.7.0'
|
||||
MIN_DOCKER_API = None
|
||||
|
||||
|
||||
@ -193,7 +185,15 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
add_legacy_groups = self.get_option('add_legacy_groups')
|
||||
|
||||
try:
|
||||
containers = client.containers(all=True)
|
||||
params = {
|
||||
'limit': -1,
|
||||
'all': 1,
|
||||
'size': 0,
|
||||
'trunc_cmd': 0,
|
||||
'since': None,
|
||||
'before': None,
|
||||
}
|
||||
containers = client.get_json('/containers/json', params=params)
|
||||
except APIError as exc:
|
||||
raise AnsibleError("Error listing containers: %s" % to_native(exc))
|
||||
|
||||
@ -227,7 +227,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
full_facts = dict()
|
||||
|
||||
try:
|
||||
inspect = client.inspect_container(id)
|
||||
inspect = client.get_json('/containers/{0}/json', id)
|
||||
except APIError as exc:
|
||||
raise AnsibleError("Error inspecting container %s - %s" % (name, str(exc)))
|
||||
|
||||
@ -261,7 +261,9 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
# Figure out ssh IP and Port
|
||||
try:
|
||||
# Lookup the public facing port Nat'ed to ssh port.
|
||||
port = client.port(container, ssh_port)[0]
|
||||
network_settings = inspect.get('NetworkSettings') or {}
|
||||
port_settings = network_settings.get('Ports') or {}
|
||||
port = port_settings.get('%d/tcp' % (ssh_port, ))[0]
|
||||
except (IndexError, AttributeError, TypeError):
|
||||
port = dict()
|
||||
|
||||
@ -330,7 +332,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
path.endswith(('docker.yaml', 'docker.yml')))
|
||||
|
||||
def _create_client(self):
|
||||
return AnsibleDockerClient(self, min_docker_version=MIN_DOCKER_PY, min_docker_api_version=MIN_DOCKER_API)
|
||||
return AnsibleDockerClient(self, min_docker_api_version=MIN_DOCKER_API)
|
||||
|
||||
def parse(self, inventory, loader, path, cache=True):
|
||||
super(InventoryModule, self).parse(inventory, loader, path, cache)
|
||||
@ -340,9 +342,9 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||
self._populate(client)
|
||||
except DockerException as e:
|
||||
raise AnsibleError(
|
||||
'An unexpected docker error occurred: {0}'.format(e)
|
||||
'An unexpected Docker error occurred: {0}'.format(e)
|
||||
)
|
||||
except RequestException as e:
|
||||
raise AnsibleError(
|
||||
'An unexpected requests error occurred when Docker SDK for Python tried to talk to the docker daemon: {0}'.format(e)
|
||||
'An unexpected requests error occurred when trying to talk to the Docker daemon: {0}'.format(e)
|
||||
)
|
||||
|
||||
@ -93,29 +93,22 @@ def create_get_option(options, default=False):
|
||||
|
||||
class FakeClient(object):
|
||||
def __init__(self, *hosts):
|
||||
self.hosts = dict()
|
||||
self.list_reply = []
|
||||
self.get_results = {}
|
||||
list_reply = []
|
||||
for host in hosts:
|
||||
self.list_reply.append({
|
||||
list_reply.append({
|
||||
'Id': host['Id'],
|
||||
'Names': [host['Name']] if host['Name'] else [],
|
||||
'Image': host['Config']['Image'],
|
||||
'ImageId': host['Image'],
|
||||
})
|
||||
self.hosts[host['Name']] = host
|
||||
self.hosts[host['Id']] = host
|
||||
self.get_results['/containers/{0}/json'.format(host['Name'])] = host
|
||||
self.get_results['/containers/{0}/json'.format(host['Id'])] = host
|
||||
self.get_results['/containers/json'] = list_reply
|
||||
|
||||
def containers(self, all=False):
|
||||
return list(self.list_reply)
|
||||
|
||||
def inspect_container(self, id):
|
||||
return self.hosts[id]
|
||||
|
||||
def port(self, container, port):
|
||||
host = self.hosts[container['Id']]
|
||||
network_settings = host.get('NetworkSettings') or dict()
|
||||
ports = network_settings.get('Ports') or dict()
|
||||
return ports.get('{0}/tcp'.format(port)) or []
|
||||
def get_json(self, url, *param, **kwargs):
|
||||
url = url.format(*param)
|
||||
return self.get_results[url]
|
||||
|
||||
|
||||
def test_populate(inventory, mocker):
|
||||
|
||||
Loading…
Reference in New Issue
Block a user