diff options
| author | Ivan Halomi <ivan.halomi@tietoevry.com> | 2024-03-06 10:53:21 +0100 |
|---|---|---|
| committer | Ivan Halomi <ivan.halomi@tietoevry.com> | 2024-08-12 09:54:05 +0200 |
| commit | 4ce47e225064dd99bd04ad8a63283287cde5282f (patch) | |
| tree | a39bdda8faa7c6674ab1603204d919e624bcef3a /ansible/library | |
| parent | 416574c8b48a342fac5c99806a227cabb1782841 (diff) | |
| download | kolla-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.py | 142 |
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__": |
