From da420f96d95daa564cbc7ba3697546b4b819a454 Mon Sep 17 00:00:00 2001 From: Sergey <6213510+sshnaidm@users.noreply.github.com> Date: Mon, 29 Jan 2024 00:14:51 +0200 Subject: [PATCH] Add secrets info module (#706) Signed-off-by: Sagi Shnaidman --- .github/workflows/podman_secret.yml | 82 ------------ .github/workflows/podman_secret_info.yml | 108 ++++++++++++++++ .../containers/podman_secret_info.yml | 9 ++ plugins/modules/podman_secret_info.py | 121 ++++++++++++++++++ .../targets/podman_secret_info/tasks/main.yml | 107 ++++++++++++++++ 5 files changed, 345 insertions(+), 82 deletions(-) create mode 100644 .github/workflows/podman_secret_info.yml create mode 100644 ci/playbooks/containers/podman_secret_info.yml create mode 100644 plugins/modules/podman_secret_info.py create mode 100644 tests/integration/targets/podman_secret_info/tasks/main.yml diff --git a/.github/workflows/podman_secret.yml b/.github/workflows/podman_secret.yml index 7b13b2a8..95a1ef9e 100644 --- a/.github/workflows/podman_secret.yml +++ b/.github/workflows/podman_secret.yml @@ -108,85 +108,3 @@ jobs: TEST2RUN=podman_secret ./ci/run_containers_tests.sh shell: bash - - test_podman_secret_with_pip: - name: Podman secret w/ pip ${{ matrix.ansible-version }}-${{ matrix.os || 'ubuntu-22.04' }} - runs-on: ${{ matrix.os || 'ubuntu-22.04' }} - defaults: - run: - shell: bash - strategy: - fail-fast: false - matrix: - ansible-version: - - ansible<2.10 - #- git+https://github.com/ansible/ansible.git@stable-2.10 - os: - - ubuntu-22.04 - python-version: - - 3.9 - - steps: - - - name: Check out repository - uses: actions/checkout@v4 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Upgrade pip and display Python and PIP versions - run: | - sudo apt-get update - sudo apt-get install -y python*-wheel python*-yaml - python -m pip install --upgrade pip - python -V - pip --version - - - name: Set up pip cache - uses: actions/cache@v4 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ github.ref }}-units-VMs - restore-keys: | - ${{ runner.os }}-pip- - ${{ runner.os }}- - - - name: Install Ansible ${{ matrix.ansible-version }} - run: python3 -m pip install --user --force-reinstall --upgrade '${{ matrix.ansible-version }}' - - - name: Build and install the collection tarball - run: | - export PATH=~/.local/bin:$PATH - - echo "Run ansible version" - command -v ansible - ansible --version - python3 -m pip install --user --force-reinstall --upgrade . - - - - name: Run collection tests for podman secret - run: | - export PATH=~/.local/bin:$PATH - export ANSIBLE_COLLECTIONS_PATHS=~/.local/share/ansible/collections - - export ANSIBLE_CONFIG=$(pwd)/ci/ansible-dev.cfg - if [[ '${{ matrix.ansible-version }}' == 'ansible<2.10' ]]; then - export ANSIBLE_CONFIG=$(pwd)/ci/ansible-2.9.cfg - fi - - echo $ANSIBLE_CONFIG - command -v ansible-playbook - pip --version - python --version - ansible-playbook --version - - ansible-playbook -vv ci/playbooks/pre.yml \ - -e host=localhost \ - -i localhost, \ - -e ansible_connection=local \ - -e setup_python=false - - TEST2RUN=podman_secret ./ci/run_containers_tests.sh - shell: bash diff --git a/.github/workflows/podman_secret_info.yml b/.github/workflows/podman_secret_info.yml new file mode 100644 index 00000000..2a6184ab --- /dev/null +++ b/.github/workflows/podman_secret_info.yml @@ -0,0 +1,108 @@ +name: Podman secret info + +on: + push: + paths: + - '.github/workflows/podman_secret_info.yml' + - 'ci/*.yml' + - 'ci/run_containers_tests.sh' + - 'ci/playbooks/containers/podman_secret_info.yml' + - 'plugins/modules/podman_secret.py' + - 'plugins/modules/podman_secret_info.py' + branches: + - master + pull_request: + paths: + - '.github/workflows/podman_secret_info.yml' + - 'ci/*.yml' + - 'ci/run_containers_tests.sh' + - 'ci/playbooks/containers/podman_secret_info.yml' + - 'plugins/modules/podman_secret.py' + - 'plugins/modules/podman_secret_info.py' + schedule: + - cron: 4 0 * * * # Run daily at 0:03 UTC + +jobs: + + test_podman_secret_info: + name: Podman secret info ${{ matrix.ansible-version }}-${{ matrix.os || 'ubuntu-22.04' }} + runs-on: ${{ matrix.os || 'ubuntu-22.04' }} + defaults: + run: + shell: bash + strategy: + fail-fast: false + matrix: + ansible-version: + - ansible<2.10 + - git+https://github.com/ansible/ansible.git@stable-2.15 + - git+https://github.com/ansible/ansible.git@devel + os: + - ubuntu-22.04 + python-version: + - "3.10" + + steps: + + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Upgrade pip and display Python and PIP versions + run: | + sudo apt-get update + sudo apt-get install -y python*-wheel python*-yaml + python -m pip install --upgrade pip + python -V + pip --version + + - name: Set up pip cache + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ github.ref }}-units-VMs + restore-keys: | + ${{ runner.os }}-pip- + ${{ runner.os }}- + + - name: Install Ansible ${{ matrix.ansible-version }} + run: python3 -m pip install --user --force-reinstall --upgrade '${{ matrix.ansible-version }}' + + - name: Build and install the collection tarball + run: | + export PATH=~/.local/bin:$PATH + + echo "Run ansible version" + command -v ansible + ansible --version + rm -rf /tmp/just_new_collection + ~/.local/bin/ansible-galaxy collection build --output-path /tmp/just_new_collection --force + ~/.local/bin/ansible-galaxy collection install -vvv --force /tmp/just_new_collection/*.tar.gz + + - name: Run collection tests for podman secret info + run: | + export PATH=~/.local/bin:$PATH + + export ANSIBLE_CONFIG=$(pwd)/ci/ansible-dev.cfg + if [[ '${{ matrix.ansible-version }}' == 'ansible<2.10' ]]; then + export ANSIBLE_CONFIG=$(pwd)/ci/ansible-2.9.cfg + fi + + echo $ANSIBLE_CONFIG + command -v ansible-playbook + pip --version + python --version + ansible-playbook --version + + ansible-playbook -vv ci/playbooks/pre.yml \ + -e host=localhost \ + -i localhost, \ + -e ansible_connection=local \ + -e setup_python=false + + TEST2RUN=podman_secret_info ./ci/run_containers_tests.sh + shell: bash diff --git a/ci/playbooks/containers/podman_secret_info.yml b/ci/playbooks/containers/podman_secret_info.yml new file mode 100644 index 00000000..6528f07a --- /dev/null +++ b/ci/playbooks/containers/podman_secret_info.yml @@ -0,0 +1,9 @@ +--- +- hosts: all + gather_facts: true + tasks: + - include_role: + name: podman_secret_info + vars: + idem_image: idempotency_test + ansible_python_interpreter: "{{ _ansible_python_interpreter }}" diff --git a/plugins/modules/podman_secret_info.py b/plugins/modules/podman_secret_info.py new file mode 100644 index 00000000..ebe85424 --- /dev/null +++ b/plugins/modules/podman_secret_info.py @@ -0,0 +1,121 @@ +#!/usr/bin/python +# Copyright (c) 2024 Red Hat +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +DOCUMENTATION = r''' +module: podman_secret_info +author: + - "Sagi Shnaidman (@sshnaidm)" +short_description: Gather info about podman secrets +notes: [] +description: + - Gather info about podman secrets with podman inspect command. +requirements: + - "Podman installed on host" +options: + name: + description: + - Name of the secret + type: str + showsecret: + description: + - Show secret data value + type: bool + default: False + executable: + description: + - Path to C(podman) executable if it is not in the C($PATH) on the + machine running C(podman) + default: 'podman' + type: str +''' + +EXAMPLES = r""" +- name: Gather info about all present secrets + podman_secret_info: + +- name: Gather info about specific secret + podman_secret_info: + name: specific_secret +""" + +RETURN = r""" +secrets: + description: Facts from all or specified secrets + returned: always + type: list + sample: [ + { + "ID": "06068c676e9a7f1c7dc0da8dd", + "CreatedAt": "2024-01-28T20:32:08.31857841+02:00", + "UpdatedAt": "2024-01-28T20:32:08.31857841+02:00", + "Spec": { + "Name": "secret_name", + "Driver": { + "Name": "file", + "Options": { + "path": "/home/user/.local/share/containers/storage/secrets/filedriver" + } + }, + "Labels": {} + } + } + ] +""" + +import json +from ansible.module_utils.basic import AnsibleModule + + +def get_secret_info(module, executable, show, name): + command = [executable, 'secret', 'inspect'] + if show: + command.append('--showsecret') + if name: + command.append(name) + else: + all_names = [executable, 'secret', 'ls', '-q'] + rc, out, err = module.run_command(all_names) + name = out.split() + if not name: + return [], out, err + command.extend(name) + rc, out, err = module.run_command(command) + if rc != 0 or 'no secret with name or id' in err: + module.fail_json(msg="Unable to gather info for %s: %s" % (name or 'all secrets', err)) + if not out or json.loads(out) is None: + return [], out, err + return json.loads(out), out, err + + +def main(): + module = AnsibleModule( + argument_spec=dict( + executable=dict(type='str', default='podman'), + name=dict(type='str'), + showsecret=dict(type='bool', default=False), + ), + supports_check_mode=True, + ) + + name = module.params['name'] + showsecret = module.params['showsecret'] + executable = module.get_bin_path(module.params['executable'], required=True) + + inspect_results, out, err = get_secret_info(module, executable, showsecret, name) + + results = { + "changed": False, + "secrets": inspect_results, + "stderr": err, + } + + module.exit_json(**results) + + +if __name__ == '__main__': + main() diff --git a/tests/integration/targets/podman_secret_info/tasks/main.yml b/tests/integration/targets/podman_secret_info/tasks/main.yml new file mode 100644 index 00000000..90c588f6 --- /dev/null +++ b/tests/integration/targets/podman_secret_info/tasks/main.yml @@ -0,0 +1,107 @@ +- name: Test podman_secret + block: + + - name: Discover podman version + shell: podman version | grep "^Version:" | awk {'print $2'} + register: podman_v + + - name: Set podman version fact + set_fact: + podman_version: "{{ podman_v.stdout | string }}" + + - name: Set podman version fact to gt than 4.7.0 if so + set_fact: + podman_version_gt470: "{{ podman_version is version('4.7.0', '>=') }}" + + - name: Make sure secrets don't exist + containers.podman.podman_secret: + executable: "{{ test_executable | default('podman') }}" + state: absent + name: "{{ item }}" + loop: + - mysecret + - second_secret + + - name: Create secret + containers.podman.podman_secret: + executable: "{{ test_executable | default('podman') }}" + name: mysecret + debug: true + data: secret content + + - name: Create another secret + containers.podman.podman_secret: + executable: "{{ test_executable | default('podman') }}" + name: second_secret + debug: true + data: "not secret content" + + - name: Get info about all secrets + containers.podman.podman_secret_info: + executable: "{{ test_executable | default('podman') }}" + register: secrets_info + + - name: Get info about one secret + containers.podman.podman_secret_info: + executable: "{{ test_executable | default('podman') }}" + name: mysecret + register: mysecret_info + + - name: Get info about second secret with secret data + containers.podman.podman_secret_info: + executable: "{{ test_executable | default('podman') }}" + name: second_secret + showsecret: true + register: second_secret_info + when: podman_version_gt470 + + - name: Get info about secret that does not exist + containers.podman.podman_secret_info: + executable: "{{ test_executable | default('podman') }}" + name: doesnotexist + register: notfound + ignore_errors: true + + # Delete all secrets + - name: Remove secrets + containers.podman.podman_secret: + executable: "{{ test_executable | default('podman') }}" + state: absent + name: "{{ item }}" + loop: + - mysecret + - second_secret + + - name: Get info about all secrets when no secrets + containers.podman.podman_secret_info: + executable: "{{ test_executable | default('podman') }}" + register: secrets_info2 + + - name: Check secrets info + assert: + that: + - secrets_info.secrets | length == 2 + - mysecret_info.secrets | length == 1 + - mysecret_info.secrets[0].Spec.Name == 'mysecret' + - "'SecretData' not in mysecret_info.secrets[0]" + - notfound is failed + - secrets_info2.secrets | length == 0 + + - name: Check secrets info for Podman > 4.7.0 + assert: + that: + - second_secret_info.secrets[0].SecretData == 'not secret content' + - second_secret_info.secrets | length == 1 + - second_secret_info.secrets[0].Spec.Name == 'second_secret' + when: podman_version_gt470 + + always: + + - name: Remove secrets + containers.podman.podman_secret: + executable: "{{ test_executable | default('podman') }}" + state: absent + name: "{{ item }}" + loop: + - mysecret + - second_secret