aboutsummaryrefslogtreecommitdiff
path: root/ansible/library
diff options
context:
space:
mode:
authorIvan Halomi <ivan.halomi@tietoevry.com>2024-03-06 10:53:21 +0100
committerIvan Halomi <ivan.halomi@tietoevry.com>2024-08-12 09:54:05 +0200
commit4ce47e225064dd99bd04ad8a63283287cde5282f (patch)
treea39bdda8faa7c6674ab1603204d919e624bcef3a /ansible/library
parent416574c8b48a342fac5c99806a227cabb1782841 (diff)
downloadkolla-ansible-4ce47e225064dd99bd04ad8a63283287cde5282f.tar.gz
kolla-ansible-4ce47e225064dd99bd04ad8a63283287cde5282f.zip
Refactor of kolla_container_facts
Refactor that prepares kolla_container_facts module for introducing more actions that will be moved from kolla_container module and kolla_container_volume_facts. This change is based on a discussion about adding a new action to kolla_container module that retrieves all names of the running containers. It was agreed that kolla-ansible should follow Ansible's direction of splitting modules between action modules and facts modules. Because of this, kolla_container_facts needs to be able to handle different requests for data about containers or volumes. Change-Id: Ieaec8f64922e4e5a2199db2d6983518b124cb4aa Signed-off-by: Ivan Halomi <ivan.halomi@tietoevry.com>
Diffstat (limited to 'ansible/library')
-rw-r--r--ansible/library/kolla_container_facts.py142
1 files changed, 89 insertions, 53 deletions
diff --git a/ansible/library/kolla_container_facts.py b/ansible/library/kolla_container_facts.py
index ef3617db2..7e2254e51 100644
--- a/ansible/library/kolla_container_facts.py
+++ b/ansible/library/kolla_container_facts.py
@@ -12,8 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-
+from abc import ABC
+from abc import abstractmethod
from ansible.module_utils.basic import AnsibleModule
+from traceback import format_exc
DOCUMENTATION = '''
@@ -40,9 +42,9 @@ options:
- Name or names of the containers
required: False
type: str or list
- container_engine:
+ action:
description:
- - Name of container engine to use
+ - The action to perform
required: True
type: str
author: Jeffrey Zhang
@@ -54,6 +56,7 @@ EXAMPLES = '''
- name: Gather docker facts
kolla_container_facts:
container_engine: docker
+ action: get_containers
- name: Gather glance container facts
kolla_container_facts:
@@ -62,70 +65,103 @@ EXAMPLES = '''
- glance_api
- glance_registry
container_engine: podman
+ action: get_containers
'''
-def get_docker_client():
- import docker
- return docker.APIClient
-
-
-def use_docker(module, results):
- client = get_docker_client()(version=module.params.get('api_version'))
-
- containers = client.containers()
- names = module.params.get('name')
- if names and not isinstance(names, list):
- names = [names]
- for container in containers:
- for container_name in container['Names']:
- # remove '/' prefix character
- container_name = container_name[1:]
- if names and container_name not in names:
+class ContainerFactsWorker(ABC):
+ def __init__(self, module):
+ self.module = module
+ self.results = dict(changed=False, _containers=[])
+ self.params = module.params
+
+ @abstractmethod
+ def get_containers(self):
+ pass
+
+
+class DockerFactsWorker(ContainerFactsWorker):
+ def __init__(self, module):
+ super().__init__(module)
+ try:
+ import docker
+ except ImportError:
+ self.module.fail_json(
+ msg="The docker library could not be imported")
+ self.client = docker.APIClient(version=module.params.get(
+ 'api_version'))
+
+ def get_containers(self):
+ containers = self.client.containers()
+ names = self.params.get('name')
+ if names and not isinstance(names, list):
+ names = [names]
+ for container in containers:
+ for container_name in container['Names']:
+ # remove '/' prefix character
+ container_name = container_name[1:]
+ if names and container_name not in names:
+ continue
+ self.results['_containers'].append(container)
+ self.results[container_name] = container
+
+
+class PodmanFactsWorker(ContainerFactsWorker):
+ def __init__(self, module):
+ try:
+ import podman.errors as podmanError
+ from podman import PodmanClient
+ except ImportError:
+ self.module.fail_json(
+ msg="The podman library could not be imported")
+ self.podmanError = podmanError
+ super().__init__(module)
+ self.client = PodmanClient(
+ base_url="http+unix:/run/podman/podman.sock")
+
+ def get_containers(self):
+ try:
+ containers = self.client.containers.list(
+ all=True, ignore_removed=True)
+ except self.podmanError.APIError as e:
+ self.module.fail_json(failed=True,
+ msg=f"Internal error: {e.explanation}")
+ names = self.params.get('name')
+ if names and not isinstance(names, list):
+ names = [names]
+
+ for container in containers:
+ container.reload()
+ container_name = container.attrs['Name']
+ if container_name not in names:
continue
- results['_containers'].append(container)
- results[container_name] = container
-
-
-def use_podman(module, results):
- import podman.errors as pe
- from podman import PodmanClient
-
- client = PodmanClient(base_url="http+unix:/run/podman/podman.sock")
-
- try:
- containers = client.containers.list(all=True, ignore_removed=True)
- except pe.APIError as e:
- module.fail_json(failed=True, msg=f"Internal error: {e.explanation}")
- names = module.params.get('name')
- if names and not isinstance(names, list):
- names = [names]
-
- for container in containers:
- container.reload()
- container_name = container.attrs['Name']
- if names and container_name not in names:
- continue
- results['_containers'].append(container.attrs)
- results[container_name] = container.attrs
+ self.results['_containers'].append(container.attrs)
+ self.results[container_name] = container.attrs
def main():
argument_spec = dict(
name=dict(required=False, type='list', default=[]),
api_version=dict(required=False, type='str', default='auto'),
- container_engine=dict(required=True, type='str')
+ container_engine=dict(required=True, type='str'),
+ action=dict(required=True, type='str',
+ choices=['get_containers']),
)
module = AnsibleModule(argument_spec=argument_spec)
- results = dict(changed=False, _containers=[])
- if module.params['container_engine'] == 'podman':
- use_podman(module, results)
- else:
- use_docker(module, results)
-
- module.exit_json(**results)
+ cw: ContainerFactsWorker = None
+ try:
+ if module.params.get('container_engine') == 'docker':
+ cw = DockerFactsWorker(module)
+ else:
+ cw = PodmanFactsWorker(module)
+
+ result = bool(getattr(cw, module.params.get('action'))())
+ module.exit_json(result=result, **cw.results)
+ except Exception:
+ module.fail_json(changed=True, msg=repr(format_exc()),
+ **getattr(cw, 'result', {}))
if __name__ == "__main__":