mirror of
https://github.com/containers/ansible-podman-collections.git
synced 2026-02-03 23:01:48 +00:00
234 lines
7 KiB
Python
234 lines
7 KiB
Python
#!/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)"
|
|
- "Clemens Lange (@clelange)"
|
|
- "Michael Fox (@spmfox)"
|
|
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.
|
|
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.
|
|
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
|
|
secret:
|
|
description:
|
|
- Name of an existing C(podman) secret to use for authentication
|
|
to target registry
|
|
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 quay.io and create ${XDG_RUNTIME_DIR}/containers/auth.json
|
|
containers.podman.podman_login:
|
|
username: user
|
|
password: 'p4ssw0rd'
|
|
registry: quay.io
|
|
|
|
- name: Login to quay.io using existing secret called password
|
|
containers.podman.podman_login:
|
|
username: user
|
|
secret: password
|
|
registry: quay.io
|
|
|
|
"""
|
|
# noqa: F402
|
|
|
|
import hashlib
|
|
import os
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
from ansible_collections.containers.podman.plugins.module_utils.podman.common import (
|
|
LooseVersion,
|
|
)
|
|
from ansible_collections.containers.podman.plugins.module_utils.podman.common import (
|
|
get_podman_version,
|
|
)
|
|
|
|
|
|
def login(
|
|
module,
|
|
executable,
|
|
registry,
|
|
authfile,
|
|
certdir,
|
|
tlsverify,
|
|
username,
|
|
password,
|
|
secret,
|
|
):
|
|
|
|
command = [executable, "login"]
|
|
changed = False
|
|
|
|
if username:
|
|
command.extend(["--username", username])
|
|
if password:
|
|
command.extend(["--password", password])
|
|
if secret:
|
|
command.extend(["--secret", secret])
|
|
if authfile:
|
|
command.extend(["--authfile", authfile])
|
|
authfile = os.path.expandvars(authfile)
|
|
else:
|
|
authfile = os.getenv("XDG_RUNTIME_DIR", "") + "/containers/auth.json"
|
|
if registry:
|
|
command.append(registry)
|
|
if certdir:
|
|
command.extend(["--cert-dir", certdir])
|
|
if tlsverify is not None:
|
|
if tlsverify:
|
|
command.append("--tls-verify")
|
|
else:
|
|
command.append("--tls-verify=False")
|
|
# Use a checksum to check if the auth JSON has changed
|
|
checksum = None
|
|
docker_authfile = os.path.expandvars("$HOME/.docker/config.json")
|
|
# podman falls back to ~/.docker/config.json if the default authfile doesn't exist
|
|
check_file = authfile if os.path.exists(authfile) else docker_authfile
|
|
if os.path.exists(check_file):
|
|
content = open(check_file, "rb").read()
|
|
checksum = hashlib.sha256(content).hexdigest()
|
|
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
|
|
# If we have managed to calculate a checksum before, check if it has changed
|
|
# due to the login
|
|
if checksum:
|
|
content = open(check_file, "rb").read()
|
|
new_checksum = hashlib.sha256(content).hexdigest()
|
|
if new_checksum == checksum:
|
|
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"),
|
|
password=dict(type="str", no_log=True),
|
|
certdir=dict(type="path"),
|
|
tlsverify=dict(type="bool"),
|
|
secret=dict(type="str", no_log=False),
|
|
),
|
|
supports_check_mode=False,
|
|
required_by={
|
|
"password": "username",
|
|
},
|
|
mutually_exclusive=[
|
|
["password", "secret"],
|
|
],
|
|
)
|
|
|
|
registry = module.params["registry"]
|
|
authfile = module.params["authfile"]
|
|
username = module.params["username"]
|
|
password = module.params["password"]
|
|
certdir = module.params["certdir"]
|
|
tlsverify = module.params["tlsverify"]
|
|
secret = module.params["secret"]
|
|
executable = module.get_bin_path(module.params["executable"], required=True)
|
|
|
|
podman_version = get_podman_version(module, fail=False)
|
|
|
|
if (
|
|
(podman_version is not None)
|
|
and (LooseVersion(podman_version) < LooseVersion("4.7.0"))
|
|
and secret
|
|
):
|
|
module.fail_json(msg="secret option may not be used with podman < 4.7.0")
|
|
|
|
if username and ((not password) and (not secret)):
|
|
module.fail_json(msg="Must pass either password or secret with username")
|
|
|
|
changed, out, err = login(
|
|
module,
|
|
executable,
|
|
registry,
|
|
authfile,
|
|
certdir,
|
|
tlsverify,
|
|
username,
|
|
password,
|
|
secret,
|
|
)
|
|
|
|
results = {
|
|
"changed": changed,
|
|
"stdout": out,
|
|
"stderr": err,
|
|
}
|
|
|
|
module.exit_json(**results)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|