From 755fc0f5116220afc05667316f599482490d967f Mon Sep 17 00:00:00 2001 From: Sagi Shnaidman Date: Sat, 12 Oct 2024 00:06:06 +0300 Subject: [PATCH] Add option to specify kube file content in module Fix #463 Signed-off-by: Sagi Shnaidman --- plugins/modules/podman_play.py | 40 +++- .../targets/podman_play/tasks/main.yml | 172 ++++++++++++++++++ 2 files changed, 203 insertions(+), 9 deletions(-) diff --git a/plugins/modules/podman_play.py b/plugins/modules/podman_play.py index 66138efc..a8493dbe 100644 --- a/plugins/modules/podman_play.py +++ b/plugins/modules/podman_play.py @@ -28,7 +28,10 @@ description: - Path to file with YAML configuration for a Pod. type: path - required: True + kube_file_content: + description: + - Content of the kube file. + type: str annotation: description: - Add an annotation to the container or pod. @@ -268,10 +271,16 @@ def __init__(self, module, executable): }.items(): if self.module.params[param] is not None: self.command += ["%s=%s" % (arg, self.module.params[param])] - self.command += [self.module.params['kube_file']] + if self.module.params['kube_file']: + self.command += [self.module.params['kube_file']] + elif self.module.params['kube_file_content']: + self.command += ['-'] def _command_run(self, cmd): - rc, out, err = self.module.run_command(cmd) + if self.module.params['kube_file_content']: + rc, out, err = self.module.run_command(cmd, data=self.module.params['kube_file_content']) + else: + rc, out, err = self.module.run_command(cmd) self.actions.append(" ".join(cmd)) if self.module.params['debug']: self.module.log('PODMAN-PLAY-KUBE command: %s' % " ".join(cmd)) @@ -287,13 +296,20 @@ def tear_down_pods(self): ''' changed = False kube_file = self.module.params['kube_file'] - - rc, out, err = self._command_run([self.executable, "kube", "play", "--down", kube_file]) + kube_file_content = self.module.params['kube_file_content'] + if kube_file: + rc, out, err = self._command_run([self.executable, "kube", "play", "--down", kube_file]) + elif kube_file_content: + rc, out, err = self._command_run([self.executable, "kube", "play", "--down", "-"]) if rc != 0: - self.module.fail_json(msg="Failed to delete Pod with %s" % (kube_file)) - else: - changed = True + self.module.fail_json(msg="Failed to delete Pod with %s" % ( + kube_file if kube_file else "YAML content")) + # hack to check if no resources are deleted + for line in out.splitlines(): + if line and not line.endswith(':'): + changed = True + break return changed, out, err def discover_pods(self): @@ -384,7 +400,8 @@ def main(): argument_spec=dict( annotation=dict(type='dict', aliases=['annotations']), executable=dict(type='str', default='podman'), - kube_file=dict(type='path', required=True), + kube_file=dict(type='path'), + kube_file_content=dict(type='str'), authfile=dict(type='path'), build=dict(type='bool'), cert_dir=dict(type='path'), @@ -419,11 +436,16 @@ def main(): required_if=[ ('state', 'quadlet', ['quadlet_filename']), ], + required_one_of=[ + ('kube_file', 'kube_file_content'), + ], ) executable = module.get_bin_path( module.params['executable'], required=True) manage = PodmanKubeManagement(module, executable) + changed = False + out = err = '' if module.params['state'] == 'absent': if manage.version is not None and LooseVersion(manage.version) > LooseVersion('3.4.0'): manage.module.log(msg="version: %s, kube file %s" % (manage.version, manage.module.params['kube_file'])) diff --git a/tests/integration/targets/podman_play/tasks/main.yml b/tests/integration/targets/podman_play/tasks/main.yml index d22615e4..35e2912f 100644 --- a/tests/integration/targets/podman_play/tasks/main.yml +++ b/tests/integration/targets/podman_play/tasks/main.yml @@ -130,6 +130,177 @@ that: - nonexist.pods == [] + - name: Run with file content + containers.podman.podman_play: + executable: "{{ test_executable | default('podman') }}" + debug: true + state: started + kube_file_content: | + kind: ConfigMap + metadata: + name: new + data: + FOO1: bar1 + --- + apiVersion: v1 + kind: Pod + metadata: + name: contentpod + spec: + containers: + - command: + - top + name: container-42 + image: alpine + envFrom: + - configMapRef: + name: new + optional: false + --- + apiVersion: v1 + kind: ConfigMap + metadata: + name: newest + data: + FOO3: bar3 + register: playc1 + + - name: Get info about pods + containers.podman.podman_pod_info: + executable: "{{ test_executable | default('podman') }}" + register: infopods + + - name: Check if the pod was created + assert: + that: + - "'contentpod' in (infopods.pods | map(attribute='Name') | list)" + + - name: Run with file content - again + containers.podman.podman_play: + executable: "{{ test_executable | default('podman') }}" + debug: true + state: started + kube_file_content: | + kind: ConfigMap + metadata: + name: new + data: + FOO1: bar1 + --- + apiVersion: v1 + kind: Pod + metadata: + name: contentpod + spec: + containers: + - command: + - top + name: container-42 + image: alpine + envFrom: + - configMapRef: + name: new + optional: false + --- + apiVersion: v1 + kind: ConfigMap + metadata: + name: newest + data: + FOO3: bar3 + register: playc2 + + - name: Check info + assert: + that: + - playc1 is changed + - playc2 is not changed + + - name: Remove with file content + containers.podman.podman_play: + executable: "{{ test_executable | default('podman') }}" + debug: true + state: absent + kube_file_content: | + kind: ConfigMap + metadata: + name: new + data: + FOO1: bar1 + --- + apiVersion: v1 + kind: Pod + metadata: + name: contentpod + spec: + containers: + - command: + - top + name: container-42 + image: alpine + envFrom: + - configMapRef: + name: new + optional: false + --- + apiVersion: v1 + kind: ConfigMap + metadata: + name: newest + data: + FOO3: bar3 + register: playc3 + + - name: Remove with file content - again + containers.podman.podman_play: + executable: "{{ test_executable | default('podman') }}" + debug: true + state: absent + kube_file_content: | + kind: ConfigMap + metadata: + name: new + data: + FOO1: bar1 + --- + apiVersion: v1 + kind: Pod + metadata: + name: contentpod + spec: + containers: + - command: + - top + name: container-42 + image: alpine + envFrom: + - configMapRef: + name: new + optional: false + --- + apiVersion: v1 + kind: ConfigMap + metadata: + name: newest + data: + FOO3: bar3 + register: playc4 + + - name: Check info + assert: + that: + - playc3 is changed + - playc4 is not changed + + - name: Get info about pods + containers.podman.podman_pod_info: + executable: "{{ test_executable | default('podman') }}" + register: infopods2 + + - name: Check if the pod was created + assert: + that: + - "'contentpod' not in (infopods2.pods | map(attribute='Name') | list)" - name: Create a Quadlet for kube with filename containers.podman.podman_play: @@ -294,6 +465,7 @@ - web-deploy-pod-0 - web-deploy-pod-1 - web-deploy-pod-2 + - contentpod - name: Test idempotency for root pods include_tasks: root-play.yml