From 8bb3d5d233888e3ec37cdaa068703ab4c258b76c Mon Sep 17 00:00:00 2001 From: Jason Hiatt Date: Mon, 5 Apr 2021 08:22:13 -0500 Subject: [PATCH] Podman login module (#236) * Module for podman login * Podman login tests * Fixed tlsverify check --- plugins/modules/podman_login.py | 160 ++++++++++++++++++ .../targets/podman_login/tasks/main.yml | 33 ++++ 2 files changed, 193 insertions(+) create mode 100644 plugins/modules/podman_login.py create mode 100644 tests/integration/targets/podman_login/tasks/main.yml diff --git a/plugins/modules/podman_login.py b/plugins/modules/podman_login.py new file mode 100644 index 0000000..edd1a4d --- /dev/null +++ b/plugins/modules/podman_login.py @@ -0,0 +1,160 @@ +#!/usr/bin/python +# 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_login +author: + - "Jason Hiatt (@jthiatt)" +short_description: Login to a container registry using podman +notes: [] +description: + - Login to a container registry server using the podman login command + If the registry is not specified, the first registry under + `[registries.search]` from `registries.conf `will be used. The path of + the authentication file can be overridden by the user by setting the + `authfile` flag. The default path used is + `${XDG_RUNTIME_DIR}/containers/auth.json`. +requirements: + - "Podman installed on host" +options: + authfile: + description: + - Path of the authentication file. Default is + ``${XDG_RUNTIME_DIR}/containers/auth.json`` + You can also override the default path of the authentication + file by setting the ``REGISTRY_AUTH_FILE`` environment + variable. ``export REGISTRY_AUTH_FILE=path`` + type: path + certdir: + description: + - Use certificates at path (*.crt, *.cert, *.key) to connect + to the registry. Default certificates directory + is /etc/containers/certs.d. + type: path + password: + description: + - Password for the registry server. + required: True + type: str + registry: + description: + - Registry server. If the registry is not specified, + the first registry under `[registries.search]` from + `registries.conf` will be used. + type: str + tlsverify: + description: + - Require HTTPS and verify certificates when + contacting registries. If explicitly set to true, + then TLS verification will be used. If set to false, + then TLS verification will not be used. If not specified, + TLS verification will be used unless the target registry + is listed as an insecure registry in registries.conf. + type: bool + username: + description: + - Username for the registry server. + required: True + type: str + 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: Login to default registry and create ${XDG_RUNTIME_DIR}/containers/auth.json + containers.podman.podman_login: + username: user + password: 'p4ssw0rd' + +- name: Login to default registry and create ${XDG_RUNTIME_DIR}/containers/auth.json + containers.podman.podman_login: + username: user + password: 'p4ssw0rd' + registry: quay.io + +""" +# noqa: F402 + +import json # noqa: F402 +from ansible.module_utils.basic import AnsibleModule + + +def login(module, executable, registry, authfile, + certdir, tlsverify, username, password): + + command = [executable, 'login'] + changed = False + + if username: + command.extend(['--username', username]) + if password: + command.extend(['--password', password]) + if authfile: + command.extend(['--authfile', authfile]) + if registry: + command.append(registry) + if certdir: + command.extend(['--cert-dir', certdir]) + if tlsverify is not None: + command.extend(['--tls-verify', tlsverify]) + rc, out, err = module.run_command(command) + if rc != 0: + if 'Error: Not logged into' not in err: + module.fail_json(msg="Unable to gather info for %s: %s" % (registry, err)) + else: + # If the command is successful, we managed to login + changed = True + if 'Existing credentials are valid' in out: + changed = False + return changed, out, err + + +def main(): + module = AnsibleModule( + argument_spec=dict( + executable=dict(type='str', default='podman'), + registry=dict(type='str'), + authfile=dict(type='path'), + username=dict(type='str', required=True), + password=dict(type='str', required=True, no_log=True), + certdir=dict(type='path'), + tlsverify=dict(type='bool'), + ), + supports_check_mode=True, + required_together=( + ['username', 'password'], + ), + mutually_exclusive=( + ['certdir', 'tlsverify'], + ), + ) + + registry = module.params['registry'] + authfile = module.params['authfile'] + username = module.params['username'] + password = module.params['password'] + certdir = module.params['certdir'] + tlsverify = module.params['tlsverify'] + executable = module.get_bin_path(module.params['executable'], required=True) + + changed, out, err = login(module, executable, registry, authfile, + certdir, tlsverify, username, password) + + results = { + "changed": changed, + "stdout": out, + "stderr": err, + } + + module.exit_json(**results) + + +if __name__ == '__main__': + main() diff --git a/tests/integration/targets/podman_login/tasks/main.yml b/tests/integration/targets/podman_login/tasks/main.yml new file mode 100644 index 0000000..108cb68 --- /dev/null +++ b/tests/integration/targets/podman_login/tasks/main.yml @@ -0,0 +1,33 @@ +- name: Test podman_login + block: + + - name: Print podman version + command: podman version + + - name: Logout from docker if it exists + command: docker logout + ignore_errors: true + + - name: Login with invalid executable + containers.podman.podman_login: + executable: podman_invalid + register: invalid_executable + ignore_errors: yes + + - name: Check invalid executable results + assert: + that: + - invalid_executable is failed + + - name: Login to registry.fedoraproject.org + containers.podman.podman_login: + username: foo + password: bar + registry: registry.fedoraproject.org + register: login + ignore_errors: yes + + - name: Check login + assert: + that: + - login is not failed