helm_registry_auth module to authenticate in OCI registry (#800)

* new module helm_registry_auth

* Initial integration tests

* final update copyright and integration test before pr

* update link to pr in changelog fragment

* reformat plugins/module_utils/helm.py with black

to fix linters in actions

* attempt to fix unit test

unit test was missing initially

* fix https://pycqa.github.io/isort/ linter

* next attemp to fix unit-test

* remove unused and unsupported helm_args_common

* remove unused imports and fix other linters errors

* another fix for unit test

* fix issue introducied by commit ff02893a12a31f9c44b5c48f9a8bf85057295961

* add binary_path to arg_spec

* return helm_cmd in the output of check mode

remove changlog fragment

* description suggestion from reviewer/maintainer

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>

* description suggestion from reviewer/maintainer

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>

* description suggestion from reviewer/maintainer

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>

* description suggestion from reviewer/maintainer

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>

* description suggestion from reviewer/maintainer

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>

* description suggestion from reviewer/maintainer

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>

* description suggestion from reviewer/maintainer

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>

* description suggestion from reviewer/maintainer

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>

* remove changed from module return

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>

* remove redundant code

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>

* Update plugins/modules/helm_registry_auth.py

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>

* consider support of logout when user is not logged in

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>

* consider support helm < 3.0.0

* Revert "consider support helm < 3.0.0"

This reverts commit f20004d196.

* reintroduce support of helm version less than 3.8.0

reference: https://helm.sh/docs/topics/registries/#enabling-oci-support-prior-to-v380

* revert reintroducing support of helm < 3.8.0

reason: didn't find a quick way to deal with tests

* update documentation with the recent module updates

* Update plugins/modules/helm_registry_auth.py

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>

* add test of logout impendency

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>

* fix linters

* fix intendations in the integration tests

* create tests/integration/targets/helm_registry_auth/aliases

* fix integration test (typo)

* fix integration tests (test wrong cred)

* add stderr when module fail

* another attempt to fix integration test

* fix assertion in integration test to be not affceted by the #830

---------

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>
This commit is contained in:
Yuriy Novostavskiy
2024-12-17 15:39:42 +01:00
committed by GitHub
parent 6609abdd5a
commit aee847431a
20 changed files with 807 additions and 10 deletions

View File

@@ -21,7 +21,7 @@ For more information about communication, see the [Ansible communication guide](
## Requirements
<!--start requires_ansible-->
### Ansible version compatibility
## Ansible version compatibility
This collection has been tested against following Ansible versions: **>=2.15.0**.
@@ -47,28 +47,28 @@ This collection supports Kubernetes versions >= 1.24.
Click on the name of a plugin or module to view that content's documentation:
<!--start collection content-->
#### Connection plugins
### Connection plugins
Name | Description
--- | ---
[kubernetes.core.kubectl](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.kubectl_connection.rst)|Execute tasks in pods running on Kubernetes.
#### K8s filter plugins
### K8s filter plugins
Name | Description
--- | ---
kubernetes.core.k8s_config_resource_name|Generate resource name for the given resource of type ConfigMap, Secret
#### Inventory plugins
### Inventory plugins
Name | Description
--- | ---
[kubernetes.core.k8s](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_inventory.rst)|Kubernetes (K8s) inventory source
#### Lookup plugins
### Lookup plugins
Name | Description
--- | ---
[kubernetes.core.k8s](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_lookup.rst)|Query the K8s API
[kubernetes.core.kustomize](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.kustomize_lookup.rst)|Build a set of kubernetes resources using a 'kustomization.yaml' file.
#### Modules
### Modules
Name | Description
--- | ---
[kubernetes.core.helm](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_module.rst)|Manages Kubernetes packages with the Helm package manager
@@ -76,6 +76,7 @@ Name | Description
[kubernetes.core.helm_plugin](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_plugin_module.rst)|Manage Helm plugins
[kubernetes.core.helm_plugin_info](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_plugin_info_module.rst)|Gather information about Helm plugins
[kubernetes.core.helm_pull](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_pull_module.rst)|download a chart from a repository and (optionally) unpack it in local directory.
[kubernetes.core.helm_registry_auth](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_registry_auth_module.rst)|Helm registry authentication module
[kubernetes.core.helm_repository](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_repository_module.rst)|Manage Helm repositories.
[kubernetes.core.helm_template](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_template_module.rst)|Render chart templates
[kubernetes.core.k8s](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_module.rst)|Manage Kubernetes (K8s) objects

View File

@@ -0,0 +1,332 @@
.. _kubernetes.core.helm_registry_auth_module:
**********************************
kubernetes.core.helm_registry_auth
**********************************
**Helm registry authentication module**
Version added: 5.1.0
.. contents::
:local:
:depth: 1
Synopsis
--------
- Helm registry authentication module allows you to login ``helm registry login`` and logout ``helm registry logout`` from a Helm registry.
Requirements
------------
The below requirements are needed on the host that executes this module.
- helm (https://github.com/helm/helm/releases) => 3.8.0
Parameters
----------
.. raw:: html
<table border=0 cellpadding=0 class="documentation-table">
<tr>
<th colspan="1">Parameter</th>
<th>Choices/<font color="blue">Defaults</font></th>
<th width="100%">Comments</th>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>binary_path</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">path</span>
</div>
</td>
<td>
</td>
<td>
<div>The path of a helm binary to use.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>ca_file</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">path</span>
</div>
</td>
<td>
</td>
<td>
<div>Path to the CA certificate SSL file for verify registry server certificate.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>cert_file</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">path</span>
</div>
</td>
<td>
</td>
<td>
<div>Path to the client certificate SSL file for identify registry client using this certificate file.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>host</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
/ <span style="color: red">required</span>
</div>
</td>
<td>
</td>
<td>
<div>Provide a URL for accessing the registry.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: registry_url</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>insecure</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">boolean</span>
</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>Allow connections to SSL sites without certs.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>key_file</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">path</span>
</div>
</td>
<td>
</td>
<td>
<div>Path to the client key SSL file for identify registry client using this key file.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>password</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
</td>
<td>
</td>
<td>
<div>Password for the registry.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: repo_password</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>state</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li><div style="color: blue"><b>present</b>&nbsp;&larr;</div></li>
<li>absent</li>
</ul>
</td>
<td>
<div>Desired state of the registry.</div>
<div>If set to V(present) attempt to log in to the remote registry server using the URL specified in O(host).</div>
<div>If set to V(absent) attempt to log out from the remote registry server using the URL specified in O(host).</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>username</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
</td>
<td>
</td>
<td>
<div>Username for the registry.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: repo_username</div>
</td>
</tr>
</table>
<br/>
Examples
--------
.. code-block:: yaml
- name: Login to remote registry
kubernetes.core.helm_registry_auth:
username: admin
password: "sample_password"
host: localhost:5000
- name: Logout from remote registry
kubernetes.core.helm_registry_auth:
state: absent
host: localhost:5000
Return Values
-------------
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
.. raw:: html
<table border=0 cellpadding=0 class="documentation-table">
<tr>
<th colspan="1">Key</th>
<th>Returned</th>
<th width="100%">Description</th>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>command</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
</td>
<td>always</td>
<td>
<div>Full <code>helm</code> command executed</div>
<br/>
<div style="font-size: smaller"><b>Sample:</b></div>
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">/usr/local/bin/helm registry login oci-registry.domain.example --username=admin --password-stdin --insecure</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>failed</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">boolean</span>
</div>
</td>
<td>always</td>
<td>
<div>Indicate if the <code>helm</code> command failed</div>
<br/>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>stderr</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
</td>
<td>always</td>
<td>
<div>Full <code>helm</code> command stderr, in case you want to display it or examine the event log. Please be note that helm binnary may print messages to stderr even if the command is successful.</div>
<br/>
<div style="font-size: smaller"><b>Sample:</b></div>
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">Login Succeeded\n</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>stderr_lines</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">list</span>
</div>
</td>
<td>always</td>
<td>
<div>Full <code>helm</code> command stderr, in case you want to display it or examine the event log</div>
<br/>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>stdout</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
</td>
<td>always</td>
<td>
<div>Full <code>helm</code> command stdout, in case you want to display it or examine the event log</div>
<br/>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>stout_lines</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">list</span>
</div>
</td>
<td>always</td>
<td>
<div>Full <code>helm</code> command stdout, in case you want to display it or examine the event log</div>
<br/>
</td>
</tr>
</table>
<br/><br/>
Status
------
Authors
~~~~~~~
- Yuriy Novostavskiy (@yurnov)

View File

@@ -159,11 +159,13 @@ class AnsibleHelmModule(object):
self.helm_env = self._prepare_helm_environment()
return self.helm_env
def run_helm_command(self, command, fails_on_error=True):
def run_helm_command(self, command, fails_on_error=True, data=None):
if not HAS_YAML:
self.fail_json(msg=missing_required_lib("PyYAML"), exception=YAML_IMP_ERR)
rc, out, err = self.run_command(command, environ_update=self.env_update)
rc, out, err = self.run_command(
command, environ_update=self.env_update, data=data
)
if fails_on_error and rc != 0:
self.fail_json(
msg="Failure when executing Helm command. Exited {0}.\nstdout: {1}\nstderr: {2}".format(

View File

@@ -0,0 +1,238 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: © Ericsson AB 2024
# 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: helm_registry_auth
short_description: Helm registry authentication module
version_added: 5.1.0
author:
- Yuriy Novostavskiy (@yurnov)
requirements:
- "helm (https://github.com/helm/helm/releases) => 3.8.0"
description:
- Helm registry authentication module allows you to login C(helm registry login) and logout C(helm registry logout) from a Helm registry.
options:
state:
description:
- Desired state of the registry.
- If set to V(present) attempt to log in to the remote registry server using the URL specified in O(host).
- If set to V(absent) attempt to log out from the remote registry server using the URL specified in O(host).
required: false
default: present
choices: ['present', 'absent']
type: str
host:
description:
- Provide a URL for accessing the registry.
required: true
aliases: [ registry_url ]
type: str
insecure:
description:
- Allow connections to SSL sites without certs.
required: false
default: false
type: bool
username:
description:
- Username for the registry.
required: false
type: str
aliases: [ repo_username ]
password:
description:
- Password for the registry.
required: false
type: str
aliases: [ repo_password ]
key_file:
description:
- Path to the client key SSL file for identify registry client using this key file.
required: false
type: path
cert_file:
description:
- Path to the client certificate SSL file for identify registry client using this certificate file.
required: false
type: path
ca_file:
description:
- Path to the CA certificate SSL file for verify registry server certificate.
required: false
type: path
binary_path:
description:
- The path of a helm binary to use.
required: false
type: path
"""
EXAMPLES = r"""
- name: Login to remote registry
kubernetes.core.helm_registry_auth:
username: admin
password: "sample_password"
host: localhost:5000
- name: Logout from remote registry
kubernetes.core.helm_registry_auth:
state: absent
host: localhost:5000
"""
RETURN = r"""
stdout:
type: str
description: Full C(helm) command stdout, in case you want to display it or examine the event log
returned: always
stout_lines:
type: list
description: Full C(helm) command stdout, in case you want to display it or examine the event log
returned: always
stderr:
type: str
description: >-
Full C(helm) command stderr, in case you want to display it or examine the event log.
Please be note that helm binnary may print messages to stderr even if the command is successful.
returned: always
sample: 'Login Succeeded\n'
stderr_lines:
type: list
description: Full C(helm) command stderr, in case you want to display it or examine the event log
returned: always
command:
type: str
description: Full C(helm) command executed
returned: always
sample: '/usr/local/bin/helm registry login oci-registry.domain.example --username=admin --password-stdin --insecure'
failed:
type: bool
description: Indicate if the C(helm) command failed
returned: always
sample: false
"""
from ansible_collections.kubernetes.core.plugins.module_utils.helm import (
AnsibleHelmModule,
)
def arg_spec():
return dict(
binary_path=dict(type="path", required=False),
host=dict(type="str", aliases=["registry_url"], required=True),
state=dict(default="present", choices=["present", "absent"], required=False),
insecure=dict(type="bool", default=False, required=False),
username=dict(type="str", aliases=["repo_username"], required=False),
password=dict(
type="str", aliases=["repo_password"], no_log=True, required=False
),
key_file=dict(type="path", required=False),
cert_file=dict(type="path", required=False),
ca_file=dict(type="path", required=False),
)
def login(
command,
host,
insecure,
username,
password,
key_file,
cert_file,
ca_file,
):
login_command = command + " registry login " + host
if username is not None and password is not None:
login_command += " --username=" + username + " --password-stdin"
if insecure:
login_command += " --insecure"
if key_file is not None:
login_command += " --key-file=" + key_file
if cert_file is not None:
login_command += " --cert-file=" + cert_file
if ca_file is not None:
login_command += " --ca-file=" + ca_file
return login_command
def logout(command, host):
return command + " registry logout " + host
def main():
global module
module = AnsibleHelmModule(
argument_spec=arg_spec(),
required_together=[["username", "password"]],
supports_check_mode=True,
)
changed = False
host = module.params.get("host")
state = module.params.get("state")
insecure = module.params.get("insecure")
username = module.params.get("username")
password = module.params.get("password")
key_file = module.params.get("key_file")
cert_file = module.params.get("cert_file")
ca_file = module.params.get("ca_file")
helm_cmd = module.get_helm_binary()
if state == "absent":
helm_cmd = logout(helm_cmd, host)
changed = True
elif state == "present":
helm_cmd = login(
helm_cmd, host, insecure, username, password, key_file, cert_file, ca_file
)
changed = True
if module.check_mode:
module.exit_json(changed=changed, command=helm_cmd)
rc, out, err = module.run_helm_command(
helm_cmd, data=password, fails_on_error=False
)
if rc != 0:
if state == "absent" and "Error: not logged in" in err:
changed = False
else:
module.fail_json(
msg="Failure when executing Helm command. Exited {0}.\nstdout: {1}\nstderr: {2}".format(
rc, out, err
),
stderr=err,
command=helm_cmd,
)
module.exit_json(changed=changed, stdout=out, stderr=err, command=helm_cmd)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,2 @@
time=16
helm_registry_auth

View File

@@ -0,0 +1,9 @@
---
# Username and password for the registry
# ../files/registry.password contains username and hashed password
username: testuser
password: testpassword
wrong_password: 'WrongPassword'
registry_name: oci_registry
registry_port: 5000
test_chart: https://github.com/grafana/helm-charts/releases/download/k8s-monitoring-1.6.8/k8s-monitoring-1.6.8.tgz

View File

@@ -0,0 +1 @@
testuser:$2y$05$PmdUjSCJYdRUZlsYy8QGWuJDiwuHtWXa28YrELlN5haeHkZ1seZZG

View File

@@ -0,0 +1,3 @@
---
dependencies:
- install_helm

View File

@@ -0,0 +1,7 @@
---
- name: Test helm_registry_auth module
hosts: localhost
connection: local
gather_facts: true
roles:
- helm_registry_auth

View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -eux
export ANSIBLE_CALLBACKS_ENABLED=profile_tasks
export ANSIBLE_ROLES_PATH=../
ansible-playbook playbook.yaml "$@"

View File

@@ -0,0 +1,178 @@
---
- name: Run module test
# using a shell and command module to run the test as test can be non-idempotent
# and it allow to not install any additional dependencies
block:
- name: Ensure that helm is installed
ansible.builtin.shell: helm version --client --short | grep v3
register: _helm_version
failed_when: _helm_version.rc != 0
- name: Ensure that Docker demon is running
ansible.builtin.command: "docker info"
register: _docker_info
failed_when: _docker_info.rc != 0
- name: Create a tmpfile htpasswd directory
ansible.builtin.tempfile:
state: directory
suffix: .httppasswd
register: _tmpfile
- name: Copy htpasswd to the tmpfile directory
ansible.builtin.copy:
src: registry.password
dest: "{{ _tmpfile.path }}/registry.password"
- name: Setup the registry
ansible.builtin.command: >-
docker run -d --rm
-p {{ registry_port }}:5000
--name "{{ registry_name }}"
-v "{{ _tmpfile.path }}:/auth"
-e "REGISTRY_AUTH=htpasswd"
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm"
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/registry.password
registry:2
register: _setup_registry
failed_when: _setup_registry.rc != 0
- name: Ensure that the registry is running and rechable
ansible.builtin.wait_for:
host: localhost
port: "{{ registry_port }}"
- name: Test the registry with correct credentials to ensure that the registry is running
ansible.builtin.shell: >-
echo {{ password | quote }} | helm registry login localhost:{{ registry_port }}
-u {{ username }} --password-stdin
register: _login_correct
failed_when: _login_correct.rc != 0
- name: Clean up credentials to run test on clean environment
ansible.builtin.shell: >-
helm registry logout localhost:{{ registry_port }}
register: _logout
failed_when: _logout.rc != 0
- name: Create directory for helm chart
ansible.builtin.tempfile:
state: directory
suffix: ".helm"
register: _destination
- name: Pull test helm chart
ansible.builtin.uri:
url: "{{ test_chart }}"
dest: "{{ _destination.path }}/k8s-monitoring-1.6.8.tgz"
return_content: no
status_code: 200
- name: Test module helm_registry_auth with correct credentials
helm_registry_auth:
username: "{{ username }}"
password: "{{ password }}"
host: localhost:{{ registry_port }}
state: present
register: _helm_registry_auth_correct
- name: Assert that the registry is logged in
# Helm binary prints the message to stderr, refence: https://github.com/helm/helm/issues/13464
assert:
that:
- "'Login Succeeded' in _helm_registry_auth_correct.stderr"
- "'{{ password }}' not in _helm_registry_auth_correct.command"
- "'{{ password }}' not in _helm_registry_auth_correct.stdout"
- "'{{ password }}' not in _helm_registry_auth_correct.stderr"
- name: Ensure that push to the registry is working
ansible.builtin.shell: >-
helm push "{{ _destination.path }}/k8s-monitoring-1.6.8.tgz" oci://localhost:{{ registry_port }}/test/
register: _save_chart
failed_when: _save_chart.rc != 0
- name: Assert that the chart is saved
# Helm binary prints the message to stderr, refence: https://github.com/helm/helm/issues/13464
assert:
that: "'Pushed: localhost:{{ registry_port }}/test/k8s-monitoring' in _save_chart.stderr"
- name: Test logout
helm_registry_auth:
host: localhost:{{ registry_port }}
state: absent
register: _helm_registry_auth_logout
- name: Assert logout
# Helm binary prints the message to stderr
assert:
that: "'Removing login credentials' in _helm_registry_auth_logout.stderr"
- name: Test logout idempotency
helm_registry_auth:
host: localhost:{{ registry_port }}
state: absent
register: _helm_registry_auth_logout_idempotency
- name: Assert logout operation did not report change
ansible.builtin.assert:
that: _helm_registry_auth_logout_idempotency is not changed
- name: Ensure that not able to push to the registry
ansible.builtin.shell: >-
helm push "{{ _destination.path }}/k8s-monitoring-1.6.8.tgz" oci://localhost:{{ registry_port }}/test/
register: _save_chart
failed_when: _save_chart.rc == 0
- name: Read content of ~/.config/helm/registry/config.json
ansible.builtin.slurp:
src: ~/.config/helm/registry/config.json
register: _config_json
- name: Assert that auth data is remove and the chart is not saved
# Helm binary prints the message to stderr
ansible.builtin.assert:
that:
- "'push access denied' in _save_chart.stderr"
- "'authorization failed' in _save_chart.stderr"
- "_save_chart.rc != 0"
- "'localhost:{{ registry_port }}' not in _config_json.content | b64decode"
- name: Test module helm_registry_auth with wrong credentials
helm_registry_auth:
username: "{{ username }}"
password: "{{ wrong_password }}"
host: localhost:{{ registry_port }}
state: present
register: _helm_registry_auth_wrong
ignore_errors: true
- name: Read content of ~/.config/helm/registry/config.json
ansible.builtin.slurp:
src: ~/.config/helm/registry/config.json
register: _config_json
- name: Assert that the registry is not logged in and auth data is not saved
ansible.builtin.assert:
that:
- "'401 Unauthorized' in _helm_registry_auth_wrong.stderr"
- "'{{ wrong_password }}' not in _helm_registry_auth_correct.command"
- "'{{ wrong_password }}' not in _helm_registry_auth_correct.stdout"
- "'{{ wrong_password }}' not in _helm_registry_auth_correct.stderr"
- "'localhost:{{ registry_port }}' not in _config_json.content | b64decode"
# Clean up
always:
- name: Stop and remove the registry
ansible.builtin.command: docker stop {{ registry_name }}
ignore_errors: true
- name: Remove the tmpfile
ansible.builtin.file:
state: absent
path: "{{ item }}"
force: true
loop:
- "{{ _tmpfile.path }}"
- "{{ _destination.path }}"
ignore_errors: true

View File

@@ -25,4 +25,6 @@ plugins/modules/k8s_service.py validate-modules:return-syntax-error
plugins/modules/k8s_taint.py validate-modules:return-syntax-error
tests/integration/targets/k8s_delete/files/deployments.yaml yamllint!skip
tests/integration/targets/helm_diff/files/test-chart-reuse-values/templates/configmap.yaml yamllint!skip
tests/integration/targets/helm_registry_auth/tasks/main.yaml yamllint!skip
tests/integration/targets/helm_diff/files/test-chart-deployment-time/templates/configmap.yaml yamllint!skip

View File

@@ -26,4 +26,5 @@ plugins/modules/k8s_scale.py validate-modules:return-syntax-error
plugins/modules/k8s_service.py validate-modules:return-syntax-error
plugins/modules/k8s_taint.py validate-modules:return-syntax-error
tests/integration/targets/helm_diff/files/test-chart-reuse-values/templates/configmap.yaml yamllint!skip
tests/integration/targets/helm_registry_auth/tasks/main.yaml yamllint!skip
tests/integration/targets/helm_diff/files/test-chart-deployment-time/templates/configmap.yaml yamllint!skip

View File

@@ -29,4 +29,5 @@ plugins/modules/k8s_scale.py validate-modules:return-syntax-error
plugins/modules/k8s_service.py validate-modules:return-syntax-error
plugins/modules/k8s_taint.py validate-modules:return-syntax-error
tests/integration/targets/helm_diff/files/test-chart-reuse-values/templates/configmap.yaml yamllint!skip
tests/integration/targets/helm_registry_auth/tasks/main.yaml yamllint!skip
tests/integration/targets/helm_diff/files/test-chart-deployment-time/templates/configmap.yaml yamllint!skip

View File

@@ -29,4 +29,5 @@ plugins/modules/k8s_scale.py validate-modules:return-syntax-error
plugins/modules/k8s_service.py validate-modules:return-syntax-error
plugins/modules/k8s_taint.py validate-modules:return-syntax-error
tests/integration/targets/helm_diff/files/test-chart-reuse-values/templates/configmap.yaml yamllint!skip
tests/integration/targets/helm_registry_auth/tasks/main.yaml yamllint!skip
tests/integration/targets/helm_diff/files/test-chart-deployment-time/templates/configmap.yaml yamllint!skip

View File

@@ -26,4 +26,5 @@ plugins/modules/k8s_scale.py validate-modules:return-syntax-error
plugins/modules/k8s_service.py validate-modules:return-syntax-error
plugins/modules/k8s_taint.py validate-modules:return-syntax-error
tests/integration/targets/helm_diff/files/test-chart-reuse-values/templates/configmap.yaml yamllint!skip
tests/integration/targets/helm_registry_auth/tasks/main.yaml yamllint!skip
tests/integration/targets/helm_diff/files/test-chart-deployment-time/templates/configmap.yaml yamllint!skip

View File

@@ -26,4 +26,5 @@ plugins/modules/k8s_scale.py validate-modules:return-syntax-error
plugins/modules/k8s_service.py validate-modules:return-syntax-error
plugins/modules/k8s_taint.py validate-modules:return-syntax-error
tests/integration/targets/helm_diff/files/test-chart-reuse-values/templates/configmap.yaml yamllint!skip
tests/integration/targets/helm_registry_auth/tasks/main.yaml yamllint!skip
tests/integration/targets/helm_diff/files/test-chart-deployment-time/templates/configmap.yaml yamllint!skip

View File

@@ -242,7 +242,7 @@ def test_module_run_helm_command(_ansible_helm_module):
assert (rc, out, err) == (0, output, error)
_ansible_helm_module.run_command.assert_called_once_with(
command, environ_update=env_update
command, environ_update=env_update, data=None
)

View File

@@ -51,7 +51,7 @@ class TestDependencyUpdateWithoutChartRepoUrlOption(unittest.TestCase):
with self.assertRaises(AnsibleExitJson) as result:
helm_template.main()
mock_run_command.assert_called_once_with(
"/usr/bin/helm template /tmp/path", environ_update={}
"/usr/bin/helm template /tmp/path", environ_update={}, data=None
)
assert result.exception.args[0]["command"] == "/usr/bin/helm template /tmp/path"
@@ -74,6 +74,7 @@ class TestDependencyUpdateWithoutChartRepoUrlOption(unittest.TestCase):
mock_run_command.assert_called_once_with(
"/usr/bin/helm template test --repo=https://charts.com/test",
environ_update={},
data=None,
)
assert (
result.exception.args[0]["command"]
@@ -95,6 +96,7 @@ class TestDependencyUpdateWithoutChartRepoUrlOption(unittest.TestCase):
mock_run_command.assert_called_once_with(
"/usr/bin/helm template https://charts/example.tgz --dependency-update",
environ_update={},
data=None,
)
assert (
result.exception.args[0]["command"]

View File

@@ -88,6 +88,7 @@ class TestDependencyUpdateWithoutChartRepoUrlOption(unittest.TestCase):
mock_run_command.assert_called_once_with(
"/usr/bin/helm upgrade -i --reset-values test '/tmp/path'",
environ_update={"HELM_NAMESPACE": "test"},
data=None,
)
assert (
result.exception.args[0]["command"]
@@ -118,6 +119,7 @@ class TestDependencyUpdateWithoutChartRepoUrlOption(unittest.TestCase):
mock_run_command.assert_called_once_with(
"/usr/bin/helm upgrade -i --reset-values test '/tmp/path'",
environ_update={"HELM_NAMESPACE": "test"},
data=None,
)
assert (
result.exception.args[0]["command"]
@@ -147,6 +149,7 @@ class TestDependencyUpdateWithoutChartRepoUrlOption(unittest.TestCase):
call(
"/usr/bin/helm upgrade -i --reset-values test '/tmp/path'",
environ_update={"HELM_NAMESPACE": "test"},
data=None,
)
]
)
@@ -181,6 +184,7 @@ class TestDependencyUpdateWithoutChartRepoUrlOption(unittest.TestCase):
call(
"/usr/bin/helm upgrade -i --reset-values test '/tmp/path'",
environ_update={"HELM_NAMESPACE": "test"},
data=None,
)
]
)
@@ -251,6 +255,7 @@ class TestDependencyUpdateWithChartRepoUrlOption(unittest.TestCase):
mock_run_command.assert_called_once_with(
"/usr/bin/helm --repo=http://repo.example/charts upgrade -i --reset-values test 'chart1'",
environ_update={"HELM_NAMESPACE": "test"},
data=None,
)
assert (
result.exception.args[0]["command"]
@@ -280,6 +285,7 @@ class TestDependencyUpdateWithChartRepoUrlOption(unittest.TestCase):
mock_run_command.assert_called_once_with(
"/usr/bin/helm --repo=http://repo.example/charts upgrade -i --reset-values test 'chart1'",
environ_update={"HELM_NAMESPACE": "test"},
data=None,
)
assert (
result.exception.args[0]["command"]
@@ -338,6 +344,7 @@ class TestDependencyUpdateWithChartRepoUrlOption(unittest.TestCase):
mock_run_command.assert_called_once_with(
"/usr/bin/helm --repo=http://repo.example/charts install --dependency-update --replace test 'chart1'",
environ_update={"HELM_NAMESPACE": "test"},
data=None,
)
assert (
result.exception.args[0]["command"]
@@ -405,6 +412,7 @@ class TestDependencyUpdateWithChartRefIsUrl(unittest.TestCase):
mock_run_command.assert_called_once_with(
"/usr/bin/helm upgrade -i --reset-values test 'http://repo.example/charts/application.tgz'",
environ_update={"HELM_NAMESPACE": "test"},
data=None,
)
assert (
result.exception.args[0]["command"]
@@ -433,6 +441,7 @@ class TestDependencyUpdateWithChartRefIsUrl(unittest.TestCase):
mock_run_command.assert_called_once_with(
"/usr/bin/helm upgrade -i --reset-values test 'http://repo.example/charts/application.tgz'",
environ_update={"HELM_NAMESPACE": "test"},
data=None,
)
assert (
result.exception.args[0]["command"]
@@ -489,6 +498,7 @@ class TestDependencyUpdateWithChartRefIsUrl(unittest.TestCase):
mock_run_command.assert_called_once_with(
"/usr/bin/helm install --dependency-update --replace test 'http://repo.example/charts/application.tgz'",
environ_update={"HELM_NAMESPACE": "test"},
data=None,
)
assert (
result.exception.args[0]["command"]