mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-05-12 12:32:05 +00:00
Compare commits
81 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a2aa079829 | ||
|
|
ca050aa3f6 | ||
|
|
84249fc4f1 | ||
|
|
229575fe8f | ||
|
|
386f601ae0 | ||
|
|
3f2841be95 | ||
|
|
91f6827e23 | ||
|
|
4136d6f606 | ||
|
|
12847a1555 | ||
|
|
8ddb19aade | ||
|
|
0f6b4c873a | ||
|
|
acc168e61f | ||
|
|
49f54edad2 | ||
|
|
c6519926a6 | ||
|
|
0ff5c952b8 | ||
|
|
477a9b0b9e | ||
|
|
eac3c0a88b | ||
|
|
e00d4fc9d7 | ||
|
|
623b8b2716 | ||
|
|
906c50f2c6 | ||
|
|
b16bb15d34 | ||
|
|
588f60adc8 | ||
|
|
deac7719c2 | ||
|
|
cb4b792038 | ||
|
|
6215ac763b | ||
|
|
d5599f1964 | ||
|
|
90134ec3e0 | ||
|
|
dcbe52e722 | ||
|
|
1e711d4da8 | ||
|
|
4b2dc4f974 | ||
|
|
eb0aeeb318 | ||
|
|
f3d3696093 | ||
|
|
e3da2f28fd | ||
|
|
bb599542e8 | ||
|
|
6560fb1c53 | ||
|
|
20084d119e | ||
|
|
c47343d7b6 | ||
|
|
c213b51741 | ||
|
|
60b53b9dc9 | ||
|
|
d531368d64 | ||
|
|
c3bf5cc47f | ||
|
|
349534b85b | ||
|
|
92e3f98a20 | ||
|
|
d2dcb9e55f | ||
|
|
0eff03dd19 | ||
|
|
81fb8662da | ||
|
|
f74ee14d71 | ||
|
|
6f75d86954 | ||
|
|
c93a7e2459 | ||
|
|
2d68a37a52 | ||
|
|
c5f5398e9e | ||
|
|
05aea7727d | ||
|
|
d3f6dd186c | ||
|
|
8cee9fddbe | ||
|
|
05a942e41e | ||
|
|
fcd47ca995 | ||
|
|
f1729ce186 | ||
|
|
c37dc5b566 | ||
|
|
410855cd36 | ||
|
|
e1f52ddbee | ||
|
|
5d038db848 | ||
|
|
9d3195641e | ||
|
|
dac1448b9c | ||
|
|
4bdff5d672 | ||
|
|
19a71c82ba | ||
|
|
c73f3e3f75 | ||
|
|
2cdcc195e6 | ||
|
|
e98605eb16 | ||
|
|
e13a7fd0c6 | ||
|
|
2098dfea5e | ||
|
|
10a9b9e811 | ||
|
|
67868442f3 | ||
|
|
5eefa9c308 | ||
|
|
4ed9105797 | ||
|
|
46f8e4adfb | ||
|
|
5761205513 | ||
|
|
7b0190f8d5 | ||
|
|
c47e691101 | ||
|
|
8ae6469696 | ||
|
|
1174fee5c9 | ||
|
|
f22ffcab18 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -17,7 +17,6 @@ tests/integration/cloud-config-*
|
|||||||
|
|
||||||
# Helm charts
|
# Helm charts
|
||||||
tests/integration/*-chart-*.tgz
|
tests/integration/*-chart-*.tgz
|
||||||
tests/integration/targets/*/*.tgz
|
|
||||||
|
|
||||||
# ansible-test generated file
|
# ansible-test generated file
|
||||||
tests/integration/inventory
|
tests/integration/inventory
|
||||||
|
|||||||
@@ -4,44 +4,17 @@ Kubernetes Collection Release Notes
|
|||||||
|
|
||||||
.. contents:: Topics
|
.. contents:: Topics
|
||||||
|
|
||||||
v6.4.0
|
v5.4.2
|
||||||
======
|
======
|
||||||
|
|
||||||
Release Summary
|
Release Summary
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
This release adds Helm v4 compatibility across the Helm modules and improves ``k8s_drain`` with check mode. When you explicitly allow evicting unmanaged pods, pods with local storage, or pods managed by a ``DaemonSet``, those cases are reported as informational output instead of module warnings.
|
This release includes bugfixes such as replacing the passing of ``warnings`` to ``exit_json`` with ``AnsibleModule.warn`` as well as a security update for selectively redacting sensitive information from kubeconfig.
|
||||||
|
|
||||||
Minor Changes
|
Minor Changes
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
- helm_info - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
|
|
||||||
- helm_plugin - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
|
|
||||||
- helm_plugin_info - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
|
|
||||||
- helm_pull - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
|
|
||||||
- helm_registry_auth - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
|
|
||||||
- helm_registry_auth - add new option plain_http to allow insecure http connection when running ``helm registry login`` (https://github.com/ansible-collections/kubernetes.core/pull/1090).
|
|
||||||
- helm_repository - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
|
|
||||||
- k8s_drain - Add support for ``check_mode`` (https://github.com/ansible-collections/kubernetes.core/pull/1086).
|
|
||||||
- k8s_drain - Convert module warnings into informational displays when users explicitly request the deletion of unmanaged pods, pods with local storage, or those managed by a `DaemonSet` (https://github.com/ansible-collections/kubernetes.core/issues/1037).
|
|
||||||
|
|
||||||
Bugfixes
|
|
||||||
--------
|
|
||||||
|
|
||||||
- Helm - Allow taking ownership of existing Kubernetes resources on the first installation of a Helm release. Previously, the ``take_ownership`` parameter was always disabled during the initial install, preventing resource adoption (https://github.com/ansible-collections/kubernetes.core/pull/1034).
|
|
||||||
|
|
||||||
v6.3.0
|
|
||||||
======
|
|
||||||
|
|
||||||
Release Summary
|
|
||||||
---------------
|
|
||||||
|
|
||||||
This release includes bugfixes such as implementing idempotency for the ``helm_pull`` module as well as a security update for selectively redacting sensitive information from kubeconfig.
|
|
||||||
|
|
||||||
Minor Changes
|
|
||||||
-------------
|
|
||||||
|
|
||||||
- Remove deprecated import from ``ansible.module_utils._text`` (https://github.com/ansible-collections/kubernetes.core/pull/1053).
|
|
||||||
- helm - add ``release_values`` key to ``status`` return value that can be accessed using Jinja2 dot notation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
|
- helm - add ``release_values`` key to ``status`` return value that can be accessed using Jinja2 dot notation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
|
||||||
- helm_info - add ``release_values`` key to ``status`` return value that can be accessed using Jinja2 dot notation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
|
- helm_info - add ``release_values`` key to ``status`` return value that can be accessed using Jinja2 dot notation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
|
||||||
|
|
||||||
@@ -60,64 +33,12 @@ Bugfixes
|
|||||||
--------
|
--------
|
||||||
|
|
||||||
- Add idempotency for ``helm_pull`` module (https://github.com/ansible-collections/kubernetes.core/pull/1055).
|
- Add idempotency for ``helm_pull`` module (https://github.com/ansible-collections/kubernetes.core/pull/1055).
|
||||||
- Fixed a bug where setting ``K8S_AUTH_VERIFY_SSL=true`` (or any string value) caused the value to be treated as a separate ``kubectl`` command argument. (https://github.com/ansible-collections/kubernetes.core/pull/1049).
|
- Fixed a bug where setting ``K8S_AUTH_VERIFY_SSL=true`` (or any string value) caused the value to be treated as a separate ``kubectl`` command argument (https://github.com/ansible-collections/kubernetes.core/pull/1049).
|
||||||
- Limit supported versions of Helm to <4.0.0 (https://github.com/ansible-collections/kubernetes.core/pull/1039).
|
- Limit supported versions of Helm to <4.0.0 (https://github.com/ansible-collections/kubernetes.core/pull/1039).
|
||||||
- Replace passing ``warnings`` to ``exit_json`` with ``AnsibleModule.warn`` in the ``k8s_drain``, ``k8s_rollback.py`` and ``k8s_scale.py`` modules as it deprecated in ``ansible-core>=2.19.0`` and will be removed in ``ansible-core>=2.23.0`` (https://github.com/ansible-collections/kubernetes.core/pull/1033).
|
- Replace passing ``warnings`` to ``exit_json`` with ``AnsibleModule.warn`` in the ``k8s_drain``, ``k8s_rollback.py`` and ``k8s_scale.py`` modules as it deprecated in ``ansible-core>=2.19.0`` and will be removed in ``ansible-core>=2.23.0`` (https://github.com/ansible-collections/kubernetes.core/pull/1033).
|
||||||
- k8s - Fix return block from the module documentation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
|
- k8s - Fix return block from the module documentation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
|
||||||
- meta - Add ``k8s_cluster_info``, ``k8s_json_patch`` and ``k8s_rollback`` to k8s action group (https://github.com/ansible-collections/kubernetes.core/pull/992).
|
- meta - Add ``k8s_cluster_info``, ``k8s_json_patch`` and ``k8s_rollback`` to k8s action group (https://github.com/ansible-collections/kubernetes.core/pull/992).
|
||||||
|
|
||||||
v6.2.0
|
|
||||||
======
|
|
||||||
|
|
||||||
Release Summary
|
|
||||||
---------------
|
|
||||||
|
|
||||||
This release adds minor changes and bugfixes, including support of skip-schema-validation in ``helm`` module and removing deprecated ``ansible.module_utils.six`` imports.
|
|
||||||
|
|
||||||
Minor Changes
|
|
||||||
-------------
|
|
||||||
|
|
||||||
- Add support of skip-schema-validation in ``helm`` module (https://github.com/ansible-collections/kubernetes.core/pull/995)
|
|
||||||
- kustomize - Add support of local environ (https://github.com/ansible-collections/kubernetes.core/pull/786).
|
|
||||||
|
|
||||||
Bugfixes
|
|
||||||
--------
|
|
||||||
|
|
||||||
- Remove ``ansible.module_utils.six`` imports to avoid warnings (https://github.com/ansible-collections/kubernetes.core/pull/998).
|
|
||||||
- Update the ``k8s_cp`` module to also work for init containers (https://github.com/ansible-collections/kubernetes.core/pull/971).
|
|
||||||
|
|
||||||
v6.1.0
|
|
||||||
======
|
|
||||||
|
|
||||||
Release Summary
|
|
||||||
---------------
|
|
||||||
|
|
||||||
This release adds ``plain_http`` and ``take_ownership`` parameters for helm modules, support for ``hidden_fields`` in ``k8s_json_patch``, documented lack of idempotency support in ``helm_registry_auth`` with ``helm ≥ 3.18.0``, and improved ``k8s_rollback`` test coverage.
|
|
||||||
|
|
||||||
Minor Changes
|
|
||||||
-------------
|
|
||||||
|
|
||||||
- Module helm_registry_auth do not support idempotency with `helm >= 3.18.0` (https://github.com/ansible-collections/kubernetes.core/pull/946)
|
|
||||||
- Module k8s_json_patch - Add support for `hidden_fields` (https://github.com/ansible-collections/kubernetes.core/pull/964).
|
|
||||||
- helm - Parameter plain_http added for working with insecure OCI registries (https://github.com/ansible-collections/kubernetes.core/pull/934).
|
|
||||||
- helm - Parameter take_ownership added (https://github.com/ansible-collections/kubernetes.core/pull/957).
|
|
||||||
- helm_pull - Parameter plain_http added for working with insecure OCI registries (https://github.com/ansible-collections/kubernetes.core/pull/934).
|
|
||||||
- helm_template - Parameter plain_http added for working with insecure OCI registries (https://github.com/ansible-collections/kubernetes.core/pull/934).
|
|
||||||
|
|
||||||
Bugfixes
|
|
||||||
--------
|
|
||||||
|
|
||||||
- module_utils/k8s/service - hide fields first before creating diffs (https://github.com/ansible-collections/kubernetes.core/pull/915).
|
|
||||||
|
|
||||||
v6.0.0
|
|
||||||
======
|
|
||||||
|
|
||||||
Breaking Changes / Porting Guide
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
- Remove deprecated ``k8s`` invetory plugin (https://github.com/ansible-collections/kubernetes.core/pull/867).
|
|
||||||
- Remove support for ``ansible-core<2.16`` (https://github.com/ansible-collections/kubernetes.core/pull/867).
|
|
||||||
|
|
||||||
v5.4.1
|
v5.4.1
|
||||||
======
|
======
|
||||||
|
|
||||||
@@ -144,7 +65,7 @@ This release updates the ``helm_registry_auth`` module to match the behavior of
|
|||||||
Minor Changes
|
Minor Changes
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
- Module ``helm_registry_auth`` does not support idempotency with ``helm >= 3.18.0`` (https://github.com/ansible-collections/kubernetes.core/pull/946).
|
- Module ``helm_registry_auth`` does not support idempotency with ``helm >= 3.18.0`` (https://github.com/ansible-collections/kubernetes.core/pull/946)
|
||||||
|
|
||||||
v5.3.0
|
v5.3.0
|
||||||
======
|
======
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -1,5 +1,5 @@
|
|||||||
# Also needs to be updated in galaxy.yml
|
# Also needs to be updated in galaxy.yml
|
||||||
VERSION = 6.4.0
|
VERSION = 5.4.2
|
||||||
|
|
||||||
TEST_ARGS ?= ""
|
TEST_ARGS ?= ""
|
||||||
PYTHON_VERSION ?= `python -c 'import platform; print(".".join(platform.python_version_tuple()[0:2]))'`
|
PYTHON_VERSION ?= `python -c 'import platform; print(".".join(platform.python_version_tuple()[0:2]))'`
|
||||||
|
|||||||
21
README.md
21
README.md
@@ -21,10 +21,12 @@ For more information about communication, see the [Ansible communication guide](
|
|||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
<!--start requires_ansible-->
|
<!--start requires_ansible-->
|
||||||
## Ansible version compatibility
|
## Ansible Version Compatibility
|
||||||
|
|
||||||
This collection has been tested against the following Ansible versions: **>=2.16.0**.
|
This collection has been tested against following Ansible versions: **>=2.15.0**.
|
||||||
|
|
||||||
|
For collections that support Ansible 2.9, please ensure you update your `network_os` to use the
|
||||||
|
fully qualified collection name (for example, `cisco.ios.ios`).
|
||||||
Plugins and modules within a collection may be tested with only specific Ansible versions.
|
Plugins and modules within a collection may be tested with only specific Ansible versions.
|
||||||
A collection may contain metadata that identifies these versions.
|
A collection may contain metadata that identifies these versions.
|
||||||
PEP440 is the schema used to describe the versions of Ansible.
|
PEP440 is the schema used to describe the versions of Ansible.
|
||||||
@@ -32,7 +34,7 @@ PEP440 is the schema used to describe the versions of Ansible.
|
|||||||
|
|
||||||
### Helm Version Compatibility
|
### Helm Version Compatibility
|
||||||
|
|
||||||
This collection supports Helm v3.x and newer. Please note that specific modules or certain parameters may have additional version requirements.
|
Helm modules in this collection are compatible with Helm v3.x and are not yet compatible with Helm v4. Individual modules and their parameters may support a more specific range of Helm versions.
|
||||||
|
|
||||||
### Python Support
|
### Python Support
|
||||||
|
|
||||||
@@ -49,17 +51,22 @@ This collection supports Kubernetes versions >= 1.24.
|
|||||||
Click on the name of a plugin or module to view that content's documentation:
|
Click on the name of a plugin or module to view that content's documentation:
|
||||||
|
|
||||||
<!--start collection content-->
|
<!--start collection content-->
|
||||||
### Connection plugins
|
### Connection Plugins
|
||||||
Name | Description
|
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.
|
[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
|
Name | Description
|
||||||
--- | ---
|
--- | ---
|
||||||
kubernetes.core.k8s_config_resource_name|Generate resource name for the given resource of type ConfigMap, Secret
|
kubernetes.core.k8s_config_resource_name|Generate resource name for the given resource of type ConfigMap, Secret
|
||||||
|
|
||||||
### Lookup 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
|
||||||
Name | Description
|
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.k8s](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_lookup.rst)|Query the K8s API
|
||||||
@@ -103,7 +110,7 @@ You can also include it in a `requirements.yml` file and install it via `ansible
|
|||||||
---
|
---
|
||||||
collections:
|
collections:
|
||||||
- name: kubernetes.core
|
- name: kubernetes.core
|
||||||
version: 6.4.0
|
version: 5.4.2
|
||||||
```
|
```
|
||||||
|
|
||||||
### Installing the Kubernetes Python Library
|
### Installing the Kubernetes Python Library
|
||||||
|
|||||||
@@ -1027,13 +1027,13 @@ releases:
|
|||||||
changes:
|
changes:
|
||||||
bugfixes:
|
bugfixes:
|
||||||
- module_utils/k8s/service - fix issue when trying to delete resource using
|
- module_utils/k8s/service - fix issue when trying to delete resource using
|
||||||
``delete_options`` and ``check_mode=true`` (https://github.com/ansible-collections/kubernetes.core/issues/892).
|
`delete_options` and `check_mode=true` (https://github.com/ansible-collections/kubernetes.core/issues/892).
|
||||||
minor_changes:
|
minor_changes:
|
||||||
- Bump version of ``ansible-lint`` to 25.1.2 (https://github.com/ansible-collections/kubernetes.core/pull/919).
|
- kubernetes.core - Bump version of ``ansible-lint`` to ``25.1.2`` (https://github.com/ansible-collections/kubernetes.core/pull/919).
|
||||||
- action/k8s_info - update templating mechanism with changes from ``ansible-core
|
- action/k8s_info - update templating mechanism with changes from ``ansible-core
|
||||||
2.19`` (https://github.com/ansible-collections/kubernetes.core/pull/888).
|
2.19`` (https://github.com/ansible-collections/kubernetes.core/pull/888).
|
||||||
- helm - add ``reset_then_reuse_values`` support to helm module (https://github.com/ansible-collections/kubernetes.core/issues/803).
|
- helm - add ``reset_then_reuse_values`` support to helm module (https://github.com/ansible-collections/kubernetes.core/issues/803).
|
||||||
- helm - add support for ``insecure_skip_tls_verify`` option to helm and helm_repository(https://github.com/ansible-collections/kubernetes.core/issues/694).
|
- helm - add support for ``insecure_skip_tls_verify`` option to helm and ``helm_repository`` (https://github.com/ansible-collections/kubernetes.core/issues/694).
|
||||||
release_summary: This release includes minor changes, bug fixes and also bumps
|
release_summary: This release includes minor changes, bug fixes and also bumps
|
||||||
``ansible-lint`` version to ``25.1.2``.
|
``ansible-lint`` version to ``25.1.2``.
|
||||||
fragments:
|
fragments:
|
||||||
@@ -1062,7 +1062,7 @@ releases:
|
|||||||
changes:
|
changes:
|
||||||
bugfixes:
|
bugfixes:
|
||||||
- Remove ``ansible.module_utils.six`` imports to avoid warnings (https://github.com/ansible-collections/kubernetes.core/pull/998).
|
- Remove ``ansible.module_utils.six`` imports to avoid warnings (https://github.com/ansible-collections/kubernetes.core/pull/998).
|
||||||
- Update the ``k8s_cp`` module to also work for init containers (https://github.com/ansible-collections/kubernetes.core/pull/971).
|
- Update the `k8s_cp` module to also work for init containers (https://github.com/ansible-collections/kubernetes.core/pull/971).
|
||||||
- module_utils/k8s/service - hide fields first before creating diffs (https://github.com/ansible-collections/kubernetes.core/pull/915).
|
- module_utils/k8s/service - hide fields first before creating diffs (https://github.com/ansible-collections/kubernetes.core/pull/915).
|
||||||
release_summary: This release includes bugfixes for k8s service field handling,
|
release_summary: This release includes bugfixes for k8s service field handling,
|
||||||
k8s_cp init containers support, and removes deprecated ansible.module_utils.six
|
k8s_cp init containers support, and removes deprecated ansible.module_utils.six
|
||||||
@@ -1073,67 +1073,12 @@ releases:
|
|||||||
- 20250922-remove-ansible-six-imports.yaml
|
- 20250922-remove-ansible-six-imports.yaml
|
||||||
- 5.4.1.yml
|
- 5.4.1.yml
|
||||||
release_date: '2025-10-07'
|
release_date: '2025-10-07'
|
||||||
6.0.0:
|
5.4.2:
|
||||||
changes:
|
|
||||||
breaking_changes:
|
|
||||||
- Remove deprecated ``k8s`` invetory plugin (https://github.com/ansible-collections/kubernetes.core/pull/867).
|
|
||||||
- Remove support for ``ansible-core<2.16`` (https://github.com/ansible-collections/kubernetes.core/pull/867).
|
|
||||||
fragments:
|
|
||||||
- 20250121-breaking-changes-6.0.0.yml
|
|
||||||
release_date: '2025-05-19'
|
|
||||||
6.1.0:
|
|
||||||
changes:
|
|
||||||
bugfixes:
|
|
||||||
- module_utils/k8s/service - hide fields first before creating diffs (https://github.com/ansible-collections/kubernetes.core/pull/915).
|
|
||||||
minor_changes:
|
|
||||||
- Module ``helm_registry_auth`` does not support idempotency with `helm >= 3.18.0`
|
|
||||||
(https://github.com/ansible-collections/kubernetes.core/pull/946).
|
|
||||||
- Module k8s_json_patch - Add support for ``hidden_fields`` (https://github.com/ansible-collections/kubernetes.core/pull/964).
|
|
||||||
- helm - Parameter plain_http added for working with insecure OCI registries
|
|
||||||
(https://github.com/ansible-collections/kubernetes.core/pull/934).
|
|
||||||
- helm - Parameter take_ownership added (https://github.com/ansible-collections/kubernetes.core/pull/957).
|
|
||||||
- helm_pull - Parameter plain_http added for working with insecure OCI registries
|
|
||||||
(https://github.com/ansible-collections/kubernetes.core/pull/934).
|
|
||||||
- helm_template - Parameter plain_http added for working with insecure OCI registries
|
|
||||||
(https://github.com/ansible-collections/kubernetes.core/pull/934).
|
|
||||||
release_summary: "This release adds ``plain_http`` and ``take_ownership`` parameters
|
|
||||||
for helm modules, support for ``hidden_fields`` in ``k8s_json_patch``, documented
|
|
||||||
lack of idempotency support in ``helm_registry_auth`` with ``helm \u2265 3.18.0``,
|
|
||||||
and improved ``k8s_rollback`` test coverage."
|
|
||||||
fragments:
|
|
||||||
- 20250411-kubeconfig-no_log-revert.yaml
|
|
||||||
- 20250428-k8s-service-hide-fields-first.yaml
|
|
||||||
- 20250522-add-plain-http-for-oci-registries.yaml
|
|
||||||
- 20250605-fix-helm_registry_auth-integration_test.yaml
|
|
||||||
- 20250704-k8s-rollback-integration-test-coverage.yaml
|
|
||||||
- 20250720-k8s-patch-add-hidden-fields.yaml
|
|
||||||
- 20250911-add-support-helm-take-ownership.yaml
|
|
||||||
- release_summary.yml
|
|
||||||
release_date: '2025-08-12'
|
|
||||||
6.2.0:
|
|
||||||
changes:
|
|
||||||
bugfixes:
|
|
||||||
- Remove ``ansible.module_utils.six`` imports to avoid warnings (https://github.com/ansible-collections/kubernetes.core/pull/998).
|
|
||||||
- Update the `k8s_cp` module to also work for init containers (https://github.com/ansible-collections/kubernetes.core/pull/971).
|
|
||||||
minor_changes:
|
|
||||||
- Add support of skip-schema-validation in ``helm`` module (https://github.com/ansible-collections/kubernetes.core/pull/995)
|
|
||||||
- kustomize - Add support of local environ (https://github.com/ansible-collections/kubernetes.core/pull/786).
|
|
||||||
release_summary: This release adds minor changes and bugfixes, including support
|
|
||||||
of skip-schema-validation in ``helm`` module and removing deprecated ``ansible.module_utils.six``
|
|
||||||
imports.
|
|
||||||
fragments:
|
|
||||||
- 20241030-support-of-evrion-for-kustomize-lookup-plugin.yaml
|
|
||||||
- 20250731-fix-k8s_cp-initcontainers.yaml
|
|
||||||
- 20250916-skip-schema-validation.yaml
|
|
||||||
- 20250922-remove-ansible-six-imports.yaml
|
|
||||||
- 6_2_0.yml
|
|
||||||
release_date: '2025-10-07'
|
|
||||||
6.3.0:
|
|
||||||
changes:
|
changes:
|
||||||
bugfixes:
|
bugfixes:
|
||||||
- Add idempotency for ``helm_pull`` module (https://github.com/ansible-collections/kubernetes.core/pull/1055).
|
- Add idempotency for ``helm_pull`` module (https://github.com/ansible-collections/kubernetes.core/pull/1055).
|
||||||
- Fixed a bug where setting ``K8S_AUTH_VERIFY_SSL=true`` (or any string value)
|
- Fixed a bug where setting ``K8S_AUTH_VERIFY_SSL=true`` (or any string value)
|
||||||
caused the value to be treated as a separate ``kubectl`` command argument.
|
caused the value to be treated as a separate ``kubectl`` command argument
|
||||||
(https://github.com/ansible-collections/kubernetes.core/pull/1049).
|
(https://github.com/ansible-collections/kubernetes.core/pull/1049).
|
||||||
- Limit supported versions of Helm to <4.0.0 (https://github.com/ansible-collections/kubernetes.core/pull/1039).
|
- Limit supported versions of Helm to <4.0.0 (https://github.com/ansible-collections/kubernetes.core/pull/1039).
|
||||||
- Replace passing ``warnings`` to ``exit_json`` with ``AnsibleModule.warn``
|
- Replace passing ``warnings`` to ``exit_json`` with ``AnsibleModule.warn``
|
||||||
@@ -1151,14 +1096,13 @@ releases:
|
|||||||
be removed in a release after 2027-01-08. Use ``status.release_values`` instead
|
be removed in a release after 2027-01-08. Use ``status.release_values`` instead
|
||||||
(https://github.com/ansible-collections/kubernetes.core/pull/1056).
|
(https://github.com/ansible-collections/kubernetes.core/pull/1056).
|
||||||
minor_changes:
|
minor_changes:
|
||||||
- Remove deprecated import from ``ansible.module_utils._text`` (https://github.com/ansible-collections/kubernetes.core/pull/1053).
|
- helm - added ``release_values`` key to ``status`` return value that can be
|
||||||
- helm - add ``release_values`` key to ``status`` return value that can be accessed
|
accessed using Jinja2 dot notation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
|
||||||
using Jinja2 dot notation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
|
- helm_info - added ``release_values`` key to ``status`` return value that can
|
||||||
- helm_info - add ``release_values`` key to ``status`` return value that can
|
|
||||||
be accessed using Jinja2 dot notation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
|
be accessed using Jinja2 dot notation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
|
||||||
release_summary: This release includes bugfixes such as implementing idempotency
|
release_summary: This release includes various bugfixes such as replacing the
|
||||||
for the ``helm_pull`` module as well as a security update for selectively
|
passing of ``warnings`` to ``exit_json`` with ``AnsibleModule.warn`` as well
|
||||||
redacting sensitive information from kubeconfig.
|
as security updates for selectively redacting sensitive information from kubeconfig.
|
||||||
security_fixes:
|
security_fixes:
|
||||||
- Selectively redact sensitive info from kubeconfig instead of applying blanket
|
- Selectively redact sensitive info from kubeconfig instead of applying blanket
|
||||||
``no_log=True`` (https://github.com/ansible-collections/kubernetes.core/pull/1014).
|
``no_log=True`` (https://github.com/ansible-collections/kubernetes.core/pull/1014).
|
||||||
@@ -1168,38 +1112,7 @@ releases:
|
|||||||
- 20251007-selective-kubeconfig-redaction.yaml
|
- 20251007-selective-kubeconfig-redaction.yaml
|
||||||
- 20251115-limit-versions-of-helm.yaml
|
- 20251115-limit-versions-of-helm.yaml
|
||||||
- 20251220-fix-K8S_AUTH_VERIFY_SSL-in-kubectl-connecton-plugion.yaml
|
- 20251220-fix-K8S_AUTH_VERIFY_SSL-in-kubectl-connecton-plugion.yaml
|
||||||
- 20251228-1053-remove-deprecated-import.yaml
|
|
||||||
- 20260107-add-idempodency-for-helm-pull.yaml
|
- 20260107-add-idempodency-for-helm-pull.yaml
|
||||||
- 20260108-fix-sanity-failures.yml
|
- 20260108-fix-sanity-failures.yml
|
||||||
- 6-3-0.yaml
|
- 5-4-2.yaml
|
||||||
release_date: '2026-02-03'
|
release_date: '2026-02-03'
|
||||||
6.4.0:
|
|
||||||
changes:
|
|
||||||
bugfixes:
|
|
||||||
- Helm - Allow taking ownership of existing Kubernetes resources on the first
|
|
||||||
installation of a Helm release. Previously, the ``take_ownership`` parameter
|
|
||||||
was always disabled during the initial install, preventing resource adoption
|
|
||||||
(https://github.com/ansible-collections/kubernetes.core/pull/1034).
|
|
||||||
minor_changes:
|
|
||||||
- helm_info - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
|
|
||||||
- helm_plugin - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
|
|
||||||
- helm_plugin_info - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
|
|
||||||
- helm_pull - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
|
|
||||||
- helm_registry_auth - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
|
|
||||||
- helm_registry_auth - add new option plain_http to allow insecure http connection
|
|
||||||
when running ``helm registry login`` (https://github.com/ansible-collections/kubernetes.core/pull/1090).
|
|
||||||
- helm_repository - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
|
|
||||||
- k8s_drain - Add support for ``check_mode`` (https://github.com/ansible-collections/kubernetes.core/pull/1086).
|
|
||||||
- k8s_drain - Convert module warnings into informational displays when users
|
|
||||||
explicitly request the deletion of unmanaged pods, pods with local storage,
|
|
||||||
or those managed by a ``DaemonSet`` (https://github.com/ansible-collections/kubernetes.core/issues/1037).
|
|
||||||
release_summary: This release adds Helm v4 compatibility across the Helm modules
|
|
||||||
and improves ``k8s_drain`` with check mode. When you explicitly allow evicting
|
|
||||||
unmanaged pods, pods with local storage, or pods managed by a ``DaemonSet``,
|
|
||||||
those cases are reported as informational output instead of module warnings.
|
|
||||||
fragments:
|
|
||||||
- 20251224-take-ownership-helm-initialization.yaml
|
|
||||||
- 20260203-k8s_drain-warning-fixes.yaml
|
|
||||||
- 20260213-support-helm-v4-for-helm-plugin-modules.yaml
|
|
||||||
- release-6-4-0.yml
|
|
||||||
release_date: '2026-04-22'
|
|
||||||
|
|||||||
147
docs/ansible_turbo_mode.rst
Normal file
147
docs/ansible_turbo_mode.rst
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
.. _ansible_turbo_mode:
|
||||||
|
|
||||||
|
|
||||||
|
******************
|
||||||
|
Ansible Turbo mode
|
||||||
|
******************
|
||||||
|
|
||||||
|
Following document provides overview of Ansible Turbo mode in ``kubernetes.core`` collection.
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
:depth: 1
|
||||||
|
|
||||||
|
|
||||||
|
Synopsis
|
||||||
|
--------
|
||||||
|
- A brief introduction about Ansible Turbo mode in ``kuberentes.core`` collection.
|
||||||
|
- Ansible Turbo mode is an optional performance optimization. It can be enabled by installing the cloud.common collection and setting the ``ENABLE_TURBO_MODE`` environment variable.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
|
||||||
|
The following requirement is needed on the host that executes this module.
|
||||||
|
|
||||||
|
- The ``cloud.common`` collection (https://github.com/ansible-collections/cloud.common)
|
||||||
|
|
||||||
|
You will also need to set the environment variable ``ENABLE_TURBO_MODE=1`` on the managed host. This can be done in the same ways you would usually do so, for example::
|
||||||
|
|
||||||
|
---
|
||||||
|
- hosts: remote
|
||||||
|
environment:
|
||||||
|
ENABLE_TURBO_MODE: 1
|
||||||
|
tasks:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
|
||||||
|
You can install ``cloud.common`` collection using following command::
|
||||||
|
|
||||||
|
# ansible-galaxy collection install cloud.common
|
||||||
|
|
||||||
|
|
||||||
|
Current situation without Ansible Turbo mode
|
||||||
|
============================================
|
||||||
|
|
||||||
|
The traditional execution flow of an Ansible module includes the following steps:
|
||||||
|
|
||||||
|
- Upload of a ZIP archive with the module and its dependencies
|
||||||
|
- Execution of the module
|
||||||
|
- Ansible collects the results once the script is finished
|
||||||
|
|
||||||
|
These steps happen for each task of a playbook, and on every host.
|
||||||
|
|
||||||
|
Most of the time, the execution of a module is fast enough for
|
||||||
|
the user. However, sometime the module requires significant amount of time,
|
||||||
|
just to initialize itself. This is a common situation with the API based modules.
|
||||||
|
|
||||||
|
A classic initialization involves the following steps:
|
||||||
|
|
||||||
|
- Load a Python library to access the remote resource (via SDK)
|
||||||
|
- Open a client
|
||||||
|
- Load a bunch of Python modules.
|
||||||
|
- Request a new TCP connection.
|
||||||
|
- Create a session.
|
||||||
|
- Authenticate the client.
|
||||||
|
|
||||||
|
All these steps are time consuming and the same operations will be running again and again.
|
||||||
|
|
||||||
|
For instance, here:
|
||||||
|
|
||||||
|
- ``import openstack``: takes 0.569s
|
||||||
|
- ``client = openstack.connect()``: takes 0.065s
|
||||||
|
- ``client.authorize()``: takes 1.360s,
|
||||||
|
|
||||||
|
These numbers are from test running against VexxHost public cloud.
|
||||||
|
|
||||||
|
In this case, it's a 2s-ish overhead per task. If the playbook
|
||||||
|
comes with 10 tasks, the execution time cannot go below 20s.
|
||||||
|
|
||||||
|
How Ansible Turbo Module improve the situation
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
``AnsibleTurboModule`` is actually a class that inherites from
|
||||||
|
the standard ``AnsibleModule`` class that your modules probably
|
||||||
|
already use.
|
||||||
|
The big difference is that when a module starts, it also spawns
|
||||||
|
a little Python daemon. If a daemon already exists, it will just
|
||||||
|
reuse it.
|
||||||
|
All the module logic is run inside this Python daemon. This means:
|
||||||
|
|
||||||
|
- Python modules are actually loaded one time
|
||||||
|
- Ansible module can reuse an existing authenticated session.
|
||||||
|
|
||||||
|
The background service
|
||||||
|
======================
|
||||||
|
|
||||||
|
The daemon kills itself after 15s, and communication are done
|
||||||
|
through an Unix socket.
|
||||||
|
It runs in one single process and uses ``asyncio`` internally.
|
||||||
|
Consequently you can use the ``async`` keyword in your Ansible module.
|
||||||
|
This will be handy if you interact with a lot of remote systems
|
||||||
|
at the same time.
|
||||||
|
|
||||||
|
Security impact
|
||||||
|
===============
|
||||||
|
|
||||||
|
``ansible_module.turbo`` open an Unix socket to interact with the background service.
|
||||||
|
We use this service to open the connection toward the different target systems.
|
||||||
|
|
||||||
|
This is similar to what SSH does with the sockets.
|
||||||
|
|
||||||
|
Keep in mind that:
|
||||||
|
|
||||||
|
- All the modules can access the same cache. Soon an isolation will be done at the collection level (https://github.com/ansible-collections/cloud.common/pull/17)
|
||||||
|
- A task can load a different version of a library and impact the next tasks.
|
||||||
|
- If the same user runs two ``ansible-playbook`` at the same time, they will have access to the same cache.
|
||||||
|
|
||||||
|
When a module stores a session in a cache, it's a good idea to use a hash of the authentication information to identify the session.
|
||||||
|
|
||||||
|
Error management
|
||||||
|
================
|
||||||
|
|
||||||
|
``ansible_module.turbo`` uses exceptions to communicate a result back to the module.
|
||||||
|
|
||||||
|
- ``EmbeddedModuleFailure`` is raised when ``json_fail()`` is called.
|
||||||
|
- ``EmbeddedModuleSuccess`` is raised in case of success and returns the result to the origin module process.
|
||||||
|
|
||||||
|
These exceptions are defined in ``ansible_collections.cloud.common.plugins.module_utils.turbo.exceptions``.
|
||||||
|
You can raise ``EmbeddedModuleFailure`` exception yourself, for instance from a module in ``module_utils``.
|
||||||
|
|
||||||
|
.. note:: Be careful with the ``except Exception:`` blocks.
|
||||||
|
Not only they are bad practice, but also may interface with this
|
||||||
|
mechanism.
|
||||||
|
|
||||||
|
|
||||||
|
Troubleshooting
|
||||||
|
===============
|
||||||
|
|
||||||
|
You may want to manually start the server. This can be done with the following command:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
PYTHONPATH=$HOME/.ansible/collections python -m ansible_collections.cloud.common.plugins.module_utils.turbo.server --socket-path $HOME/.ansible/tmp/turbo_mode.kubernetes.core.socket
|
||||||
|
|
||||||
|
You can use the ``--help`` argument to get a list of the optional parameters.
|
||||||
@@ -17,7 +17,7 @@ Requirements
|
|||||||
|
|
||||||
To use the modules, you'll need the following:
|
To use the modules, you'll need the following:
|
||||||
|
|
||||||
- Ansible 2.16.0 or latest installed
|
- Ansible 2.9.17 or latest installed
|
||||||
- `Kubernetes Python client <https://pypi.org/project/kubernetes/>`_ installed on the host that will execute the modules.
|
- `Kubernetes Python client <https://pypi.org/project/kubernetes/>`_ installed on the host that will execute the modules.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
88
docs/docsite/rst/kubernetes_scenarios/k8s_inventory.rst
Normal file
88
docs/docsite/rst/kubernetes_scenarios/k8s_inventory.rst
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
.. _ansible_collections.kubernetes.core.docsite.k8s_ansible_inventory:
|
||||||
|
|
||||||
|
*****************************************
|
||||||
|
Using Kubernetes dynamic inventory plugin
|
||||||
|
*****************************************
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
|
||||||
|
Kubernetes dynamic inventory plugin
|
||||||
|
===================================
|
||||||
|
|
||||||
|
|
||||||
|
The best way to interact with your Pods is to use the Kubernetes dynamic inventory plugin, which queries Kubernetes APIs using ``kubectl`` command line available on controller node and tells Ansible what Pods can be managed.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
|
||||||
|
To use the Kubernetes dynamic inventory plugins, you must install `Kubernetes Python client <https://github.com/kubernetes-client/python>`_, `kubectl <https://github.com/kubernetes/kubectl>`_ on your control node (the host running Ansible).
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ pip install kubernetes
|
||||||
|
|
||||||
|
Please refer to Kubernetes official documentation for `installing kubectl <https://kubernetes.io/docs/tasks/tools/install-kubectl/>`_ on the given operating systems.
|
||||||
|
|
||||||
|
To use this Kubernetes dynamic inventory plugin, you need to enable it first by specifying the following in the ``ansible.cfg`` file:
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[inventory]
|
||||||
|
enable_plugins = kubernetes.core.k8s
|
||||||
|
|
||||||
|
Then, create a file that ends in ``.k8s.yml`` or ``.k8s.yaml`` in your working directory.
|
||||||
|
|
||||||
|
The ``kubernetes.core.k8s`` inventory plugin takes in the same authentication information as any other Kubernetes modules.
|
||||||
|
|
||||||
|
Here's an example of a valid inventory file:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
plugin: kubernetes.core.k8s
|
||||||
|
|
||||||
|
Executing ``ansible-inventory --list -i <filename>.k8s.yml`` will create a list of Pods that are ready to be configured using Ansible.
|
||||||
|
|
||||||
|
You can also provide the namespace to gather information about specific pods from the given namespace. For example, to gather information about Pods under the ``test`` namespace you will specify the ``namespaces`` parameter:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
plugin: kubernetes.core.k8s
|
||||||
|
connections:
|
||||||
|
- namespaces:
|
||||||
|
- test
|
||||||
|
|
||||||
|
Using vaulted configuration files
|
||||||
|
=================================
|
||||||
|
|
||||||
|
Since the inventory configuration file contains Kubernetes related sensitive information in plain text, a security risk, you may want to
|
||||||
|
encrypt your entire inventory configuration file.
|
||||||
|
|
||||||
|
You can encrypt a valid inventory configuration file as follows:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ ansible-vault encrypt <filename>.k8s.yml
|
||||||
|
New Vault password:
|
||||||
|
Confirm New Vault password:
|
||||||
|
Encryption successful
|
||||||
|
|
||||||
|
$ echo "MySuperSecretPassw0rd!" > /path/to/vault_password_file
|
||||||
|
|
||||||
|
And you can use this vaulted inventory configuration file using:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ ansible-inventory -i <filename>.k8s.yml --list --vault-password-file=/path/to/vault_password_file
|
||||||
|
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
|
||||||
|
`Kubernetes Python client - Issue Tracker <https://github.com/kubernetes-client/python/issues>`_
|
||||||
|
The issue tracker for Kubernetes Python client
|
||||||
|
`Kubectl installation <https://kubernetes.io/docs/tasks/tools/install-kubectl/>`_
|
||||||
|
Installation guide for installing Kubectl
|
||||||
|
:ref:`working_with_playbooks`
|
||||||
|
An introduction to playbooks
|
||||||
|
:ref:`playbooks_vault`
|
||||||
|
Using Vault in playbooks
|
||||||
@@ -13,5 +13,6 @@ To get started, please select one of the following topics.
|
|||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|
||||||
kubernetes_scenarios/k8s_intro
|
kubernetes_scenarios/k8s_intro
|
||||||
|
kubernetes_scenarios/k8s_inventory
|
||||||
kubernetes_scenarios/k8s_scenarios
|
kubernetes_scenarios/k8s_scenarios
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Requirements
|
|||||||
------------
|
------------
|
||||||
The below requirements are needed on the host that executes this module.
|
The below requirements are needed on the host that executes this module.
|
||||||
|
|
||||||
- helm >= 3.0.0 (https://github.com/helm/helm/releases)
|
- helm (https://github.com/helm/helm/releases)
|
||||||
- yaml (https://pypi.org/project/PyYAML/)
|
- yaml (https://pypi.org/project/PyYAML/)
|
||||||
|
|
||||||
|
|
||||||
@@ -268,7 +268,7 @@ Examples
|
|||||||
|
|
||||||
Return Values
|
Return Values
|
||||||
-------------
|
-------------
|
||||||
Common return values are documented `here <https://docs.ansible.com/projects/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
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
|
.. raw:: html
|
||||||
|
|
||||||
@@ -410,23 +410,6 @@ Common return values are documented `here <https://docs.ansible.com/projects/ans
|
|||||||
<br/>
|
<br/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td class="elbow-placeholder"> </td>
|
|
||||||
<td colspan="1">
|
|
||||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
|
||||||
<b>release_values</b>
|
|
||||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
|
||||||
<div style="font-size: small">
|
|
||||||
<span style="color: purple">dictionary</span>
|
|
||||||
</div>
|
|
||||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 6.3.0</div>
|
|
||||||
</td>
|
|
||||||
<td>always</td>
|
|
||||||
<td>
|
|
||||||
<div>Dict of Values used to deploy.</div>
|
|
||||||
<br/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td class="elbow-placeholder"> </td>
|
<td class="elbow-placeholder"> </td>
|
||||||
<td colspan="1">
|
<td colspan="1">
|
||||||
@@ -482,13 +465,12 @@ Common return values are documented `here <https://docs.ansible.com/projects/ans
|
|||||||
<b>values</b>
|
<b>values</b>
|
||||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||||
<div style="font-size: small">
|
<div style="font-size: small">
|
||||||
<span style="color: purple">dictionary</span>
|
<span style="color: purple">string</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>always</td>
|
<td>always</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Dict of Values used to deploy</div>
|
<div>Dict of Values used to deploy</div>
|
||||||
<div>This return value has been deprecated and will be removed in a release after 2027-01-08. Use RV(status.release_values) instead.</div>
|
|
||||||
<br/>
|
<br/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Requirements
|
|||||||
------------
|
------------
|
||||||
The below requirements are needed on the host that executes this module.
|
The below requirements are needed on the host that executes this module.
|
||||||
|
|
||||||
- helm >= 3.0.0 (https://github.com/helm/helm/releases)
|
- helm (https://github.com/helm/helm/releases)
|
||||||
- yaml (https://pypi.org/project/PyYAML/)
|
- yaml (https://pypi.org/project/PyYAML/)
|
||||||
|
|
||||||
|
|
||||||
@@ -330,27 +330,6 @@ Parameters
|
|||||||
<div style="font-size: small; color: darkgreen"><br/>aliases: kubeconfig_path</div>
|
<div style="font-size: small; color: darkgreen"><br/>aliases: kubeconfig_path</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td colspan="2">
|
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
|
||||||
<b>plain_http</b>
|
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
|
||||||
<div style="font-size: small">
|
|
||||||
<span style="color: purple">boolean</span>
|
|
||||||
</div>
|
|
||||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 6.1.0</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
|
||||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
|
||||||
<li>yes</li>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div>Use HTTP instead of HTTPS when working with OCI registries</div>
|
|
||||||
<div>Requires Helm >= 3.13.0</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
@@ -622,48 +601,6 @@ Parameters
|
|||||||
<div>Skip custom resource definitions when installing or upgrading.</div>
|
<div>Skip custom resource definitions when installing or upgrading.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td colspan="2">
|
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
|
||||||
<b>skip_schema_validation</b>
|
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
|
||||||
<div style="font-size: small">
|
|
||||||
<span style="color: purple">boolean</span>
|
|
||||||
</div>
|
|
||||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 6.2.0</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
|
||||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
|
||||||
<li>yes</li>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div>Disables JSON schema validation for Chart and values.</div>
|
|
||||||
<div>This feature requires helm >= 3.16.0</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="2">
|
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
|
||||||
<b>take_ownership</b>
|
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
|
||||||
<div style="font-size: small">
|
|
||||||
<span style="color: purple">boolean</span>
|
|
||||||
</div>
|
|
||||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 6.1.0</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
|
||||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
|
||||||
<li>yes</li>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div>Helm will ignore the check for helm annotations and take ownership of the existing resources</div>
|
|
||||||
<div>This feature requires helm >= 3.17.0</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
@@ -873,12 +810,6 @@ Examples
|
|||||||
chart_ref: "https://github.com/grafana/helm-charts/releases/download/grafana-5.6.0/grafana-5.6.0.tgz"
|
chart_ref: "https://github.com/grafana/helm-charts/releases/download/grafana-5.6.0/grafana-5.6.0.tgz"
|
||||||
release_namespace: monitoring
|
release_namespace: monitoring
|
||||||
|
|
||||||
- name: Deploy Bitnami's MongoDB latest chart from OCI registry
|
|
||||||
kubernetes.core.helm:
|
|
||||||
name: test
|
|
||||||
chart_ref: "oci://registry-1.docker.io/bitnamicharts/mongodb"
|
|
||||||
release_namespace: database
|
|
||||||
|
|
||||||
# Using complex Values
|
# Using complex Values
|
||||||
- name: Deploy new-relic client chart
|
- name: Deploy new-relic client chart
|
||||||
kubernetes.core.helm:
|
kubernetes.core.helm:
|
||||||
@@ -920,7 +851,7 @@ Examples
|
|||||||
|
|
||||||
Return Values
|
Return Values
|
||||||
-------------
|
-------------
|
||||||
Common return values are documented `here <https://docs.ansible.com/projects/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
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
|
.. raw:: html
|
||||||
|
|
||||||
@@ -1026,23 +957,6 @@ Common return values are documented `here <https://docs.ansible.com/projects/ans
|
|||||||
<br/>
|
<br/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td class="elbow-placeholder"> </td>
|
|
||||||
<td colspan="1">
|
|
||||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
|
||||||
<b>release_values</b>
|
|
||||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
|
||||||
<div style="font-size: small">
|
|
||||||
<span style="color: purple">dictionary</span>
|
|
||||||
</div>
|
|
||||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 6.3.0</div>
|
|
||||||
</td>
|
|
||||||
<td>always</td>
|
|
||||||
<td>
|
|
||||||
<div>Dict of Values used to deploy.</div>
|
|
||||||
<br/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td class="elbow-placeholder"> </td>
|
<td class="elbow-placeholder"> </td>
|
||||||
<td colspan="1">
|
<td colspan="1">
|
||||||
@@ -1098,13 +1012,12 @@ Common return values are documented `here <https://docs.ansible.com/projects/ans
|
|||||||
<b>values</b>
|
<b>values</b>
|
||||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||||
<div style="font-size: small">
|
<div style="font-size: small">
|
||||||
<span style="color: purple">dictionary</span>
|
<span style="color: purple">string</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>always</td>
|
<td>always</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Dict of Values used to deploy.</div>
|
<div>Dict of Values used to deploy</div>
|
||||||
<div>This return value has been deprecated and will be removed in a release after 2027-01-08. Use RV(status.release_values) instead.</div>
|
|
||||||
<br/>
|
<br/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Requirements
|
|||||||
------------
|
------------
|
||||||
The below requirements are needed on the host that executes this module.
|
The below requirements are needed on the host that executes this module.
|
||||||
|
|
||||||
- helm >= 3.0.0 (https://github.com/helm/helm/releases)
|
- helm (https://github.com/helm/helm/releases)
|
||||||
|
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
@@ -196,7 +196,7 @@ Examples
|
|||||||
|
|
||||||
Return Values
|
Return Values
|
||||||
-------------
|
-------------
|
||||||
Common return values are documented `here <https://docs.ansible.com/projects/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
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
|
.. raw:: html
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Requirements
|
|||||||
------------
|
------------
|
||||||
The below requirements are needed on the host that executes this module.
|
The below requirements are needed on the host that executes this module.
|
||||||
|
|
||||||
- helm >= 3.0.0 (https://github.com/helm/helm/releases)
|
- helm (https://github.com/helm/helm/releases)
|
||||||
|
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
@@ -231,28 +231,6 @@ Parameters
|
|||||||
<div style="font-size: small; color: darkgreen"><br/>aliases: verify_ssl</div>
|
<div style="font-size: small; color: darkgreen"><br/>aliases: verify_ssl</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td colspan="1">
|
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
|
||||||
<b>verify</b>
|
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
|
||||||
<div style="font-size: small">
|
|
||||||
<span style="color: purple">boolean</span>
|
|
||||||
</div>
|
|
||||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 6.4.0</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
|
||||||
<li>no</li>
|
|
||||||
<li><div style="color: blue"><b>yes</b> ←</div></li>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div>Verify the plugin signature before installing.</div>
|
|
||||||
<div>This option requires helm version >= 4.0.0</div>
|
|
||||||
<div>Used with <em>state=present</em>.</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
</table>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
@@ -294,7 +272,7 @@ Examples
|
|||||||
|
|
||||||
Return Values
|
Return Values
|
||||||
-------------
|
-------------
|
||||||
Common return values are documented `here <https://docs.ansible.com/projects/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
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
|
.. raw:: html
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ Requirements
|
|||||||
------------
|
------------
|
||||||
The below requirements are needed on the host that executes this module.
|
The below requirements are needed on the host that executes this module.
|
||||||
|
|
||||||
- helm >= 3.0.0 (https://github.com/helm/helm/releases)
|
- helm >= 3.0, <4.0.0 (https://github.com/helm/helm/releases)
|
||||||
|
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
@@ -215,27 +215,6 @@ Parameters
|
|||||||
<div>Pass credentials to all domains.</div>
|
<div>Pass credentials to all domains.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td colspan="1">
|
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
|
||||||
<b>plain_http</b>
|
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
|
||||||
<div style="font-size: small">
|
|
||||||
<span style="color: purple">boolean</span>
|
|
||||||
</div>
|
|
||||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 6.1.0</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
|
||||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
|
||||||
<li>yes</li>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div>Use HTTP instead of HTTPS when working with OCI registries</div>
|
|
||||||
<div>Requires Helm >= 3.13.0</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="1">
|
<td colspan="1">
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Requirements
|
|||||||
------------
|
------------
|
||||||
The below requirements are needed on the host that executes this module.
|
The below requirements are needed on the host that executes this module.
|
||||||
|
|
||||||
- helm (https://github.com/helm/helm/releases) >= 3.8.0
|
- helm (https://github.com/helm/helm/releases) >= 3.8.0, <4.0.0
|
||||||
|
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
@@ -151,27 +151,6 @@ Parameters
|
|||||||
<div style="font-size: small; color: darkgreen"><br/>aliases: repo_password</div>
|
<div style="font-size: small; color: darkgreen"><br/>aliases: repo_password</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td colspan="1">
|
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
|
||||||
<b>plain_http</b>
|
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
|
||||||
<div style="font-size: small">
|
|
||||||
<span style="color: purple">boolean</span>
|
|
||||||
</div>
|
|
||||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 6.4.0</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
|
||||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
|
||||||
<li>yes</li>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div>Use insecure HTTP connections for <code>helm registry login</code>.</div>
|
|
||||||
<div>Requires Helm >= 3.18.0</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="1">
|
<td colspan="1">
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ Requirements
|
|||||||
------------
|
------------
|
||||||
The below requirements are needed on the host that executes this module.
|
The below requirements are needed on the host that executes this module.
|
||||||
|
|
||||||
- helm >= 3.0.0 (https://github.com/helm/helm/releases)
|
- helm (https://github.com/helm/helm/releases)
|
||||||
- yaml (https://pypi.org/project/PyYAML/)
|
- yaml (https://pypi.org/project/PyYAML/)
|
||||||
|
|
||||||
|
|
||||||
@@ -336,7 +336,7 @@ Examples
|
|||||||
|
|
||||||
Return Values
|
Return Values
|
||||||
-------------
|
-------------
|
||||||
Common return values are documented `here <https://docs.ansible.com/projects/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
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
|
.. raw:: html
|
||||||
|
|
||||||
|
|||||||
@@ -20,13 +20,6 @@ Synopsis
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
|
||||||
------------
|
|
||||||
The below requirements are needed on the host that executes this module.
|
|
||||||
|
|
||||||
- helm >= 3.0.0 (https://github.com/helm/helm/releases)
|
|
||||||
- yaml (https://pypi.org/project/PyYAML/)
|
|
||||||
|
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
@@ -201,27 +194,6 @@ Parameters
|
|||||||
<div>If the directory already exists, it will be overwritten.</div>
|
<div>If the directory already exists, it will be overwritten.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td colspan="2">
|
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
|
||||||
<b>plain_http</b>
|
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
|
||||||
<div style="font-size: small">
|
|
||||||
<span style="color: purple">boolean</span>
|
|
||||||
</div>
|
|
||||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 6.1.0</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
|
||||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
|
||||||
<li>yes</li>
|
|
||||||
</ul>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div>Use HTTP instead of HTTPS when working with OCI registries</div>
|
|
||||||
<div>Requires Helm >= 3.13.0</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
@@ -437,7 +409,7 @@ Examples
|
|||||||
|
|
||||||
Return Values
|
Return Values
|
||||||
-------------
|
-------------
|
||||||
Common return values are documented `here <https://docs.ansible.com/projects/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
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
|
.. raw:: html
|
||||||
|
|
||||||
|
|||||||
372
docs/kubernetes.core.k8s_inventory.rst
Normal file
372
docs/kubernetes.core.k8s_inventory.rst
Normal file
@@ -0,0 +1,372 @@
|
|||||||
|
.. _kubernetes.core.k8s_inventory:
|
||||||
|
|
||||||
|
|
||||||
|
*******************
|
||||||
|
kubernetes.core.k8s
|
||||||
|
*******************
|
||||||
|
|
||||||
|
**Kubernetes (K8s) inventory source**
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
:depth: 1
|
||||||
|
|
||||||
|
DEPRECATED
|
||||||
|
----------
|
||||||
|
:Removed in collection release after
|
||||||
|
:Why: As discussed in https://github.com/ansible-collections/kubernetes.core/issues/31, we decided to
|
||||||
|
remove the k8s inventory plugin in release 6.0.0.
|
||||||
|
|
||||||
|
:Alternative: Use :ref:`kubernetes.core.k8s_info <kubernetes.core.k8s_info_module>` and :ref:`ansible.builtin.add_host <ansible.builtin.add_host_module>` instead.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Synopsis
|
||||||
|
--------
|
||||||
|
- Fetch containers and services for one or more clusters.
|
||||||
|
- Groups by cluster name, namespace, namespace_services, namespace_pods, and labels.
|
||||||
|
- Uses the kubectl connection plugin to access the Kubernetes cluster.
|
||||||
|
- Uses k8s.(yml|yaml) YAML configuration file to set parameter values.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
The below requirements are needed on the local Ansible controller node that executes this inventory.
|
||||||
|
|
||||||
|
- python >= 3.9
|
||||||
|
- kubernetes >= 24.2.0
|
||||||
|
- PyYAML >= 3.11
|
||||||
|
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
|
||||||
|
<table border=0 cellpadding=0 class="documentation-table">
|
||||||
|
<tr>
|
||||||
|
<th colspan="2">Parameter</th>
|
||||||
|
<th>Choices/<font color="blue">Defaults</font></th>
|
||||||
|
<th>Configuration</th>
|
||||||
|
<th width="100%">Comments</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>connections</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">-</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Optional list of cluster connection settings. If no connections are provided, the default <em>~/.kube/config</em> and active context will be used, and objects will be returned for all namespaces the active user is authorized to access.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>api_key</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">-</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Token used to authenticate with the API. Can also be specified via K8S_AUTH_API_KEY environment variable.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>ca_cert</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">-</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Path to a CA certificate used to authenticate with the API. Can also be specified via K8S_AUTH_SSL_CA_CERT environment variable.</div>
|
||||||
|
<div style="font-size: small; color: darkgreen"><br/>aliases: ssl_ca_cert</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>client_cert</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">-</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Path to a certificate used to authenticate with the API. Can also be specified via K8S_AUTH_CERT_FILE environment variable.</div>
|
||||||
|
<div style="font-size: small; color: darkgreen"><br/>aliases: cert_file</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>client_key</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">-</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Path to a key file used to authenticate with the API. Can also be specified via K8S_AUTH_KEY_FILE environment variable.</div>
|
||||||
|
<div style="font-size: small; color: darkgreen"><br/>aliases: key_file</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>context</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">-</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>The name of a context found in the config file. Can also be specified via K8S_AUTH_CONTEXT environment variable.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<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">-</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Provide a URL for accessing the API. Can also be specified via K8S_AUTH_HOST environment variable.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>kubeconfig</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">-</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>name</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">-</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Optional name to assign to the cluster. If not provided, a name is constructed from the server and port.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>namespaces</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">-</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>List of namespaces. If not specified, will fetch all containers for all namespaces user is authorized to access.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<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">-</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Provide a password for authenticating with the API. Can also be specified via K8S_AUTH_PASSWORD environment variable.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<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">-</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Provide a username for authenticating with the API. Can also be specified via K8S_AUTH_USERNAME environment variable.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>validate_certs</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>no</li>
|
||||||
|
<li>yes</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Whether or not to verify the API server's SSL certificates. Can also be specified via K8S_AUTH_VERIFY_SSL environment variable.</div>
|
||||||
|
<div style="font-size: small; color: darkgreen"><br/>aliases: verify_ssl</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>plugin</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">-</span>
|
||||||
|
/ <span style="color: red">required</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||||
|
<li>kubernetes.core.k8s</li>
|
||||||
|
<li>k8s</li>
|
||||||
|
<li>community.kubernetes.k8s</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>token that ensures this is a source file for the 'k8s' plugin.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
# File must be named k8s.yaml or k8s.yml
|
||||||
|
|
||||||
|
- name: Authenticate with token, and return all pods and services for all namespaces
|
||||||
|
plugin: kubernetes.core.k8s
|
||||||
|
connections:
|
||||||
|
- host: https://192.168.64.4:8443
|
||||||
|
api_key: xxxxxxxxxxxxxxxx
|
||||||
|
validate_certs: false
|
||||||
|
|
||||||
|
- name: Use default config (~/.kube/config) file and active context, and return objects for a specific namespace
|
||||||
|
plugin: kubernetes.core.k8s
|
||||||
|
connections:
|
||||||
|
- namespaces:
|
||||||
|
- testing
|
||||||
|
|
||||||
|
- name: Use a custom config file, and a specific context.
|
||||||
|
plugin: kubernetes.core.k8s
|
||||||
|
connections:
|
||||||
|
- kubeconfig: /path/to/config
|
||||||
|
context: 'awx/192-168-64-4:8443/developer'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Status
|
||||||
|
------
|
||||||
|
|
||||||
|
|
||||||
|
- This inventory will be removed in version 6.0.0. *[deprecated]*
|
||||||
|
- For more information see `DEPRECATED`_.
|
||||||
|
|
||||||
|
|
||||||
|
Authors
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
- Chris Houseknecht (@chouseknecht)
|
||||||
|
- Fabian von Feilitzsch (@fabianvf)
|
||||||
|
|
||||||
|
|
||||||
|
.. hint::
|
||||||
|
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||||
@@ -140,25 +140,6 @@ Parameters
|
|||||||
<div>The name of a context found in the config file. Can also be specified via K8S_AUTH_CONTEXT environment variable.</div>
|
<div>The name of a context found in the config file. Can also be specified via K8S_AUTH_CONTEXT environment variable.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td colspan="2">
|
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
|
||||||
<b>hidden_fields</b>
|
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
|
||||||
<div style="font-size: small">
|
|
||||||
<span style="color: purple">list</span>
|
|
||||||
/ <span style="color: purple">elements=string</span>
|
|
||||||
</div>
|
|
||||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 6.1.0</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<b>Default:</b><br/><div style="color: blue">[]</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div>List of fields to hide from the diff output.</div>
|
|
||||||
<div>This is useful for fields that are not relevant to the patch operation, such as `metadata.managedFields`.</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
|||||||
@@ -95,26 +95,6 @@ Parameters
|
|||||||
<div>Enable the helm chart inflation generator</div>
|
<div>Enable the helm chart inflation generator</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td colspan="1">
|
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
|
||||||
<b>environment</b>
|
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
|
||||||
<div style="font-size: small">
|
|
||||||
<span style="color: purple">raw</span>
|
|
||||||
</div>
|
|
||||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 6.2.0</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<b>Default:</b><br/><div style="color: blue">{}</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div>The environment variables to pass to the kustomize or kubectl command.</div>
|
|
||||||
<div>This can be a dictionary or a string in the format key=value, multiple pairs separated by space.</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="1">
|
<td colspan="1">
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
@@ -165,14 +145,6 @@ Examples
|
|||||||
kubernetes.core.k8s:
|
kubernetes.core.k8s:
|
||||||
definition: "{{ lookup('kubernetes.core.kustomize', dir='/path/to/kustomization', enable_helm=True) }}"
|
definition: "{{ lookup('kubernetes.core.kustomize', dir='/path/to/kustomization', enable_helm=True) }}"
|
||||||
|
|
||||||
- name: Create kubernetes resources for lookup output with environment variables in string format
|
|
||||||
kubernetes.core.k8s:
|
|
||||||
definition: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kubectl', environment='HTTP_PROXY=http://proxy.example.com:3128') }}"
|
|
||||||
|
|
||||||
- name: Create kubernetes resources for lookup output with environment variables in dict format
|
|
||||||
kubernetes.core.k8s:
|
|
||||||
definition: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kubectl', environment={'HTTP_PROXY': 'http://proxy.example.com:3128'}) }}"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Return Values
|
Return Values
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ tags:
|
|||||||
- openshift
|
- openshift
|
||||||
- okd
|
- okd
|
||||||
- cluster
|
- cluster
|
||||||
version: 6.4.0
|
version: 5.4.2
|
||||||
build_ignore:
|
build_ignore:
|
||||||
- .DS_Store
|
- .DS_Store
|
||||||
- "*.tar.gz"
|
- "*.tar.gz"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
requires_ansible: '>=2.16.0'
|
requires_ansible: '>=2.15.0'
|
||||||
|
|
||||||
action_groups:
|
action_groups:
|
||||||
helm:
|
helm:
|
||||||
@@ -24,10 +24,11 @@ plugin_routing:
|
|||||||
openshift:
|
openshift:
|
||||||
redirect: community.okd.openshift
|
redirect: community.okd.openshift
|
||||||
k8s:
|
k8s:
|
||||||
tombstone:
|
deprecation:
|
||||||
removal_version: 6.0.0
|
removal_version: 6.0.0
|
||||||
warning_text: >-
|
warning_text: >-
|
||||||
The k8s inventory plugin was slated for deprecation in 3.3.0 and has been removed in release 6.0.0. Use kubernetes.core.k8s_info and ansible.builtin.add_host instead.
|
The k8s inventory plugin has been deprecated and
|
||||||
|
will be removed in release 6.0.0.
|
||||||
modules:
|
modules:
|
||||||
k8s_auth:
|
k8s_auth:
|
||||||
redirect: community.okd.k8s_auth
|
redirect: community.okd.k8s_auth
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ from ansible.errors import (
|
|||||||
AnsibleError,
|
AnsibleError,
|
||||||
AnsibleFileNotFound,
|
AnsibleFileNotFound,
|
||||||
)
|
)
|
||||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||||
from ansible.module_utils.parsing.convert_bool import boolean
|
from ansible.module_utils.parsing.convert_bool import boolean
|
||||||
from ansible.plugins.action import ActionBase
|
from ansible.plugins.action import ActionBase
|
||||||
|
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ import subprocess
|
|||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
from ansible.errors import AnsibleError, AnsibleFileNotFound
|
from ansible.errors import AnsibleError, AnsibleFileNotFound
|
||||||
from ansible.module_utils.common.text.converters import to_bytes
|
from ansible.module_utils._text import to_bytes
|
||||||
from ansible.module_utils.parsing.convert_bool import boolean
|
from ansible.module_utils.parsing.convert_bool import boolean
|
||||||
from ansible.module_utils.six.moves import shlex_quote
|
from ansible.module_utils.six.moves import shlex_quote
|
||||||
from ansible.parsing.yaml.loader import AnsibleLoader
|
from ansible.parsing.yaml.loader import AnsibleLoader
|
||||||
|
|||||||
476
plugins/inventory/k8s.py
Normal file
476
plugins/inventory/k8s.py
Normal file
@@ -0,0 +1,476 @@
|
|||||||
|
# Copyright (c) 2018 Ansible Project
|
||||||
|
# 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 = """
|
||||||
|
name: k8s
|
||||||
|
author:
|
||||||
|
- Chris Houseknecht (@chouseknecht)
|
||||||
|
- Fabian von Feilitzsch (@fabianvf)
|
||||||
|
|
||||||
|
short_description: Kubernetes (K8s) inventory source
|
||||||
|
|
||||||
|
description:
|
||||||
|
- Fetch containers and services for one or more clusters.
|
||||||
|
- Groups by cluster name, namespace, namespace_services, namespace_pods, and labels.
|
||||||
|
- Uses the kubectl connection plugin to access the Kubernetes cluster.
|
||||||
|
- Uses k8s.(yml|yaml) YAML configuration file to set parameter values.
|
||||||
|
|
||||||
|
deprecated:
|
||||||
|
removed_in: 6.0.0
|
||||||
|
why: |
|
||||||
|
As discussed in U(https://github.com/ansible-collections/kubernetes.core/issues/31), we decided to
|
||||||
|
remove the k8s inventory plugin in release 6.0.0.
|
||||||
|
alternative: "Use M(kubernetes.core.k8s_info) and M(ansible.builtin.add_host) instead."
|
||||||
|
|
||||||
|
options:
|
||||||
|
plugin:
|
||||||
|
description: token that ensures this is a source file for the 'k8s' plugin.
|
||||||
|
required: True
|
||||||
|
choices: ['kubernetes.core.k8s', 'k8s', 'community.kubernetes.k8s']
|
||||||
|
connections:
|
||||||
|
description:
|
||||||
|
- Optional list of cluster connection settings. If no connections are provided, the default
|
||||||
|
I(~/.kube/config) and active context will be used, and objects will be returned for all namespaces
|
||||||
|
the active user is authorized to access.
|
||||||
|
suboptions:
|
||||||
|
name:
|
||||||
|
description:
|
||||||
|
- Optional name to assign to the cluster. If not provided, a name is constructed from the server
|
||||||
|
and port.
|
||||||
|
kubeconfig:
|
||||||
|
description:
|
||||||
|
- Path to an existing Kubernetes config file. If not provided, and no other connection
|
||||||
|
options are provided, the Kubernetes client will attempt to load the default
|
||||||
|
configuration file from I(~/.kube/config). Can also be specified via K8S_AUTH_KUBECONFIG
|
||||||
|
environment variable.
|
||||||
|
context:
|
||||||
|
description:
|
||||||
|
- The name of a context found in the config file. Can also be specified via K8S_AUTH_CONTEXT environment
|
||||||
|
variable.
|
||||||
|
host:
|
||||||
|
description:
|
||||||
|
- Provide a URL for accessing the API. Can also be specified via K8S_AUTH_HOST environment variable.
|
||||||
|
api_key:
|
||||||
|
description:
|
||||||
|
- Token used to authenticate with the API. Can also be specified via K8S_AUTH_API_KEY environment
|
||||||
|
variable.
|
||||||
|
username:
|
||||||
|
description:
|
||||||
|
- Provide a username for authenticating with the API. Can also be specified via K8S_AUTH_USERNAME
|
||||||
|
environment variable.
|
||||||
|
password:
|
||||||
|
description:
|
||||||
|
- Provide a password for authenticating with the API. Can also be specified via K8S_AUTH_PASSWORD
|
||||||
|
environment variable.
|
||||||
|
client_cert:
|
||||||
|
description:
|
||||||
|
- Path to a certificate used to authenticate with the API. Can also be specified via K8S_AUTH_CERT_FILE
|
||||||
|
environment variable.
|
||||||
|
aliases: [ cert_file ]
|
||||||
|
client_key:
|
||||||
|
description:
|
||||||
|
- Path to a key file used to authenticate with the API. Can also be specified via K8S_AUTH_KEY_FILE
|
||||||
|
environment variable.
|
||||||
|
aliases: [ key_file ]
|
||||||
|
ca_cert:
|
||||||
|
description:
|
||||||
|
- Path to a CA certificate used to authenticate with the API. Can also be specified via
|
||||||
|
K8S_AUTH_SSL_CA_CERT environment variable.
|
||||||
|
aliases: [ ssl_ca_cert ]
|
||||||
|
validate_certs:
|
||||||
|
description:
|
||||||
|
- "Whether or not to verify the API server's SSL certificates. Can also be specified via
|
||||||
|
K8S_AUTH_VERIFY_SSL environment variable."
|
||||||
|
type: bool
|
||||||
|
aliases: [ verify_ssl ]
|
||||||
|
namespaces:
|
||||||
|
description:
|
||||||
|
- List of namespaces. If not specified, will fetch all containers for all namespaces user is authorized
|
||||||
|
to access.
|
||||||
|
|
||||||
|
requirements:
|
||||||
|
- "python >= 3.9"
|
||||||
|
- "kubernetes >= 24.2.0"
|
||||||
|
- "PyYAML >= 3.11"
|
||||||
|
"""
|
||||||
|
|
||||||
|
EXAMPLES = r"""
|
||||||
|
# File must be named k8s.yaml or k8s.yml
|
||||||
|
|
||||||
|
- name: Authenticate with token, and return all pods and services for all namespaces
|
||||||
|
plugin: kubernetes.core.k8s
|
||||||
|
connections:
|
||||||
|
- host: https://192.168.64.4:8443
|
||||||
|
api_key: xxxxxxxxxxxxxxxx
|
||||||
|
validate_certs: false
|
||||||
|
|
||||||
|
- name: Use default config (~/.kube/config) file and active context, and return objects for a specific namespace
|
||||||
|
plugin: kubernetes.core.k8s
|
||||||
|
connections:
|
||||||
|
- namespaces:
|
||||||
|
- testing
|
||||||
|
|
||||||
|
- name: Use a custom config file, and a specific context.
|
||||||
|
plugin: kubernetes.core.k8s
|
||||||
|
connections:
|
||||||
|
- kubeconfig: /path/to/config
|
||||||
|
context: 'awx/192-168-64-4:8443/developer'
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
from ansible.errors import AnsibleError
|
||||||
|
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable
|
||||||
|
|
||||||
|
try:
|
||||||
|
from kubernetes.dynamic.exceptions import DynamicApiError
|
||||||
|
|
||||||
|
HAS_K8S_MODULE_HELPER = True
|
||||||
|
k8s_import_exception = None
|
||||||
|
except ImportError as e:
|
||||||
|
HAS_K8S_MODULE_HELPER = False
|
||||||
|
k8s_import_exception = e
|
||||||
|
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
|
||||||
|
get_api_client,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def format_dynamic_api_exc(exc):
|
||||||
|
if exc.body:
|
||||||
|
if exc.headers and exc.headers.get("Content-Type") == "application/json":
|
||||||
|
message = json.loads(exc.body).get("message")
|
||||||
|
if message:
|
||||||
|
return message
|
||||||
|
return exc.body
|
||||||
|
else:
|
||||||
|
return "%s Reason: %s" % (exc.status, exc.reason)
|
||||||
|
|
||||||
|
|
||||||
|
class K8sInventoryException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
|
NAME = "kubernetes.core.k8s"
|
||||||
|
|
||||||
|
connection_plugin = "kubernetes.core.kubectl"
|
||||||
|
transport = "kubectl"
|
||||||
|
|
||||||
|
def parse(self, inventory, loader, path, cache=True):
|
||||||
|
super(InventoryModule, self).parse(inventory, loader, path)
|
||||||
|
|
||||||
|
self.display.deprecated(
|
||||||
|
"The 'k8s' inventory plugin has been deprecated and will be removed in release 6.0.0",
|
||||||
|
version="6.0.0",
|
||||||
|
collection_name="kubernetes.core",
|
||||||
|
)
|
||||||
|
cache_key = self._get_cache_prefix(path)
|
||||||
|
config_data = self._read_config_data(path)
|
||||||
|
self.setup(config_data, cache, cache_key)
|
||||||
|
|
||||||
|
def setup(self, config_data, cache, cache_key):
|
||||||
|
connections = config_data.get("connections")
|
||||||
|
|
||||||
|
if not HAS_K8S_MODULE_HELPER:
|
||||||
|
raise K8sInventoryException(
|
||||||
|
"This module requires the Kubernetes Python client. Try `pip install kubernetes`. Detail: {0}".format(
|
||||||
|
k8s_import_exception
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
source_data = None
|
||||||
|
if cache and cache_key in self._cache:
|
||||||
|
try:
|
||||||
|
source_data = self._cache[cache_key]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not source_data:
|
||||||
|
self.fetch_objects(connections)
|
||||||
|
|
||||||
|
def fetch_objects(self, connections):
|
||||||
|
if connections:
|
||||||
|
if not isinstance(connections, list):
|
||||||
|
raise K8sInventoryException("Expecting connections to be a list.")
|
||||||
|
|
||||||
|
for connection in connections:
|
||||||
|
if not isinstance(connection, dict):
|
||||||
|
raise K8sInventoryException(
|
||||||
|
"Expecting connection to be a dictionary."
|
||||||
|
)
|
||||||
|
client = get_api_client(**connection)
|
||||||
|
name = connection.get(
|
||||||
|
"name", self.get_default_host_name(client.configuration.host)
|
||||||
|
)
|
||||||
|
if connection.get("namespaces"):
|
||||||
|
namespaces = connection["namespaces"]
|
||||||
|
else:
|
||||||
|
namespaces = self.get_available_namespaces(client)
|
||||||
|
for namespace in namespaces:
|
||||||
|
self.get_pods_for_namespace(client, name, namespace)
|
||||||
|
self.get_services_for_namespace(client, name, namespace)
|
||||||
|
else:
|
||||||
|
client = get_api_client()
|
||||||
|
name = self.get_default_host_name(client.configuration.host)
|
||||||
|
namespaces = self.get_available_namespaces(client)
|
||||||
|
for namespace in namespaces:
|
||||||
|
self.get_pods_for_namespace(client, name, namespace)
|
||||||
|
self.get_services_for_namespace(client, name, namespace)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_default_host_name(host):
|
||||||
|
return (
|
||||||
|
host.replace("https://", "")
|
||||||
|
.replace("http://", "")
|
||||||
|
.replace(".", "-")
|
||||||
|
.replace(":", "_")
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_available_namespaces(self, client):
|
||||||
|
v1_namespace = client.resources.get(api_version="v1", kind="Namespace")
|
||||||
|
try:
|
||||||
|
obj = v1_namespace.get()
|
||||||
|
except DynamicApiError as exc:
|
||||||
|
self.display.debug(exc)
|
||||||
|
raise K8sInventoryException(
|
||||||
|
"Error fetching Namespace list: %s" % format_dynamic_api_exc(exc)
|
||||||
|
)
|
||||||
|
return [namespace.metadata.name for namespace in obj.items]
|
||||||
|
|
||||||
|
def get_pods_for_namespace(self, client, name, namespace):
|
||||||
|
v1_pod = client.resources.get(api_version="v1", kind="Pod")
|
||||||
|
try:
|
||||||
|
obj = v1_pod.get(namespace=namespace)
|
||||||
|
except DynamicApiError as exc:
|
||||||
|
self.display.debug(exc)
|
||||||
|
raise K8sInventoryException(
|
||||||
|
"Error fetching Pod list: %s" % format_dynamic_api_exc(exc)
|
||||||
|
)
|
||||||
|
|
||||||
|
namespace_group = "namespace_{0}".format(namespace)
|
||||||
|
namespace_pods_group = "{0}_pods".format(namespace_group)
|
||||||
|
|
||||||
|
self.inventory.add_group(name)
|
||||||
|
self.inventory.add_group(namespace_group)
|
||||||
|
self.inventory.add_child(name, namespace_group)
|
||||||
|
self.inventory.add_group(namespace_pods_group)
|
||||||
|
self.inventory.add_child(namespace_group, namespace_pods_group)
|
||||||
|
|
||||||
|
for pod in obj.items:
|
||||||
|
pod_name = pod.metadata.name
|
||||||
|
pod_groups = []
|
||||||
|
pod_annotations = (
|
||||||
|
{} if not pod.metadata.annotations else dict(pod.metadata.annotations)
|
||||||
|
)
|
||||||
|
|
||||||
|
if pod.metadata.labels:
|
||||||
|
# create a group for each label_value
|
||||||
|
for key, value in pod.metadata.labels:
|
||||||
|
group_name = "label_{0}_{1}".format(key, value)
|
||||||
|
if group_name not in pod_groups:
|
||||||
|
pod_groups.append(group_name)
|
||||||
|
self.inventory.add_group(group_name)
|
||||||
|
pod_labels = dict(pod.metadata.labels)
|
||||||
|
else:
|
||||||
|
pod_labels = {}
|
||||||
|
|
||||||
|
if not pod.status.containerStatuses:
|
||||||
|
continue
|
||||||
|
|
||||||
|
for container in pod.status.containerStatuses:
|
||||||
|
# add each pod_container to the namespace group, and to each label_value group
|
||||||
|
container_name = "{0}_{1}".format(pod.metadata.name, container.name)
|
||||||
|
self.inventory.add_host(container_name)
|
||||||
|
self.inventory.add_child(namespace_pods_group, container_name)
|
||||||
|
if pod_groups:
|
||||||
|
for group in pod_groups:
|
||||||
|
self.inventory.add_child(group, container_name)
|
||||||
|
|
||||||
|
# Add hostvars
|
||||||
|
self.inventory.set_variable(container_name, "object_type", "pod")
|
||||||
|
self.inventory.set_variable(container_name, "labels", pod_labels)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "annotations", pod_annotations
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "cluster_name", pod.metadata.clusterName
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "pod_node_name", pod.spec.nodeName
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(container_name, "pod_name", pod.spec.name)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "pod_host_ip", pod.status.hostIP
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "pod_phase", pod.status.phase
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(container_name, "pod_ip", pod.status.podIP)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "pod_self_link", pod.metadata.selfLink
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "pod_resource_version", pod.metadata.resourceVersion
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(container_name, "pod_uid", pod.metadata.uid)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "container_name", container.image
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "container_image", container.image
|
||||||
|
)
|
||||||
|
if container.state.running:
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "container_state", "Running"
|
||||||
|
)
|
||||||
|
if container.state.terminated:
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "container_state", "Terminated"
|
||||||
|
)
|
||||||
|
if container.state.waiting:
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "container_state", "Waiting"
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "container_ready", container.ready
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "ansible_remote_tmp", "/tmp/"
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "ansible_connection", self.connection_plugin
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name, "ansible_{0}_pod".format(self.transport), pod_name
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name,
|
||||||
|
"ansible_{0}_container".format(self.transport),
|
||||||
|
container.name,
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
container_name,
|
||||||
|
"ansible_{0}_namespace".format(self.transport),
|
||||||
|
namespace,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_services_for_namespace(self, client, name, namespace):
|
||||||
|
v1_service = client.resources.get(api_version="v1", kind="Service")
|
||||||
|
try:
|
||||||
|
obj = v1_service.get(namespace=namespace)
|
||||||
|
except DynamicApiError as exc:
|
||||||
|
self.display.debug(exc)
|
||||||
|
raise K8sInventoryException(
|
||||||
|
"Error fetching Service list: %s" % format_dynamic_api_exc(exc)
|
||||||
|
)
|
||||||
|
|
||||||
|
namespace_group = "namespace_{0}".format(namespace)
|
||||||
|
namespace_services_group = "{0}_services".format(namespace_group)
|
||||||
|
|
||||||
|
self.inventory.add_group(name)
|
||||||
|
self.inventory.add_group(namespace_group)
|
||||||
|
self.inventory.add_child(name, namespace_group)
|
||||||
|
self.inventory.add_group(namespace_services_group)
|
||||||
|
self.inventory.add_child(namespace_group, namespace_services_group)
|
||||||
|
|
||||||
|
for service in obj.items:
|
||||||
|
service_name = service.metadata.name
|
||||||
|
service_labels = (
|
||||||
|
{} if not service.metadata.labels else dict(service.metadata.labels)
|
||||||
|
)
|
||||||
|
service_annotations = (
|
||||||
|
{}
|
||||||
|
if not service.metadata.annotations
|
||||||
|
else dict(service.metadata.annotations)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.inventory.add_host(service_name)
|
||||||
|
|
||||||
|
if service.metadata.labels:
|
||||||
|
# create a group for each label_value
|
||||||
|
for key, value in service.metadata.labels:
|
||||||
|
group_name = "label_{0}_{1}".format(key, value)
|
||||||
|
self.inventory.add_group(group_name)
|
||||||
|
self.inventory.add_child(group_name, service_name)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.inventory.add_child(namespace_services_group, service_name)
|
||||||
|
except AnsibleError:
|
||||||
|
raise
|
||||||
|
|
||||||
|
ports = [
|
||||||
|
{
|
||||||
|
"name": port.name,
|
||||||
|
"port": port.port,
|
||||||
|
"protocol": port.protocol,
|
||||||
|
"targetPort": port.targetPort,
|
||||||
|
"nodePort": port.nodePort,
|
||||||
|
}
|
||||||
|
for port in service.spec.ports or []
|
||||||
|
]
|
||||||
|
|
||||||
|
# add hostvars
|
||||||
|
self.inventory.set_variable(service_name, "object_type", "service")
|
||||||
|
self.inventory.set_variable(service_name, "labels", service_labels)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
service_name, "annotations", service_annotations
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
service_name, "cluster_name", service.metadata.clusterName
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(service_name, "ports", ports)
|
||||||
|
self.inventory.set_variable(service_name, "type", service.spec.type)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
service_name, "self_link", service.metadata.selfLink
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(
|
||||||
|
service_name, "resource_version", service.metadata.resourceVersion
|
||||||
|
)
|
||||||
|
self.inventory.set_variable(service_name, "uid", service.metadata.uid)
|
||||||
|
|
||||||
|
if service.spec.externalTrafficPolicy:
|
||||||
|
self.inventory.set_variable(
|
||||||
|
service_name,
|
||||||
|
"external_traffic_policy",
|
||||||
|
service.spec.externalTrafficPolicy,
|
||||||
|
)
|
||||||
|
if service.spec.externalIPs:
|
||||||
|
self.inventory.set_variable(
|
||||||
|
service_name, "external_ips", service.spec.externalIPs
|
||||||
|
)
|
||||||
|
|
||||||
|
if service.spec.externalName:
|
||||||
|
self.inventory.set_variable(
|
||||||
|
service_name, "external_name", service.spec.externalName
|
||||||
|
)
|
||||||
|
|
||||||
|
if service.spec.healthCheckNodePort:
|
||||||
|
self.inventory.set_variable(
|
||||||
|
service_name,
|
||||||
|
"health_check_node_port",
|
||||||
|
service.spec.healthCheckNodePort,
|
||||||
|
)
|
||||||
|
if service.spec.loadBalancerIP:
|
||||||
|
self.inventory.set_variable(
|
||||||
|
service_name, "load_balancer_ip", service.spec.loadBalancerIP
|
||||||
|
)
|
||||||
|
if service.spec.selector:
|
||||||
|
self.inventory.set_variable(
|
||||||
|
service_name, "selector", dict(service.spec.selector)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
hasattr(service.status.loadBalancer, "ingress")
|
||||||
|
and service.status.loadBalancer.ingress
|
||||||
|
):
|
||||||
|
load_balancer = [
|
||||||
|
{"hostname": ingress.hostname, "ip": ingress.ip}
|
||||||
|
for ingress in service.status.loadBalancer.ingress
|
||||||
|
]
|
||||||
|
self.inventory.set_variable(
|
||||||
|
service_name, "load_balancer", load_balancer
|
||||||
|
)
|
||||||
@@ -34,13 +34,6 @@ DOCUMENTATION = """
|
|||||||
description:
|
description:
|
||||||
- Enable the helm chart inflation generator
|
- Enable the helm chart inflation generator
|
||||||
default: "False"
|
default: "False"
|
||||||
environment:
|
|
||||||
description:
|
|
||||||
- The environment variables to pass to the kustomize or kubectl command.
|
|
||||||
- This can be a dictionary or a string in the format key=value, multiple pairs separated by space.
|
|
||||||
type: raw
|
|
||||||
default: {}
|
|
||||||
version_added: 6.2.0
|
|
||||||
|
|
||||||
requirements:
|
requirements:
|
||||||
- "python >= 3.6"
|
- "python >= 3.6"
|
||||||
@@ -62,14 +55,6 @@ EXAMPLES = """
|
|||||||
- name: Create kubernetes resources for lookup output with `--enable-helm` set
|
- name: Create kubernetes resources for lookup output with `--enable-helm` set
|
||||||
kubernetes.core.k8s:
|
kubernetes.core.k8s:
|
||||||
definition: "{{ lookup('kubernetes.core.kustomize', dir='/path/to/kustomization', enable_helm=True) }}"
|
definition: "{{ lookup('kubernetes.core.kustomize', dir='/path/to/kustomization', enable_helm=True) }}"
|
||||||
|
|
||||||
- name: Create kubernetes resources for lookup output with environment variables in string format
|
|
||||||
kubernetes.core.k8s:
|
|
||||||
definition: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kubectl', environment='HTTP_PROXY=http://proxy.example.com:3128') }}"
|
|
||||||
|
|
||||||
- name: Create kubernetes resources for lookup output with environment variables in dict format
|
|
||||||
kubernetes.core.k8s:
|
|
||||||
definition: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kubectl', environment={'HTTP_PROXY': 'http://proxy.example.com:3128'}) }}"
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
RETURN = """
|
RETURN = """
|
||||||
@@ -87,7 +72,6 @@ RETURN = """
|
|||||||
key1: val1
|
key1: val1
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from ansible.errors import AnsibleLookupError
|
from ansible.errors import AnsibleLookupError
|
||||||
@@ -108,10 +92,8 @@ def get_binary_from_path(name, opt_dirs=None):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def run_command(command, environ=None):
|
def run_command(command):
|
||||||
cmd = subprocess.Popen(
|
cmd = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=environ
|
|
||||||
)
|
|
||||||
stdout, stderr = cmd.communicate()
|
stdout, stderr = cmd.communicate()
|
||||||
return cmd.returncode, stdout, stderr
|
return cmd.returncode, stdout, stderr
|
||||||
|
|
||||||
@@ -125,7 +107,6 @@ class LookupModule(LookupBase):
|
|||||||
binary_path=None,
|
binary_path=None,
|
||||||
opt_dirs=None,
|
opt_dirs=None,
|
||||||
enable_helm=False,
|
enable_helm=False,
|
||||||
environment=None,
|
|
||||||
**kwargs
|
**kwargs
|
||||||
):
|
):
|
||||||
executable_path = binary_path
|
executable_path = binary_path
|
||||||
@@ -160,21 +141,7 @@ class LookupModule(LookupBase):
|
|||||||
if enable_helm:
|
if enable_helm:
|
||||||
command += ["--enable-helm"]
|
command += ["--enable-helm"]
|
||||||
|
|
||||||
environ = None
|
(ret, out, err) = run_command(command)
|
||||||
if environment:
|
|
||||||
environ = os.environ.copy()
|
|
||||||
if isinstance(environment, str):
|
|
||||||
if not all(env.count("=") == 1 for env in environment.split(" ")):
|
|
||||||
raise AnsibleLookupError(
|
|
||||||
"environment should be dict or string in the format key=value, multiple pairs separated by space"
|
|
||||||
)
|
|
||||||
for env in environment.split(" "):
|
|
||||||
key, value = env.split("=")
|
|
||||||
environ[key] = value
|
|
||||||
if isinstance(environment, dict):
|
|
||||||
environ.update(environment)
|
|
||||||
|
|
||||||
(ret, out, err) = run_command(command, environ=environ)
|
|
||||||
if ret != 0:
|
if ret != 0:
|
||||||
if err:
|
if err:
|
||||||
raise AnsibleLookupError(
|
raise AnsibleLookupError(
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import base64
|
|||||||
import os
|
import os
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
|
|
||||||
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
|
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||||
from ansible.module_utils.urls import Request
|
from ansible.module_utils.urls import Request
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ from abc import ABCMeta, abstractmethod
|
|||||||
from select import select
|
from select import select
|
||||||
from tempfile import NamedTemporaryFile, TemporaryFile
|
from tempfile import NamedTemporaryFile, TemporaryFile
|
||||||
|
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils._text import to_native
|
||||||
|
|
||||||
# from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import AnsibleModule
|
# from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import AnsibleModule
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.exceptions import (
|
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.exceptions import (
|
||||||
|
|||||||
@@ -40,20 +40,16 @@ def parse_helm_plugin_list(output=None):
|
|||||||
if not output:
|
if not output:
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
parsing_grammar = None
|
|
||||||
for line in output:
|
for line in output:
|
||||||
if line.startswith("NAME"):
|
if line.startswith("NAME"):
|
||||||
parsing_grammar = [s.strip().lower() for s in line.split("\t")]
|
|
||||||
continue
|
continue
|
||||||
if parsing_grammar is None:
|
name, version, description = line.split("\t", 3)
|
||||||
|
name = name.strip()
|
||||||
|
version = version.strip()
|
||||||
|
description = description.strip()
|
||||||
|
if name == "":
|
||||||
continue
|
continue
|
||||||
plugin = {
|
ret.append((name, version, description))
|
||||||
parsing_grammar[i]: v.strip()
|
|
||||||
for i, v in enumerate(line.split("\t", len(parsing_grammar)))
|
|
||||||
}
|
|
||||||
if plugin["name"] == "":
|
|
||||||
continue
|
|
||||||
ret.append(plugin)
|
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@@ -206,35 +202,21 @@ class AnsibleHelmModule(object):
|
|||||||
return m.group(1)
|
return m.group(1)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def is_helm_v4(self):
|
def validate_helm_version(self):
|
||||||
helm_version = self.get_helm_version()
|
|
||||||
if helm_version is None:
|
|
||||||
return False
|
|
||||||
return LooseVersion(helm_version) >= LooseVersion("4.0.0")
|
|
||||||
|
|
||||||
def is_helm_version_compatible_with_helm_diff(self, helm_diff_version):
|
|
||||||
"""
|
"""
|
||||||
Return true if the helm version is compatible with the helm diff version
|
Validate that Helm version is >=3.0.0 and <4.0.0.
|
||||||
Helm v4 requires helm diff v3.14.0
|
Helm 4 is not yet supported.
|
||||||
"""
|
|
||||||
if not helm_diff_version:
|
|
||||||
return False
|
|
||||||
if self.is_helm_v4():
|
|
||||||
return LooseVersion(helm_diff_version) >= LooseVersion("3.14.0")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def validate_helm_version(self, version="3.0.0"):
|
|
||||||
"""
|
|
||||||
Validate that Helm version is >= version (default version=3.0.0).
|
|
||||||
"""
|
"""
|
||||||
helm_version = self.get_helm_version()
|
helm_version = self.get_helm_version()
|
||||||
if helm_version is None:
|
if helm_version is None:
|
||||||
self.fail_json(msg="Unable to determine Helm version")
|
self.fail_json(msg="Unable to determine Helm version")
|
||||||
|
|
||||||
if LooseVersion(helm_version) < LooseVersion(version):
|
if (LooseVersion(helm_version) < LooseVersion("3.0.0")) or (
|
||||||
|
LooseVersion(helm_version) >= LooseVersion("4.0.0")
|
||||||
|
):
|
||||||
self.fail_json(
|
self.fail_json(
|
||||||
msg="Helm version must be >= {0}, current version is {1}".format(
|
msg="Helm version must be >=3.0.0,<4.0.0, current version is {0}".format(
|
||||||
version, helm_version
|
helm_version
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils._text import to_native
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
|
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
|
||||||
get_api_client,
|
get_api_client,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
# Copyright (c) Ansible Project
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
|
|
||||||
from __future__ import absolute_import, division, print_function
|
|
||||||
|
|
||||||
__metaclass__ = type
|
|
||||||
|
|
||||||
import hashlib
|
|
||||||
import os
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
try:
|
|
||||||
import yaml
|
|
||||||
|
|
||||||
IMP_YAML = True
|
|
||||||
IMP_YAML_ERR = None
|
|
||||||
except ImportError:
|
|
||||||
IMP_YAML = False
|
|
||||||
IMP_YAML_ERR = traceback.format_exc()
|
|
||||||
|
|
||||||
|
|
||||||
def load_yaml_file(path):
|
|
||||||
if not path or not os.path.exists(path):
|
|
||||||
return {}
|
|
||||||
with open(path, "r") as f:
|
|
||||||
return yaml.safe_load(f) or {}
|
|
||||||
|
|
||||||
|
|
||||||
def deep_merge(base, updates):
|
|
||||||
result = base.copy()
|
|
||||||
for key, value in updates.items():
|
|
||||||
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
|
|
||||||
result[key] = deep_merge(result[key], value)
|
|
||||||
else:
|
|
||||||
result[key] = value
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def merge_by_name(existing, new):
|
|
||||||
merged = {}
|
|
||||||
for item in existing:
|
|
||||||
if isinstance(item, dict) and "name" in item:
|
|
||||||
merged[item["name"]] = item
|
|
||||||
|
|
||||||
for item in new:
|
|
||||||
if not isinstance(item, dict) or "name" not in item:
|
|
||||||
continue
|
|
||||||
|
|
||||||
name = item["name"]
|
|
||||||
behavior = item.get("behavior", "merge")
|
|
||||||
item_copy = {k: v for k, v in item.items() if k != "behavior"}
|
|
||||||
|
|
||||||
if name in merged:
|
|
||||||
if behavior == "keep":
|
|
||||||
continue
|
|
||||||
elif behavior == "replace":
|
|
||||||
merged[name] = item_copy
|
|
||||||
else:
|
|
||||||
result = {"name": name}
|
|
||||||
for key in ["cluster", "user", "context"]:
|
|
||||||
if key in merged[name] or key in item_copy:
|
|
||||||
existing_config = merged[name].get(key, {})
|
|
||||||
new_config = item_copy.get(key, {})
|
|
||||||
result[key] = deep_merge(existing_config, new_config)
|
|
||||||
for key in merged[name]:
|
|
||||||
if key not in ["name", "cluster", "user", "context"]:
|
|
||||||
result[key] = merged[name][key]
|
|
||||||
for key in item_copy:
|
|
||||||
if (
|
|
||||||
key not in ["name", "cluster", "user", "context"]
|
|
||||||
and key not in result
|
|
||||||
):
|
|
||||||
result[key] = item_copy[key]
|
|
||||||
merged[name] = result
|
|
||||||
else:
|
|
||||||
merged[name] = item_copy
|
|
||||||
|
|
||||||
return list(merged.values())
|
|
||||||
|
|
||||||
|
|
||||||
def hash_data(data):
|
|
||||||
"""Generate SHA-256 hash for idempotency checking."""
|
|
||||||
return hashlib.sha256(yaml.safe_dump(data, sort_keys=True).encode()).hexdigest()
|
|
||||||
|
|
||||||
|
|
||||||
def write_file(dest, data):
|
|
||||||
if not dest:
|
|
||||||
return False
|
|
||||||
with open(dest, "w") as f:
|
|
||||||
yaml.safe_dump(data, f, sort_keys=False)
|
|
||||||
return True
|
|
||||||
@@ -21,7 +21,7 @@ author:
|
|||||||
- Matthieu Diehr (@d-matt)
|
- Matthieu Diehr (@d-matt)
|
||||||
|
|
||||||
requirements:
|
requirements:
|
||||||
- "helm >= 3.0.0 (https://github.com/helm/helm/releases)"
|
- "helm (https://github.com/helm/helm/releases)"
|
||||||
- "yaml (https://pypi.org/project/PyYAML/)"
|
- "yaml (https://pypi.org/project/PyYAML/)"
|
||||||
|
|
||||||
description:
|
description:
|
||||||
@@ -237,27 +237,6 @@ options:
|
|||||||
default: False
|
default: False
|
||||||
aliases: [ skip_tls_certs_check ]
|
aliases: [ skip_tls_certs_check ]
|
||||||
version_added: 5.3.0
|
version_added: 5.3.0
|
||||||
plain_http:
|
|
||||||
description:
|
|
||||||
- Use HTTP instead of HTTPS when working with OCI registries
|
|
||||||
- Requires Helm >= 3.13.0
|
|
||||||
type: bool
|
|
||||||
default: False
|
|
||||||
version_added: 6.1.0
|
|
||||||
take_ownership:
|
|
||||||
description:
|
|
||||||
- Helm will ignore the check for helm annotations and take ownership of the existing resources
|
|
||||||
- This feature requires helm >= 3.17.0
|
|
||||||
type: bool
|
|
||||||
default: False
|
|
||||||
version_added: 6.1.0
|
|
||||||
skip_schema_validation:
|
|
||||||
description:
|
|
||||||
- Disables JSON schema validation for Chart and values.
|
|
||||||
- This feature requires helm >= 3.16.0
|
|
||||||
type: bool
|
|
||||||
default: False
|
|
||||||
version_added: 6.2.0
|
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
- kubernetes.core.helm_common_options
|
- kubernetes.core.helm_common_options
|
||||||
"""
|
"""
|
||||||
@@ -340,12 +319,6 @@ EXAMPLES = r"""
|
|||||||
chart_ref: "https://github.com/grafana/helm-charts/releases/download/grafana-5.6.0/grafana-5.6.0.tgz"
|
chart_ref: "https://github.com/grafana/helm-charts/releases/download/grafana-5.6.0/grafana-5.6.0.tgz"
|
||||||
release_namespace: monitoring
|
release_namespace: monitoring
|
||||||
|
|
||||||
- name: Deploy Bitnami's MongoDB latest chart from OCI registry
|
|
||||||
kubernetes.core.helm:
|
|
||||||
name: test
|
|
||||||
chart_ref: "oci://registry-1.docker.io/bitnamicharts/mongodb"
|
|
||||||
release_namespace: database
|
|
||||||
|
|
||||||
# Using complex Values
|
# Using complex Values
|
||||||
- name: Deploy new-relic client chart
|
- name: Deploy new-relic client chart
|
||||||
kubernetes.core.helm:
|
kubernetes.core.helm:
|
||||||
@@ -500,13 +473,9 @@ def get_release_status(module, release_name, all_status=False):
|
|||||||
"--filter",
|
"--filter",
|
||||||
release_name,
|
release_name,
|
||||||
]
|
]
|
||||||
if all_status and not module.is_helm_v4():
|
if all_status:
|
||||||
# --all has been removed from `helm list` command on helm v4
|
|
||||||
list_command.append("--all")
|
list_command.append("--all")
|
||||||
elif not all_status:
|
|
||||||
# The default behavior to display only deployed releases has been removed from
|
|
||||||
# Helm v4
|
|
||||||
list_command.append("--deployed")
|
|
||||||
rc, out, err = module.run_helm_command(list_command)
|
rc, out, err = module.run_helm_command(list_command)
|
||||||
|
|
||||||
release = get_release(yaml.safe_load(out), release_name)
|
release = get_release(yaml.safe_load(out), release_name)
|
||||||
@@ -536,9 +505,7 @@ def run_dep_update(module, chart_ref):
|
|||||||
rc, out, err = module.run_helm_command(dep_update)
|
rc, out, err = module.run_helm_command(dep_update)
|
||||||
|
|
||||||
|
|
||||||
def fetch_chart_info(
|
def fetch_chart_info(module, command, chart_ref, insecure_skip_tls_verify=False):
|
||||||
module, command, chart_ref, insecure_skip_tls_verify=False, plain_http=False
|
|
||||||
):
|
|
||||||
"""
|
"""
|
||||||
Get chart info
|
Get chart info
|
||||||
"""
|
"""
|
||||||
@@ -547,17 +514,6 @@ def fetch_chart_info(
|
|||||||
if insecure_skip_tls_verify:
|
if insecure_skip_tls_verify:
|
||||||
inspect_command += " --insecure-skip-tls-verify"
|
inspect_command += " --insecure-skip-tls-verify"
|
||||||
|
|
||||||
if plain_http:
|
|
||||||
helm_version = module.get_helm_version()
|
|
||||||
if LooseVersion(helm_version) < LooseVersion("3.13.0"):
|
|
||||||
module.fail_json(
|
|
||||||
msg="plain_http requires helm >= 3.13.0, current version is {0}".format(
|
|
||||||
helm_version
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
inspect_command += " --plain-http"
|
|
||||||
|
|
||||||
rc, out, err = module.run_helm_command(inspect_command)
|
rc, out, err = module.run_helm_command(inspect_command)
|
||||||
|
|
||||||
return yaml.safe_load(out)
|
return yaml.safe_load(out)
|
||||||
@@ -587,9 +543,6 @@ def deploy(
|
|||||||
reset_values=True,
|
reset_values=True,
|
||||||
reset_then_reuse_values=False,
|
reset_then_reuse_values=False,
|
||||||
insecure_skip_tls_verify=False,
|
insecure_skip_tls_verify=False,
|
||||||
plain_http=False,
|
|
||||||
take_ownership=False,
|
|
||||||
skip_schema_validation=False,
|
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Install/upgrade/rollback release chart
|
Install/upgrade/rollback release chart
|
||||||
@@ -603,8 +556,6 @@ def deploy(
|
|||||||
deploy_command = command + " upgrade -i" # install/upgrade
|
deploy_command = command + " upgrade -i" # install/upgrade
|
||||||
if reset_values:
|
if reset_values:
|
||||||
deploy_command += " --reset-values"
|
deploy_command += " --reset-values"
|
||||||
if take_ownership:
|
|
||||||
deploy_command += " --take-ownership"
|
|
||||||
|
|
||||||
if reuse_values is not None:
|
if reuse_values is not None:
|
||||||
deploy_command += " --reuse-values=" + str(reuse_values)
|
deploy_command += " --reuse-values=" + str(reuse_values)
|
||||||
@@ -654,9 +605,6 @@ def deploy(
|
|||||||
else:
|
else:
|
||||||
deploy_command += " --insecure-skip-tls-verify"
|
deploy_command += " --insecure-skip-tls-verify"
|
||||||
|
|
||||||
if plain_http:
|
|
||||||
deploy_command += " --plain-http"
|
|
||||||
|
|
||||||
if values_files:
|
if values_files:
|
||||||
for value_file in values_files:
|
for value_file in values_files:
|
||||||
deploy_command += " --values=" + value_file
|
deploy_command += " --values=" + value_file
|
||||||
@@ -680,17 +628,6 @@ def deploy(
|
|||||||
if set_value_args:
|
if set_value_args:
|
||||||
deploy_command += " " + set_value_args
|
deploy_command += " " + set_value_args
|
||||||
|
|
||||||
if skip_schema_validation:
|
|
||||||
helm_version = module.get_helm_version()
|
|
||||||
if LooseVersion(helm_version) < LooseVersion("3.16.0"):
|
|
||||||
module.fail_json(
|
|
||||||
msg="skip_schema_validation requires helm >= 3.16.0, current version is {0}".format(
|
|
||||||
helm_version
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
deploy_command += " --skip-schema-validation"
|
|
||||||
|
|
||||||
deploy_command += " " + release_name + f" '{chart_name}'"
|
deploy_command += " " + release_name + f" '{chart_name}'"
|
||||||
return deploy_command
|
return deploy_command
|
||||||
|
|
||||||
@@ -743,8 +680,8 @@ def get_plugin_version(plugin):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
for line in out:
|
for line in out:
|
||||||
if line["name"] == plugin:
|
if line[0] == plugin:
|
||||||
return line["version"]
|
return line[1]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -763,8 +700,6 @@ def helmdiff_check(
|
|||||||
reset_values=True,
|
reset_values=True,
|
||||||
reset_then_reuse_values=False,
|
reset_then_reuse_values=False,
|
||||||
insecure_skip_tls_verify=False,
|
insecure_skip_tls_verify=False,
|
||||||
plain_http=False,
|
|
||||||
skip_schema_validation=False,
|
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Use helm diff to determine if a release would change by upgrading a chart.
|
Use helm diff to determine if a release would change by upgrading a chart.
|
||||||
@@ -820,28 +755,6 @@ def helmdiff_check(
|
|||||||
if insecure_skip_tls_verify:
|
if insecure_skip_tls_verify:
|
||||||
cmd += " --insecure-skip-tls-verify"
|
cmd += " --insecure-skip-tls-verify"
|
||||||
|
|
||||||
if skip_schema_validation:
|
|
||||||
helm_version = module.get_helm_version()
|
|
||||||
if LooseVersion(helm_version) < LooseVersion("3.16.0"):
|
|
||||||
module.fail_json(
|
|
||||||
msg="skip_schema_validation requires helm >= 3.16.0, current version is {0}".format(
|
|
||||||
helm_version
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
cmd += " --skip-schema-validation"
|
|
||||||
|
|
||||||
if plain_http:
|
|
||||||
helm_version = module.get_helm_version()
|
|
||||||
if LooseVersion(helm_version) < LooseVersion("3.13.0"):
|
|
||||||
module.fail_json(
|
|
||||||
msg="plain_http requires helm >= 3.13.0, current version is {0}".format(
|
|
||||||
helm_version
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
cmd += " --plain-http"
|
|
||||||
|
|
||||||
rc, out, err = module.run_helm_command(cmd)
|
rc, out, err = module.run_helm_command(cmd)
|
||||||
return (len(out.strip()) > 0, out.strip())
|
return (len(out.strip()) > 0, out.strip())
|
||||||
|
|
||||||
@@ -905,9 +818,6 @@ def argument_spec():
|
|||||||
insecure_skip_tls_verify=dict(
|
insecure_skip_tls_verify=dict(
|
||||||
type="bool", default=False, aliases=["skip_tls_certs_check"]
|
type="bool", default=False, aliases=["skip_tls_certs_check"]
|
||||||
),
|
),
|
||||||
plain_http=dict(type="bool", default=False),
|
|
||||||
take_ownership=dict(type="bool", default=False),
|
|
||||||
skip_schema_validation=dict(type="bool", default=False),
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return arg_spec
|
return arg_spec
|
||||||
@@ -932,7 +842,7 @@ def main():
|
|||||||
if not IMP_YAML:
|
if not IMP_YAML:
|
||||||
module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR)
|
module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR)
|
||||||
|
|
||||||
# Validate Helm version >=3.0.0
|
# Validate Helm version >=3.0.0,<4.0.0
|
||||||
module.validate_helm_version()
|
module.validate_helm_version()
|
||||||
|
|
||||||
changed = False
|
changed = False
|
||||||
@@ -965,9 +875,6 @@ def main():
|
|||||||
reset_values = module.params.get("reset_values")
|
reset_values = module.params.get("reset_values")
|
||||||
reset_then_reuse_values = module.params.get("reset_then_reuse_values")
|
reset_then_reuse_values = module.params.get("reset_then_reuse_values")
|
||||||
insecure_skip_tls_verify = module.params.get("insecure_skip_tls_verify")
|
insecure_skip_tls_verify = module.params.get("insecure_skip_tls_verify")
|
||||||
plain_http = module.params.get("plain_http")
|
|
||||||
take_ownership = module.params.get("take_ownership")
|
|
||||||
skip_schema_validation = module.params.get("skip_schema_validation")
|
|
||||||
|
|
||||||
if update_repo_cache:
|
if update_repo_cache:
|
||||||
run_repo_update(module)
|
run_repo_update(module)
|
||||||
@@ -977,33 +884,6 @@ def main():
|
|||||||
release_status = get_release_status(module, release_name, all_status=all_status)
|
release_status = get_release_status(module, release_name, all_status=all_status)
|
||||||
|
|
||||||
helm_cmd = module.get_helm_binary()
|
helm_cmd = module.get_helm_binary()
|
||||||
|
|
||||||
if plain_http:
|
|
||||||
helm_version = module.get_helm_version()
|
|
||||||
if LooseVersion(helm_version) < LooseVersion("3.13.0"):
|
|
||||||
module.fail_json(
|
|
||||||
msg="plain_http requires helm >= 3.13.0, current version is {0}".format(
|
|
||||||
helm_version
|
|
||||||
)
|
|
||||||
)
|
|
||||||
if take_ownership:
|
|
||||||
helm_version = module.get_helm_version()
|
|
||||||
if LooseVersion(helm_version) < LooseVersion("3.17.0"):
|
|
||||||
module.fail_json(
|
|
||||||
msg="take_ownership requires helm >= 3.17.0, current version is {0}".format(
|
|
||||||
helm_version
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if skip_schema_validation:
|
|
||||||
helm_version = module.get_helm_version()
|
|
||||||
if LooseVersion(helm_version) < LooseVersion("3.16.0"):
|
|
||||||
module.fail_json(
|
|
||||||
msg="skip_schema_validation requires helm >= 3.16.0, current version is {0}".format(
|
|
||||||
helm_version
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
opt_result = {}
|
opt_result = {}
|
||||||
if release_state == "absent" and release_status is not None:
|
if release_state == "absent" and release_status is not None:
|
||||||
# skip release statuses 'uninstalled' and 'uninstalling'
|
# skip release statuses 'uninstalled' and 'uninstalling'
|
||||||
@@ -1014,7 +894,8 @@ def main():
|
|||||||
if wait:
|
if wait:
|
||||||
helm_version = module.get_helm_version()
|
helm_version = module.get_helm_version()
|
||||||
if LooseVersion(helm_version) < LooseVersion("3.7.0"):
|
if LooseVersion(helm_version) < LooseVersion("3.7.0"):
|
||||||
module.warn(
|
opt_result["warnings"] = []
|
||||||
|
opt_result["warnings"].append(
|
||||||
"helm uninstall support option --wait for helm release >= 3.7.0"
|
"helm uninstall support option --wait for helm release >= 3.7.0"
|
||||||
)
|
)
|
||||||
wait = False
|
wait = False
|
||||||
@@ -1032,7 +913,7 @@ def main():
|
|||||||
|
|
||||||
# Fetch chart info to have real version and real name for chart_ref from archive, folder or url
|
# Fetch chart info to have real version and real name for chart_ref from archive, folder or url
|
||||||
chart_info = fetch_chart_info(
|
chart_info = fetch_chart_info(
|
||||||
module, helm_cmd, chart_ref, insecure_skip_tls_verify, plain_http
|
module, helm_cmd, chart_ref, insecure_skip_tls_verify
|
||||||
)
|
)
|
||||||
|
|
||||||
if dependency_update:
|
if dependency_update:
|
||||||
@@ -1094,29 +975,19 @@ def main():
|
|||||||
reset_values=reset_values,
|
reset_values=reset_values,
|
||||||
reset_then_reuse_values=reset_then_reuse_values,
|
reset_then_reuse_values=reset_then_reuse_values,
|
||||||
insecure_skip_tls_verify=insecure_skip_tls_verify,
|
insecure_skip_tls_verify=insecure_skip_tls_verify,
|
||||||
plain_http=plain_http,
|
|
||||||
take_ownership=take_ownership,
|
|
||||||
skip_schema_validation=skip_schema_validation,
|
|
||||||
)
|
)
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
else:
|
else:
|
||||||
helm_diff_version = get_plugin_version("diff")
|
helm_diff_version = get_plugin_version("diff")
|
||||||
helm_version_compatible = module.is_helm_version_compatible_with_helm_diff(
|
if helm_diff_version and (
|
||||||
helm_diff_version
|
|
||||||
)
|
|
||||||
if (
|
|
||||||
helm_diff_version
|
|
||||||
and helm_version_compatible
|
|
||||||
and (
|
|
||||||
not chart_repo_url
|
not chart_repo_url
|
||||||
or (
|
or (
|
||||||
chart_repo_url
|
chart_repo_url
|
||||||
and LooseVersion(helm_diff_version) >= LooseVersion("3.4.1")
|
and LooseVersion(helm_diff_version) >= LooseVersion("3.4.1")
|
||||||
)
|
)
|
||||||
)
|
|
||||||
):
|
):
|
||||||
would_change, prepared = helmdiff_check(
|
(would_change, prepared) = helmdiff_check(
|
||||||
module,
|
module,
|
||||||
release_name,
|
release_name,
|
||||||
chart_ref,
|
chart_ref,
|
||||||
@@ -1131,19 +1002,9 @@ def main():
|
|||||||
reset_values=reset_values,
|
reset_values=reset_values,
|
||||||
reset_then_reuse_values=reset_then_reuse_values,
|
reset_then_reuse_values=reset_then_reuse_values,
|
||||||
insecure_skip_tls_verify=insecure_skip_tls_verify,
|
insecure_skip_tls_verify=insecure_skip_tls_verify,
|
||||||
plain_http=plain_http,
|
|
||||||
skip_schema_validation=skip_schema_validation,
|
|
||||||
)
|
)
|
||||||
if would_change and module._diff:
|
if would_change and module._diff:
|
||||||
opt_result["diff"] = {"prepared": prepared}
|
opt_result["diff"] = {"prepared": prepared}
|
||||||
else:
|
|
||||||
if helm_diff_version and not helm_version_compatible:
|
|
||||||
module.warn(
|
|
||||||
"Idempotency checks are currently disabled due to a version mismatch."
|
|
||||||
f" Helm version {module.get_helm_version()} requires helm-diff >= 3.14.0,"
|
|
||||||
f" but the environment is currently running {helm_diff_version}."
|
|
||||||
" Please align the plugin versions to restore standard behavior."
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
module.warn(
|
module.warn(
|
||||||
"The default idempotency check can fail to report changes in certain cases. "
|
"The default idempotency check can fail to report changes in certain cases. "
|
||||||
@@ -1178,9 +1039,6 @@ def main():
|
|||||||
reset_values=reset_values,
|
reset_values=reset_values,
|
||||||
reset_then_reuse_values=reset_then_reuse_values,
|
reset_then_reuse_values=reset_then_reuse_values,
|
||||||
insecure_skip_tls_verify=insecure_skip_tls_verify,
|
insecure_skip_tls_verify=insecure_skip_tls_verify,
|
||||||
plain_http=plain_http,
|
|
||||||
take_ownership=take_ownership,
|
|
||||||
skip_schema_validation=skip_schema_validation,
|
|
||||||
)
|
)
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ author:
|
|||||||
- Lucas Boisserie (@LucasBoisserie)
|
- Lucas Boisserie (@LucasBoisserie)
|
||||||
|
|
||||||
requirements:
|
requirements:
|
||||||
- "helm >= 3.0.0 (https://github.com/helm/helm/releases)"
|
- "helm (https://github.com/helm/helm/releases)"
|
||||||
- "yaml (https://pypi.org/project/PyYAML/)"
|
- "yaml (https://pypi.org/project/PyYAML/)"
|
||||||
|
|
||||||
description:
|
description:
|
||||||
@@ -245,7 +245,7 @@ def main():
|
|||||||
if not IMP_YAML:
|
if not IMP_YAML:
|
||||||
module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR)
|
module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR)
|
||||||
|
|
||||||
# Validate Helm version >=3.0.0
|
# Validate Helm version >=3.0.0,<4.0.0
|
||||||
module.validate_helm_version()
|
module.validate_helm_version()
|
||||||
|
|
||||||
release_name = module.params.get("release_name")
|
release_name = module.params.get("release_name")
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ version_added: 1.0.0
|
|||||||
author:
|
author:
|
||||||
- Abhijeet Kasurde (@Akasurde)
|
- Abhijeet Kasurde (@Akasurde)
|
||||||
requirements:
|
requirements:
|
||||||
- "helm >= 3.0.0 (https://github.com/helm/helm/releases)"
|
- "helm (https://github.com/helm/helm/releases)"
|
||||||
description:
|
description:
|
||||||
- Manages Helm plugins.
|
- Manages Helm plugins.
|
||||||
options:
|
options:
|
||||||
@@ -48,14 +48,6 @@ options:
|
|||||||
required: false
|
required: false
|
||||||
type: str
|
type: str
|
||||||
version_added: 2.3.0
|
version_added: 2.3.0
|
||||||
verify:
|
|
||||||
description:
|
|
||||||
- Verify the plugin signature before installing.
|
|
||||||
- This option requires helm version >= 4.0.0
|
|
||||||
- Used with I(state=present).
|
|
||||||
type: bool
|
|
||||||
default: true
|
|
||||||
version_added: 6.4.0
|
|
||||||
extends_documentation_fragment:
|
extends_documentation_fragment:
|
||||||
- kubernetes.core.helm_common_options
|
- kubernetes.core.helm_common_options
|
||||||
"""
|
"""
|
||||||
@@ -126,9 +118,6 @@ from ansible_collections.kubernetes.core.plugins.module_utils.helm_args_common i
|
|||||||
HELM_AUTH_ARG_SPEC,
|
HELM_AUTH_ARG_SPEC,
|
||||||
HELM_AUTH_MUTUALLY_EXCLUSIVE,
|
HELM_AUTH_MUTUALLY_EXCLUSIVE,
|
||||||
)
|
)
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.version import (
|
|
||||||
LooseVersion,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def argument_spec():
|
def argument_spec():
|
||||||
@@ -149,10 +138,6 @@ def argument_spec():
|
|||||||
default="present",
|
default="present",
|
||||||
choices=["present", "absent", "latest"],
|
choices=["present", "absent", "latest"],
|
||||||
),
|
),
|
||||||
verify=dict(
|
|
||||||
type="bool",
|
|
||||||
default=True,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return arg_spec
|
return arg_spec
|
||||||
@@ -176,7 +161,7 @@ def main():
|
|||||||
mutually_exclusive=mutually_exclusive(),
|
mutually_exclusive=mutually_exclusive(),
|
||||||
)
|
)
|
||||||
|
|
||||||
# Validate helm version >= 3.0.0
|
# Validate Helm version >=3.0.0,<4.0.0
|
||||||
module.validate_helm_version()
|
module.validate_helm_version()
|
||||||
|
|
||||||
state = module.params.get("state")
|
state = module.params.get("state")
|
||||||
@@ -186,19 +171,8 @@ def main():
|
|||||||
if state == "present":
|
if state == "present":
|
||||||
helm_cmd_common += " install %s" % module.params.get("plugin_path")
|
helm_cmd_common += " install %s" % module.params.get("plugin_path")
|
||||||
plugin_version = module.params.get("plugin_version")
|
plugin_version = module.params.get("plugin_version")
|
||||||
verify = module.params.get("verify")
|
|
||||||
if plugin_version is not None:
|
if plugin_version is not None:
|
||||||
helm_cmd_common += " --version=%s" % plugin_version
|
helm_cmd_common += " --version=%s" % plugin_version
|
||||||
if not verify:
|
|
||||||
helm_version = module.get_helm_version()
|
|
||||||
if LooseVersion(helm_version) < LooseVersion("4.0.0"):
|
|
||||||
module.warn(
|
|
||||||
"verify parameter requires helm >= 4.0.0, current version is {0}".format(
|
|
||||||
helm_version
|
|
||||||
)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
helm_cmd_common += " --verify=false"
|
|
||||||
if not module.check_mode:
|
if not module.check_mode:
|
||||||
rc, out, err = module.run_helm_command(
|
rc, out, err = module.run_helm_command(
|
||||||
helm_cmd_common, fails_on_error=False
|
helm_cmd_common, fails_on_error=False
|
||||||
@@ -237,9 +211,9 @@ def main():
|
|||||||
elif state == "absent":
|
elif state == "absent":
|
||||||
plugin_name = module.params.get("plugin_name")
|
plugin_name = module.params.get("plugin_name")
|
||||||
rc, output, err, command = module.get_helm_plugin_list()
|
rc, output, err, command = module.get_helm_plugin_list()
|
||||||
plugins = parse_helm_plugin_list(output=output.splitlines())
|
out = parse_helm_plugin_list(output=output.splitlines())
|
||||||
|
|
||||||
if not plugins:
|
if not out:
|
||||||
module.exit_json(
|
module.exit_json(
|
||||||
failed=False,
|
failed=False,
|
||||||
changed=False,
|
changed=False,
|
||||||
@@ -250,7 +224,12 @@ def main():
|
|||||||
rc=rc,
|
rc=rc,
|
||||||
)
|
)
|
||||||
|
|
||||||
if all(plugin["name"] != plugin_name for plugin in plugins):
|
found = False
|
||||||
|
for line in out:
|
||||||
|
if line[0] == plugin_name:
|
||||||
|
found = True
|
||||||
|
break
|
||||||
|
if not found:
|
||||||
module.exit_json(
|
module.exit_json(
|
||||||
failed=False,
|
failed=False,
|
||||||
changed=False,
|
changed=False,
|
||||||
@@ -288,9 +267,9 @@ def main():
|
|||||||
elif state == "latest":
|
elif state == "latest":
|
||||||
plugin_name = module.params.get("plugin_name")
|
plugin_name = module.params.get("plugin_name")
|
||||||
rc, output, err, command = module.get_helm_plugin_list()
|
rc, output, err, command = module.get_helm_plugin_list()
|
||||||
plugins = parse_helm_plugin_list(output=output.splitlines())
|
out = parse_helm_plugin_list(output=output.splitlines())
|
||||||
|
|
||||||
if not plugins:
|
if not out:
|
||||||
module.exit_json(
|
module.exit_json(
|
||||||
failed=False,
|
failed=False,
|
||||||
changed=False,
|
changed=False,
|
||||||
@@ -301,7 +280,12 @@ def main():
|
|||||||
rc=rc,
|
rc=rc,
|
||||||
)
|
)
|
||||||
|
|
||||||
if all(plugin["name"] != plugin_name for plugin in plugins):
|
found = False
|
||||||
|
for line in out:
|
||||||
|
if line[0] == plugin_name:
|
||||||
|
found = True
|
||||||
|
break
|
||||||
|
if not found:
|
||||||
module.exit_json(
|
module.exit_json(
|
||||||
failed=False,
|
failed=False,
|
||||||
changed=False,
|
changed=False,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ version_added: 1.0.0
|
|||||||
author:
|
author:
|
||||||
- Abhijeet Kasurde (@Akasurde)
|
- Abhijeet Kasurde (@Akasurde)
|
||||||
requirements:
|
requirements:
|
||||||
- "helm >= 3.0.0 (https://github.com/helm/helm/releases)"
|
- "helm (https://github.com/helm/helm/releases)"
|
||||||
description:
|
description:
|
||||||
- Gather information about Helm plugins installed in namespace.
|
- Gather information about Helm plugins installed in namespace.
|
||||||
options:
|
options:
|
||||||
@@ -98,16 +98,29 @@ def main():
|
|||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Validate helm version >= 3.0.0
|
# Validate Helm version >=3.0.0,<4.0.0
|
||||||
module.validate_helm_version()
|
module.validate_helm_version()
|
||||||
|
|
||||||
plugin_name = module.params.get("plugin_name")
|
plugin_name = module.params.get("plugin_name")
|
||||||
|
|
||||||
|
plugin_list = []
|
||||||
|
|
||||||
rc, output, err, command = module.get_helm_plugin_list()
|
rc, output, err, command = module.get_helm_plugin_list()
|
||||||
|
|
||||||
plugins = parse_helm_plugin_list(output=output.splitlines())
|
out = parse_helm_plugin_list(output=output.splitlines())
|
||||||
if plugin_name is not None:
|
|
||||||
plugins = [plugin for plugin in plugins if plugin.get("name") == plugin_name]
|
for line in out:
|
||||||
|
if plugin_name is None:
|
||||||
|
plugin_list.append(
|
||||||
|
{"name": line[0], "version": line[1], "description": line[2]}
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if plugin_name == line[0]:
|
||||||
|
plugin_list.append(
|
||||||
|
{"name": line[0], "version": line[1], "description": line[2]}
|
||||||
|
)
|
||||||
|
break
|
||||||
|
|
||||||
module.exit_json(
|
module.exit_json(
|
||||||
changed=True,
|
changed=True,
|
||||||
@@ -115,7 +128,7 @@ def main():
|
|||||||
stdout=output,
|
stdout=output,
|
||||||
stderr=err,
|
stderr=err,
|
||||||
rc=rc,
|
rc=rc,
|
||||||
plugin_list=plugins,
|
plugin_list=plugin_list,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ description:
|
|||||||
- There are options for unpacking the chart after download.
|
- There are options for unpacking the chart after download.
|
||||||
|
|
||||||
requirements:
|
requirements:
|
||||||
- "helm >= 3.0.0 (https://github.com/helm/helm/releases)"
|
- "helm >= 3.0, <4.0.0 (https://github.com/helm/helm/releases)"
|
||||||
|
|
||||||
options:
|
options:
|
||||||
chart_ref:
|
chart_ref:
|
||||||
@@ -122,13 +122,6 @@ options:
|
|||||||
- The path of a helm binary to use.
|
- The path of a helm binary to use.
|
||||||
required: false
|
required: false
|
||||||
type: path
|
type: path
|
||||||
plain_http:
|
|
||||||
description:
|
|
||||||
- Use HTTP instead of HTTPS when working with OCI registries
|
|
||||||
- Requires Helm >= 3.13.0
|
|
||||||
type: bool
|
|
||||||
default: False
|
|
||||||
version_added: 6.1.0
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
EXAMPLES = r"""
|
EXAMPLES = r"""
|
||||||
@@ -360,7 +353,6 @@ def main():
|
|||||||
chart_ssl_cert_file=dict(type="path"),
|
chart_ssl_cert_file=dict(type="path"),
|
||||||
chart_ssl_key_file=dict(type="path"),
|
chart_ssl_key_file=dict(type="path"),
|
||||||
binary_path=dict(type="path"),
|
binary_path=dict(type="path"),
|
||||||
plain_http=dict(type="bool", default=False),
|
|
||||||
)
|
)
|
||||||
module = AnsibleHelmModule(
|
module = AnsibleHelmModule(
|
||||||
argument_spec=argspec,
|
argument_spec=argspec,
|
||||||
@@ -372,7 +364,7 @@ def main():
|
|||||||
mutually_exclusive=[("chart_version", "chart_devel")],
|
mutually_exclusive=[("chart_version", "chart_devel")],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Validate Helm version >=3.0.0
|
# Validate Helm version >=3.0.0,<4.0.0
|
||||||
module.validate_helm_version()
|
module.validate_helm_version()
|
||||||
|
|
||||||
helm_version = module.get_helm_version()
|
helm_version = module.get_helm_version()
|
||||||
@@ -382,7 +374,6 @@ def main():
|
|||||||
chart_ca_cert="3.1.0",
|
chart_ca_cert="3.1.0",
|
||||||
chart_ssl_cert_file="3.1.0",
|
chart_ssl_cert_file="3.1.0",
|
||||||
chart_ssl_key_file="3.1.0",
|
chart_ssl_key_file="3.1.0",
|
||||||
plain_http="3.13.0",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_version_requirement(opt):
|
def test_version_requirement(opt):
|
||||||
@@ -422,7 +413,6 @@ def main():
|
|||||||
skip_tls_certs_check=dict(key="insecure-skip-tls-verify"),
|
skip_tls_certs_check=dict(key="insecure-skip-tls-verify"),
|
||||||
chart_devel=dict(key="devel"),
|
chart_devel=dict(key="devel"),
|
||||||
untar_chart=dict(key="untar"),
|
untar_chart=dict(key="untar"),
|
||||||
plain_http=dict(key="plain-http"),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for k, v in helm_flag_args.items():
|
for k, v in helm_flag_args.items():
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ author:
|
|||||||
- Yuriy Novostavskiy (@yurnov)
|
- Yuriy Novostavskiy (@yurnov)
|
||||||
|
|
||||||
requirements:
|
requirements:
|
||||||
- "helm (https://github.com/helm/helm/releases) >= 3.8.0"
|
- "helm (https://github.com/helm/helm/releases) >= 3.8.0, <4.0.0"
|
||||||
|
|
||||||
description:
|
description:
|
||||||
- Helm registry authentication module allows you to login C(helm registry login) and logout C(helm registry logout) from a Helm registry.
|
- Helm registry authentication module allows you to login C(helm registry login) and logout C(helm registry logout) from a Helm registry.
|
||||||
@@ -75,14 +75,6 @@ options:
|
|||||||
- Path to the CA certificate SSL file for verify registry server certificate.
|
- Path to the CA certificate SSL file for verify registry server certificate.
|
||||||
required: false
|
required: false
|
||||||
type: path
|
type: path
|
||||||
plain_http:
|
|
||||||
description:
|
|
||||||
- Use insecure HTTP connections for C(helm registry login).
|
|
||||||
- Requires Helm >= 3.18.0
|
|
||||||
required: false
|
|
||||||
type: bool
|
|
||||||
default: False
|
|
||||||
version_added: 6.4.0
|
|
||||||
binary_path:
|
binary_path:
|
||||||
description:
|
description:
|
||||||
- The path of a helm binary to use.
|
- The path of a helm binary to use.
|
||||||
@@ -156,7 +148,6 @@ def arg_spec():
|
|||||||
key_file=dict(type="path", required=False),
|
key_file=dict(type="path", required=False),
|
||||||
cert_file=dict(type="path", required=False),
|
cert_file=dict(type="path", required=False),
|
||||||
ca_file=dict(type="path", required=False),
|
ca_file=dict(type="path", required=False),
|
||||||
plain_http=dict(type="bool", default=False),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -169,7 +160,6 @@ def login(
|
|||||||
key_file,
|
key_file,
|
||||||
cert_file,
|
cert_file,
|
||||||
ca_file,
|
ca_file,
|
||||||
plain_http,
|
|
||||||
):
|
):
|
||||||
login_command = command + " registry login " + host
|
login_command = command + " registry login " + host
|
||||||
|
|
||||||
@@ -187,8 +177,6 @@ def login(
|
|||||||
|
|
||||||
if ca_file is not None:
|
if ca_file is not None:
|
||||||
login_command += " --ca-file=" + ca_file
|
login_command += " --ca-file=" + ca_file
|
||||||
if plain_http:
|
|
||||||
login_command += " --plain-http"
|
|
||||||
|
|
||||||
return login_command
|
return login_command
|
||||||
|
|
||||||
@@ -206,8 +194,8 @@ def main():
|
|||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Validate Helm version >=3.8.0
|
# Validate Helm version >=3.0.0,<4.0.0
|
||||||
module.validate_helm_version(version="3.8.0")
|
module.validate_helm_version()
|
||||||
|
|
||||||
changed = False
|
changed = False
|
||||||
|
|
||||||
@@ -219,19 +207,6 @@ def main():
|
|||||||
key_file = module.params.get("key_file")
|
key_file = module.params.get("key_file")
|
||||||
cert_file = module.params.get("cert_file")
|
cert_file = module.params.get("cert_file")
|
||||||
ca_file = module.params.get("ca_file")
|
ca_file = module.params.get("ca_file")
|
||||||
plain_http = module.params.get("plain_http")
|
|
||||||
|
|
||||||
helm_version = module.get_helm_version()
|
|
||||||
|
|
||||||
if plain_http:
|
|
||||||
if LooseVersion(helm_version) < LooseVersion("3.18.0"):
|
|
||||||
module.warn(
|
|
||||||
"plain_http option requires helm >= 3.18.0, current version is {0}".format(
|
|
||||||
helm_version
|
|
||||||
)
|
|
||||||
)
|
|
||||||
# reset option
|
|
||||||
plain_http = False
|
|
||||||
|
|
||||||
helm_cmd = module.get_helm_binary()
|
helm_cmd = module.get_helm_binary()
|
||||||
|
|
||||||
@@ -240,15 +215,7 @@ def main():
|
|||||||
changed = True
|
changed = True
|
||||||
elif state == "present":
|
elif state == "present":
|
||||||
helm_cmd = login(
|
helm_cmd = login(
|
||||||
helm_cmd,
|
helm_cmd, host, insecure, username, password, key_file, cert_file, ca_file
|
||||||
host,
|
|
||||||
insecure,
|
|
||||||
username,
|
|
||||||
password,
|
|
||||||
key_file,
|
|
||||||
cert_file,
|
|
||||||
ca_file,
|
|
||||||
plain_http,
|
|
||||||
)
|
)
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
@@ -271,6 +238,7 @@ def main():
|
|||||||
command=helm_cmd,
|
command=helm_cmd,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
helm_version = module.get_helm_version()
|
||||||
if LooseVersion(helm_version) >= LooseVersion("3.18.0") and state == "absent":
|
if LooseVersion(helm_version) >= LooseVersion("3.18.0") and state == "absent":
|
||||||
# https://github.com/ansible-collections/kubernetes.core/issues/944
|
# https://github.com/ansible-collections/kubernetes.core/issues/944
|
||||||
module.warn(
|
module.warn(
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ author:
|
|||||||
- Lucas Boisserie (@LucasBoisserie)
|
- Lucas Boisserie (@LucasBoisserie)
|
||||||
|
|
||||||
requirements:
|
requirements:
|
||||||
- "helm >= 3.0.0 (https://github.com/helm/helm/releases)"
|
- "helm (https://github.com/helm/helm/releases)"
|
||||||
- "yaml (https://pypi.org/project/PyYAML/)"
|
- "yaml (https://pypi.org/project/PyYAML/)"
|
||||||
|
|
||||||
description:
|
description:
|
||||||
@@ -295,7 +295,7 @@ def main():
|
|||||||
if not IMP_YAML:
|
if not IMP_YAML:
|
||||||
module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR)
|
module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR)
|
||||||
|
|
||||||
# Validate Helm version >= 3.0.0
|
# Validate Helm version >=3.0.0,<4.0.0
|
||||||
module.validate_helm_version()
|
module.validate_helm_version()
|
||||||
|
|
||||||
changed = False
|
changed = False
|
||||||
|
|||||||
@@ -21,10 +21,6 @@ author:
|
|||||||
description:
|
description:
|
||||||
- Render chart templates to an output directory or as text of concatenated yaml documents.
|
- Render chart templates to an output directory or as text of concatenated yaml documents.
|
||||||
|
|
||||||
requirements:
|
|
||||||
- "helm >= 3.0.0 (https://github.com/helm/helm/releases)"
|
|
||||||
- "yaml (https://pypi.org/project/PyYAML/)"
|
|
||||||
|
|
||||||
options:
|
options:
|
||||||
binary_path:
|
binary_path:
|
||||||
description:
|
description:
|
||||||
@@ -151,13 +147,6 @@ options:
|
|||||||
- json
|
- json
|
||||||
- file
|
- file
|
||||||
version_added: 2.4.0
|
version_added: 2.4.0
|
||||||
plain_http:
|
|
||||||
description:
|
|
||||||
- Use HTTP instead of HTTPS when working with OCI registries
|
|
||||||
- Requires Helm >= 3.13.0
|
|
||||||
type: bool
|
|
||||||
default: False
|
|
||||||
version_added: 6.1.0
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
EXAMPLES = r"""
|
EXAMPLES = r"""
|
||||||
@@ -229,9 +218,6 @@ from ansible.module_utils.basic import missing_required_lib
|
|||||||
from ansible_collections.kubernetes.core.plugins.module_utils.helm import (
|
from ansible_collections.kubernetes.core.plugins.module_utils.helm import (
|
||||||
AnsibleHelmModule,
|
AnsibleHelmModule,
|
||||||
)
|
)
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.version import (
|
|
||||||
LooseVersion,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def template(
|
def template(
|
||||||
@@ -250,7 +236,6 @@ def template(
|
|||||||
values_files=None,
|
values_files=None,
|
||||||
include_crds=False,
|
include_crds=False,
|
||||||
set_values=None,
|
set_values=None,
|
||||||
plain_http=False,
|
|
||||||
):
|
):
|
||||||
cmd += " template "
|
cmd += " template "
|
||||||
|
|
||||||
@@ -277,9 +262,6 @@ def template(
|
|||||||
if insecure_registry:
|
if insecure_registry:
|
||||||
cmd += " --insecure-skip-tls-verify"
|
cmd += " --insecure-skip-tls-verify"
|
||||||
|
|
||||||
if plain_http:
|
|
||||||
cmd += " --plain-http"
|
|
||||||
|
|
||||||
if show_only:
|
if show_only:
|
||||||
for template in show_only:
|
for template in show_only:
|
||||||
cmd += " -s " + template
|
cmd += " -s " + template
|
||||||
@@ -325,7 +307,6 @@ def main():
|
|||||||
values_files=dict(type="list", default=[], elements="str"),
|
values_files=dict(type="list", default=[], elements="str"),
|
||||||
update_repo_cache=dict(type="bool", default=False),
|
update_repo_cache=dict(type="bool", default=False),
|
||||||
set_values=dict(type="list", elements="dict"),
|
set_values=dict(type="list", elements="dict"),
|
||||||
plain_http=dict(type="bool", default=False),
|
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
@@ -346,25 +327,15 @@ def main():
|
|||||||
values_files = module.params.get("values_files")
|
values_files = module.params.get("values_files")
|
||||||
update_repo_cache = module.params.get("update_repo_cache")
|
update_repo_cache = module.params.get("update_repo_cache")
|
||||||
set_values = module.params.get("set_values")
|
set_values = module.params.get("set_values")
|
||||||
plain_http = module.params.get("plain_http")
|
|
||||||
|
|
||||||
if not IMP_YAML:
|
if not IMP_YAML:
|
||||||
module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR)
|
module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR)
|
||||||
|
|
||||||
# Validate Helm version >=3.0.0
|
# Validate Helm version >=3.0.0,<4.0.0
|
||||||
module.validate_helm_version()
|
module.validate_helm_version()
|
||||||
|
|
||||||
helm_cmd = module.get_helm_binary()
|
helm_cmd = module.get_helm_binary()
|
||||||
|
|
||||||
if plain_http:
|
|
||||||
helm_version = module.get_helm_version()
|
|
||||||
if LooseVersion(helm_version) < LooseVersion("3.13.0"):
|
|
||||||
module.fail_json(
|
|
||||||
msg="plain_http requires helm >= 3.13.0, current version is {0}".format(
|
|
||||||
helm_version
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if update_repo_cache:
|
if update_repo_cache:
|
||||||
update_cmd = helm_cmd + " repo update"
|
update_cmd = helm_cmd + " repo update"
|
||||||
module.run_helm_command(update_cmd)
|
module.run_helm_command(update_cmd)
|
||||||
@@ -389,7 +360,6 @@ def main():
|
|||||||
values_files=values_files,
|
values_files=values_files,
|
||||||
include_crds=include_crds,
|
include_crds=include_crds,
|
||||||
set_values=set_values_args,
|
set_values=set_values_args,
|
||||||
plain_http=plain_http,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if not check_mode:
|
if not check_mode:
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ result:
|
|||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils._text import to_native
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
|
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
|
||||||
AnsibleModule,
|
AnsibleModule,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ import time
|
|||||||
import traceback
|
import traceback
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils._text import to_native
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
|
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
|
||||||
AnsibleModule,
|
AnsibleModule,
|
||||||
)
|
)
|
||||||
@@ -230,7 +230,7 @@ def filter_pods(pods, force, ignore_daemonset, delete_emptydir_data):
|
|||||||
else:
|
else:
|
||||||
to_delete.append((pod.metadata.namespace, pod.metadata.name))
|
to_delete.append((pod.metadata.namespace, pod.metadata.name))
|
||||||
|
|
||||||
warnings, errors, info = [], [], []
|
warnings, errors = [], []
|
||||||
if unmanaged:
|
if unmanaged:
|
||||||
pod_names = ",".join([pod[0] + "/" + pod[1] for pod in unmanaged])
|
pod_names = ",".join([pod[0] + "/" + pod[1] for pod in unmanaged])
|
||||||
if not force:
|
if not force:
|
||||||
@@ -242,7 +242,7 @@ def filter_pods(pods, force, ignore_daemonset, delete_emptydir_data):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# Pod not managed will be deleted as 'force' is true
|
# Pod not managed will be deleted as 'force' is true
|
||||||
info.append(
|
warnings.append(
|
||||||
"Deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: {0}.".format(
|
"Deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: {0}.".format(
|
||||||
pod_names
|
pod_names
|
||||||
)
|
)
|
||||||
@@ -264,7 +264,7 @@ def filter_pods(pods, force, ignore_daemonset, delete_emptydir_data):
|
|||||||
"cannot delete Pods with local storage: {0}.".format(pod_names)
|
"cannot delete Pods with local storage: {0}.".format(pod_names)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
info.append("Deleting Pods with local storage: {0}.".format(pod_names))
|
warnings.append("Deleting Pods with local storage: {0}.".format(pod_names))
|
||||||
for pod in localStorage:
|
for pod in localStorage:
|
||||||
to_delete.append((pod[0], pod[1]))
|
to_delete.append((pod[0], pod[1]))
|
||||||
|
|
||||||
@@ -278,8 +278,8 @@ def filter_pods(pods, force, ignore_daemonset, delete_emptydir_data):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
info.append("Ignoring DaemonSet-managed Pods: {0}.".format(pod_names))
|
warnings.append("Ignoring DaemonSet-managed Pods: {0}.".format(pod_names))
|
||||||
return to_delete, warnings, errors, info
|
return to_delete, warnings, errors
|
||||||
|
|
||||||
|
|
||||||
class K8sDrainAnsible(object):
|
class K8sDrainAnsible(object):
|
||||||
@@ -334,7 +334,6 @@ class K8sDrainAnsible(object):
|
|||||||
def evict_pods(self, pods):
|
def evict_pods(self, pods):
|
||||||
for namespace, name in pods:
|
for namespace, name in pods:
|
||||||
try:
|
try:
|
||||||
if not self._module.check_mode:
|
|
||||||
if self._drain_options.get("disable_eviction"):
|
if self._drain_options.get("disable_eviction"):
|
||||||
self._api_instance.delete_namespaced_pod(
|
self._api_instance.delete_namespaced_pod(
|
||||||
name=name, namespace=namespace, body=self._delete_options
|
name=name, namespace=namespace, body=self._delete_options
|
||||||
@@ -363,7 +362,11 @@ class K8sDrainAnsible(object):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def list_pods(self):
|
def list_pods(self):
|
||||||
params = {"field_selector": "spec.nodeName=" + self._module.params.get("name")}
|
params = {
|
||||||
|
"field_selector": "spec.nodeName={name}".format(
|
||||||
|
name=self._module.params.get("name")
|
||||||
|
)
|
||||||
|
}
|
||||||
pod_selectors = self._module.params.get("pod_selectors")
|
pod_selectors = self._module.params.get("pod_selectors")
|
||||||
if pod_selectors:
|
if pod_selectors:
|
||||||
params["label_selector"] = ",".join(pod_selectors)
|
params["label_selector"] = ",".join(pod_selectors)
|
||||||
@@ -373,7 +376,6 @@ class K8sDrainAnsible(object):
|
|||||||
# Mark node as unschedulable
|
# Mark node as unschedulable
|
||||||
result = []
|
result = []
|
||||||
if not node_unschedulable:
|
if not node_unschedulable:
|
||||||
if not self._module.check_mode:
|
|
||||||
self.patch_node(unschedulable=True)
|
self.patch_node(unschedulable=True)
|
||||||
result.append(
|
result.append(
|
||||||
"node {0} marked unschedulable.".format(self._module.params.get("name"))
|
"node {0} marked unschedulable.".format(self._module.params.get("name"))
|
||||||
@@ -389,7 +391,6 @@ class K8sDrainAnsible(object):
|
|||||||
def _revert_node_patch():
|
def _revert_node_patch():
|
||||||
if self._changed:
|
if self._changed:
|
||||||
self._changed = False
|
self._changed = False
|
||||||
if not self._module.check_mode:
|
|
||||||
self.patch_node(unschedulable=False)
|
self.patch_node(unschedulable=False)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -400,7 +401,7 @@ class K8sDrainAnsible(object):
|
|||||||
delete_emptydir_data = self._drain_options.get(
|
delete_emptydir_data = self._drain_options.get(
|
||||||
"delete_emptydir_data", False
|
"delete_emptydir_data", False
|
||||||
)
|
)
|
||||||
pods, warnings, errors, info = filter_pods(
|
pods, warnings, errors = filter_pods(
|
||||||
pod_list.items, force, ignore_daemonset, delete_emptydir_data
|
pod_list.items, force, ignore_daemonset, delete_emptydir_data
|
||||||
)
|
)
|
||||||
if errors:
|
if errors:
|
||||||
@@ -430,25 +431,18 @@ class K8sDrainAnsible(object):
|
|||||||
if pods:
|
if pods:
|
||||||
self.evict_pods(pods)
|
self.evict_pods(pods)
|
||||||
number_pod = len(pods)
|
number_pod = len(pods)
|
||||||
if self._module.check_mode:
|
if self._drain_options.get("wait_timeout") is not None:
|
||||||
result.append(
|
warn = self.wait_for_pod_deletion(
|
||||||
"Would have deleted {0} Pod(s) from node if not in check mode.".format(
|
pods,
|
||||||
number_pod
|
self._drain_options.get("wait_timeout"),
|
||||||
|
self._drain_options.get("wait_sleep"),
|
||||||
)
|
)
|
||||||
)
|
|
||||||
else:
|
|
||||||
wait_timeout = self._drain_options.get("wait_timeout")
|
|
||||||
wait_sleep = self._drain_options.get("wait_sleep")
|
|
||||||
if wait_timeout is not None:
|
|
||||||
warn = self.wait_for_pod_deletion(pods, wait_timeout, wait_sleep)
|
|
||||||
if warn:
|
if warn:
|
||||||
warnings.append(warn)
|
warnings.append(warn)
|
||||||
result.append("{0} Pod(s) deleted from node.".format(number_pod))
|
result.append("{0} Pod(s) deleted from node.".format(number_pod))
|
||||||
if warnings:
|
if warnings:
|
||||||
for warning in warnings:
|
for warning in warnings:
|
||||||
self._module.warn(warning)
|
self._module.warn(warning)
|
||||||
for line in info:
|
|
||||||
self._module.debug(line)
|
|
||||||
return dict(result=" ".join(result))
|
return dict(result=" ".join(result))
|
||||||
|
|
||||||
def patch_node(self, unschedulable):
|
def patch_node(self, unschedulable):
|
||||||
@@ -489,7 +483,6 @@ class K8sDrainAnsible(object):
|
|||||||
self._module.exit_json(
|
self._module.exit_json(
|
||||||
result="node {0} already marked unschedulable.".format(name)
|
result="node {0} already marked unschedulable.".format(name)
|
||||||
)
|
)
|
||||||
if not self._module.check_mode:
|
|
||||||
self.patch_node(unschedulable=True)
|
self.patch_node(unschedulable=True)
|
||||||
result["result"] = "node {0} marked unschedulable.".format(name)
|
result["result"] = "node {0} marked unschedulable.".format(name)
|
||||||
self._changed = True
|
self._changed = True
|
||||||
@@ -499,7 +492,6 @@ class K8sDrainAnsible(object):
|
|||||||
self._module.exit_json(
|
self._module.exit_json(
|
||||||
result="node {0} already marked schedulable.".format(name)
|
result="node {0} already marked schedulable.".format(name)
|
||||||
)
|
)
|
||||||
if not self._module.check_mode:
|
|
||||||
self.patch_node(unschedulable=False)
|
self.patch_node(unschedulable=False)
|
||||||
result["result"] = "node {0} marked schedulable.".format(name)
|
result["result"] = "node {0} marked schedulable.".format(name)
|
||||||
self._changed = True
|
self._changed = True
|
||||||
@@ -543,9 +535,7 @@ def argspec():
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
module = AnsibleK8SModule(
|
module = AnsibleK8SModule(module_class=AnsibleModule, argument_spec=argspec())
|
||||||
module_class=AnsibleModule, argument_spec=argspec(), supports_check_mode=True
|
|
||||||
)
|
|
||||||
|
|
||||||
if not HAS_EVICTION_API:
|
if not HAS_EVICTION_API:
|
||||||
module.fail_json(
|
module.fail_json(
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ except ImportError:
|
|||||||
# ImportError are managed by the common module already.
|
# ImportError are managed by the common module already.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils._text import to_native
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
|
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
|
||||||
AnsibleModule,
|
AnsibleModule,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -33,14 +33,6 @@ options:
|
|||||||
aliases:
|
aliases:
|
||||||
- api
|
- api
|
||||||
- version
|
- version
|
||||||
hidden_fields:
|
|
||||||
description:
|
|
||||||
- List of fields to hide from the diff output.
|
|
||||||
- This is useful for fields that are not relevant to the patch operation, such as `metadata.managedFields`.
|
|
||||||
type: list
|
|
||||||
elements: str
|
|
||||||
default: []
|
|
||||||
version_added: 6.1.0
|
|
||||||
kind:
|
kind:
|
||||||
description:
|
description:
|
||||||
- Use to specify an object model.
|
- Use to specify an object model.
|
||||||
@@ -135,8 +127,8 @@ error:
|
|||||||
import copy
|
import copy
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
|
from ansible.module_utils._text import to_native
|
||||||
from ansible.module_utils.basic import missing_required_lib
|
from ansible.module_utils.basic import missing_required_lib
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
|
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
|
||||||
AnsibleModule,
|
AnsibleModule,
|
||||||
)
|
)
|
||||||
@@ -155,7 +147,6 @@ from ansible_collections.kubernetes.core.plugins.module_utils.k8s.exceptions imp
|
|||||||
)
|
)
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.service import (
|
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.service import (
|
||||||
diff_objects,
|
diff_objects,
|
||||||
hide_fields,
|
|
||||||
)
|
)
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.waiter import (
|
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.waiter import (
|
||||||
get_waiter,
|
get_waiter,
|
||||||
@@ -183,7 +174,6 @@ JSON_PATCH_ARGS = {
|
|||||||
"namespace": {"type": "str"},
|
"namespace": {"type": "str"},
|
||||||
"name": {"type": "str", "required": True},
|
"name": {"type": "str", "required": True},
|
||||||
"patch": {"type": "list", "required": True, "elements": "dict"},
|
"patch": {"type": "list", "required": True, "elements": "dict"},
|
||||||
"hidden_fields": {"type": "list", "elements": "str", "default": []},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -213,7 +203,6 @@ def execute_module(module, client):
|
|||||||
namespace = module.params.get("namespace")
|
namespace = module.params.get("namespace")
|
||||||
patch = module.params.get("patch")
|
patch = module.params.get("patch")
|
||||||
|
|
||||||
hidden_fields = module.params.get("hidden_fields")
|
|
||||||
wait = module.params.get("wait")
|
wait = module.params.get("wait")
|
||||||
wait_sleep = module.params.get("wait_sleep")
|
wait_sleep = module.params.get("wait_sleep")
|
||||||
wait_timeout = module.params.get("wait_timeout")
|
wait_timeout = module.params.get("wait_timeout")
|
||||||
@@ -271,13 +260,13 @@ def execute_module(module, client):
|
|||||||
module.fail_json(msg=msg, error=to_native(exc), status="", reason="")
|
module.fail_json(msg=msg, error=to_native(exc), status="", reason="")
|
||||||
|
|
||||||
success = True
|
success = True
|
||||||
result = {"result": hide_fields(obj, hidden_fields)}
|
result = {"result": obj}
|
||||||
if wait and not module.check_mode:
|
if wait and not module.check_mode:
|
||||||
waiter = get_waiter(client, resource, condition=wait_condition)
|
waiter = get_waiter(client, resource, condition=wait_condition)
|
||||||
success, result["result"], result["duration"] = waiter.wait(
|
success, result["result"], result["duration"] = waiter.wait(
|
||||||
wait_timeout, wait_sleep, name, namespace
|
wait_timeout, wait_sleep, name, namespace
|
||||||
)
|
)
|
||||||
match, diffs = diff_objects(existing.to_dict(), obj, hidden_fields)
|
match, diffs = diff_objects(existing.to_dict(), obj)
|
||||||
result["changed"] = not match
|
result["changed"] = not match
|
||||||
if module._diff:
|
if module._diff:
|
||||||
result["diff"] = diffs
|
result["diff"] = diffs
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ except ImportError:
|
|||||||
# Handled in module setup
|
# Handled in module setup
|
||||||
pass
|
pass
|
||||||
|
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils._text import to_native
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
|
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
|
||||||
AnsibleModule,
|
AnsibleModule,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ result:
|
|||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils._text import to_native
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
|
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
|
||||||
AnsibleModule,
|
AnsibleModule,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,441 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
#
|
|
||||||
# Copyright (c) Ansible Project
|
|
||||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
||||||
|
|
||||||
DOCUMENTATION = r"""
|
|
||||||
---
|
|
||||||
module: kubeconfig
|
|
||||||
|
|
||||||
short_description: Generate, update, and optionally write Kubernetes kubeconfig files
|
|
||||||
|
|
||||||
version_added: "6.5.0"
|
|
||||||
|
|
||||||
author: "Youssef Khalid Ali (@YoussefKhalidAli)"
|
|
||||||
|
|
||||||
description:
|
|
||||||
- Build, update, and manage Kubernetes kubeconfig files using structured input.
|
|
||||||
- Supports loading an existing kubeconfig file and merging clusters, users, and contexts.
|
|
||||||
- Can optionally write the resulting kubeconfig to a destination path.
|
|
||||||
- Ensures idempotent behavior by only updating files when changes occur.
|
|
||||||
|
|
||||||
requirements:
|
|
||||||
- "PyYAML >= 5.1"
|
|
||||||
|
|
||||||
notes:
|
|
||||||
- Input data is merged by resource name (cluster, user, context).
|
|
||||||
- Updates under O(clusters), O(users), and O(contexts) are matched by C(name) against the kubeconfig loaded from O(path).
|
|
||||||
- For an existing C(name), each entry's C(behavior) suboption controls the update.
|
|
||||||
- The default is V(merge), which merges nested C(cluster), C(user), and C(context) data so unspecified keys are preserved.
|
|
||||||
- With V(replace), the previous entry for that name is dropped and only the new definition is used.
|
|
||||||
- With V(keep), the existing entry is left unchanged.
|
|
||||||
- This can be used to move kubeconfig files to a different location with different content.
|
|
||||||
- This module does not validate cluster connectivity or authentication.
|
|
||||||
- The module supports C(check_mode) and will not write files when enabled.
|
|
||||||
- The structure follows standard Kubernetes kubeconfig format as defined in the Kubernetes documentation.
|
|
||||||
- Tokens and sensitive data should be protected using ansible-vault or environment variables.
|
|
||||||
|
|
||||||
options:
|
|
||||||
path:
|
|
||||||
description:
|
|
||||||
- Path to an existing kubeconfig file to load and merge from.
|
|
||||||
- If the file does not exist, a new kubeconfig will be created.
|
|
||||||
- This becomes the default destination if O(dest) is not specified.
|
|
||||||
type: str
|
|
||||||
required: true
|
|
||||||
|
|
||||||
dest:
|
|
||||||
description:
|
|
||||||
- Destination path where the final kubeconfig should be written.
|
|
||||||
- If not specified, the kubeconfig will be saved to O(path).
|
|
||||||
- Allows copying and modifying a kubeconfig to a new location.
|
|
||||||
type: str
|
|
||||||
required: false
|
|
||||||
|
|
||||||
clusters:
|
|
||||||
description:
|
|
||||||
- List of cluster definitions to merge into the kubeconfig.
|
|
||||||
- Each cluster is identified by its C(name).
|
|
||||||
- When C(name) matches an existing cluster, the default C(behavior) is V(merge).
|
|
||||||
- See the C(behavior) suboption for V(replace) and V(keep).
|
|
||||||
type: list
|
|
||||||
elements: dict
|
|
||||||
required: false
|
|
||||||
default: []
|
|
||||||
suboptions:
|
|
||||||
name:
|
|
||||||
description:
|
|
||||||
- Unique name identifier for the cluster.
|
|
||||||
type: str
|
|
||||||
required: true
|
|
||||||
behavior:
|
|
||||||
description:
|
|
||||||
- How to handle merging if a cluster with this name already exists.
|
|
||||||
- C(merge) - Update only the specified fields, preserve others (default).
|
|
||||||
- C(replace) - Replace the entire cluster definition.
|
|
||||||
- C(keep) - Keep existing cluster, skip this entry.
|
|
||||||
type: str
|
|
||||||
choices: ['merge', 'replace', 'keep']
|
|
||||||
default: merge
|
|
||||||
cluster:
|
|
||||||
description:
|
|
||||||
- Cluster configuration details.
|
|
||||||
type: dict
|
|
||||||
required: true
|
|
||||||
suboptions:
|
|
||||||
server:
|
|
||||||
description:
|
|
||||||
- Kubernetes API server URL (e.g., C(https://k8s.example.com:6443)).
|
|
||||||
type: str
|
|
||||||
required: true
|
|
||||||
certificate-authority:
|
|
||||||
description:
|
|
||||||
- Path to a CA certificate file for validating the API server certificate.
|
|
||||||
type: str
|
|
||||||
certificate-authority-data:
|
|
||||||
description:
|
|
||||||
- Base64 encoded CA certificate data.
|
|
||||||
- Use this instead of C(certificate-authority) for embedded certificates.
|
|
||||||
type: str
|
|
||||||
insecure-skip-tls-verify:
|
|
||||||
description:
|
|
||||||
- If true, the server's certificate will not be validated.
|
|
||||||
type: bool
|
|
||||||
proxy-url:
|
|
||||||
description:
|
|
||||||
- Optional proxy URL for cluster connections.
|
|
||||||
type: str
|
|
||||||
tls-server-name:
|
|
||||||
description:
|
|
||||||
- Server name to use for server certificate validation.
|
|
||||||
type: str
|
|
||||||
|
|
||||||
users:
|
|
||||||
description:
|
|
||||||
- List of user authentication configurations.
|
|
||||||
- Each user is identified by its C(name).
|
|
||||||
- When C(name) matches an existing user, the default C(behavior) is V(merge).
|
|
||||||
- See the C(behavior) suboption for V(replace) and V(keep).
|
|
||||||
type: list
|
|
||||||
elements: dict
|
|
||||||
required: false
|
|
||||||
default: []
|
|
||||||
suboptions:
|
|
||||||
name:
|
|
||||||
description:
|
|
||||||
- Unique name identifier for the user.
|
|
||||||
type: str
|
|
||||||
required: true
|
|
||||||
behavior:
|
|
||||||
description:
|
|
||||||
- How to handle merging if a user with this name already exists.
|
|
||||||
- C(merge) - Update only the specified fields, preserve others (default).
|
|
||||||
- C(replace) - Replace the entire user definition.
|
|
||||||
- C(keep) - Keep existing user, skip this entry.
|
|
||||||
type: str
|
|
||||||
choices: ['merge', 'replace', 'keep']
|
|
||||||
default: merge
|
|
||||||
user:
|
|
||||||
description:
|
|
||||||
- User authentication configuration.
|
|
||||||
type: dict
|
|
||||||
required: true
|
|
||||||
suboptions:
|
|
||||||
token:
|
|
||||||
description:
|
|
||||||
- Bearer token for authentication.
|
|
||||||
type: str
|
|
||||||
username:
|
|
||||||
description:
|
|
||||||
- Username for basic authentication.
|
|
||||||
type: str
|
|
||||||
password:
|
|
||||||
description:
|
|
||||||
- Password for basic authentication.
|
|
||||||
type: str
|
|
||||||
client-certificate:
|
|
||||||
description:
|
|
||||||
- Path to client certificate file.
|
|
||||||
- Used for certificate-based authentication.
|
|
||||||
type: str
|
|
||||||
client-key:
|
|
||||||
description:
|
|
||||||
- Path to client private key file.
|
|
||||||
- Must be provided with C(client-certificate).
|
|
||||||
type: str
|
|
||||||
client-certificate-data:
|
|
||||||
description:
|
|
||||||
- Base64 encoded client certificate.
|
|
||||||
- Use instead of C(client-certificate) for embedded certificates.
|
|
||||||
type: str
|
|
||||||
client-key-data:
|
|
||||||
description:
|
|
||||||
- Base64 encoded client private key.
|
|
||||||
- Use instead of C(client-key) for embedded keys.
|
|
||||||
type: str
|
|
||||||
auth-provider:
|
|
||||||
description:
|
|
||||||
- Authentication provider configuration (e.g., for GCP, Azure).
|
|
||||||
type: dict
|
|
||||||
exec:
|
|
||||||
description:
|
|
||||||
- Exec-based credential plugin configuration.
|
|
||||||
- Used for external authentication providers.
|
|
||||||
type: dict
|
|
||||||
|
|
||||||
contexts:
|
|
||||||
description:
|
|
||||||
- List of context definitions linking users and clusters.
|
|
||||||
- Each context is identified by its C(name).
|
|
||||||
- When C(name) matches an existing context, the default C(behavior) is V(merge).
|
|
||||||
- See the C(behavior) suboption for V(replace) and V(keep).
|
|
||||||
type: list
|
|
||||||
elements: dict
|
|
||||||
required: false
|
|
||||||
default: []
|
|
||||||
suboptions:
|
|
||||||
name:
|
|
||||||
description:
|
|
||||||
- Unique name identifier for the context.
|
|
||||||
type: str
|
|
||||||
required: true
|
|
||||||
behavior:
|
|
||||||
description:
|
|
||||||
- How to handle merging if a context with this name already exists.
|
|
||||||
- C(merge) - Update only the specified fields, preserve others (default).
|
|
||||||
- C(replace) - Replace the entire context definition.
|
|
||||||
- C(keep) - Keep existing context, skip this entry.
|
|
||||||
type: str
|
|
||||||
choices: ['merge', 'replace', 'keep']
|
|
||||||
default: merge
|
|
||||||
context:
|
|
||||||
description:
|
|
||||||
- Context configuration linking cluster and user.
|
|
||||||
type: dict
|
|
||||||
required: true
|
|
||||||
suboptions:
|
|
||||||
cluster:
|
|
||||||
description:
|
|
||||||
- Name of the cluster to use (must match a cluster name in O(clusters)).
|
|
||||||
type: str
|
|
||||||
required: true
|
|
||||||
user:
|
|
||||||
description:
|
|
||||||
- Name of the user to authenticate as (must match a user name in O(users)).
|
|
||||||
type: str
|
|
||||||
required: true
|
|
||||||
namespace:
|
|
||||||
description:
|
|
||||||
- Default namespace to use for this context.
|
|
||||||
- If not specified, defaults to C(default).
|
|
||||||
type: str
|
|
||||||
|
|
||||||
preferences:
|
|
||||||
description:
|
|
||||||
- Kubeconfig preferences.
|
|
||||||
- Used for client-side settings like color output, default editor, etc.
|
|
||||||
type: dict
|
|
||||||
required: false
|
|
||||||
default: {}
|
|
||||||
|
|
||||||
current_context:
|
|
||||||
description:
|
|
||||||
- Name of the context to set as current/active.
|
|
||||||
- This context will be used by default when using kubectl.
|
|
||||||
- Must match one of the context names defined in O(contexts).
|
|
||||||
type: str
|
|
||||||
required: false
|
|
||||||
|
|
||||||
seealso:
|
|
||||||
- name: Kubernetes kubeconfig documentation
|
|
||||||
description: Official Kubernetes documentation for kubeconfig files
|
|
||||||
link: https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/
|
|
||||||
- name: kubectl config documentation
|
|
||||||
description: kubectl commands for working with kubeconfig files
|
|
||||||
link: https://kubernetes.io/docs/reference/kubectl/generated/kubectl_config/
|
|
||||||
"""
|
|
||||||
|
|
||||||
EXAMPLES = r"""
|
|
||||||
# Create a new kubeconfig file with a single cluster
|
|
||||||
- name: Create basic kubeconfig
|
|
||||||
kubernetes.core.kubeconfig:
|
|
||||||
path: /home/user/.kube/config
|
|
||||||
clusters:
|
|
||||||
- name: production-cluster
|
|
||||||
cluster:
|
|
||||||
server: https://prod.k8s.example.com:6443
|
|
||||||
certificate-authority-data: LS0tLS1CRUdJTi...
|
|
||||||
users:
|
|
||||||
- name: admin-user
|
|
||||||
user:
|
|
||||||
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9...
|
|
||||||
contexts:
|
|
||||||
- name: prod-admin
|
|
||||||
context:
|
|
||||||
cluster: production-cluster
|
|
||||||
user: admin-user
|
|
||||||
namespace: production
|
|
||||||
current_context: prod-admin
|
|
||||||
|
|
||||||
- name: Copy and modify kubeconfig
|
|
||||||
kubernetes.core.kubeconfig:
|
|
||||||
path: /home/user/.kube/config
|
|
||||||
dest: /home/user/.kube/config-backup
|
|
||||||
clusters:
|
|
||||||
- name: new-cluster
|
|
||||||
cluster:
|
|
||||||
server: https://new.example.com:6443
|
|
||||||
|
|
||||||
- name: Switch current context
|
|
||||||
kubernetes.core.kubeconfig:
|
|
||||||
path: ~/.kube/config
|
|
||||||
current_context: prod-context
|
|
||||||
|
|
||||||
- name: Update user credentials
|
|
||||||
kubernetes.core.kubeconfig:
|
|
||||||
path: ~/.kube/config
|
|
||||||
users:
|
|
||||||
- name: admin-user
|
|
||||||
user:
|
|
||||||
token: "{{ new_admin_token }}"
|
|
||||||
"""
|
|
||||||
|
|
||||||
RETURN = r"""
|
|
||||||
kubeconfig:
|
|
||||||
description: The complete kubeconfig data structure.
|
|
||||||
type: dict
|
|
||||||
returned: always
|
|
||||||
|
|
||||||
dest:
|
|
||||||
description: The path where the kubeconfig was written.
|
|
||||||
type: str
|
|
||||||
returned: always
|
|
||||||
sample: /home/user/.kube/config
|
|
||||||
"""
|
|
||||||
import os
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
|
|
||||||
extract_sensitive_values_from_kubeconfig,
|
|
||||||
)
|
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.kubeconfig import (
|
|
||||||
hash_data,
|
|
||||||
load_yaml_file,
|
|
||||||
merge_by_name,
|
|
||||||
write_file,
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
import yaml
|
|
||||||
|
|
||||||
IMP_YAML = True
|
|
||||||
IMP_YAML_ERR = None
|
|
||||||
except ImportError:
|
|
||||||
IMP_YAML = False
|
|
||||||
IMP_YAML_ERR = traceback.format_exc()
|
|
||||||
|
|
||||||
|
|
||||||
def run_module():
|
|
||||||
module_args = dict(
|
|
||||||
path=dict(type="str", required=True),
|
|
||||||
dest=dict(type="str", required=False),
|
|
||||||
clusters=dict(type="list", elements="dict", required=False, default=[]),
|
|
||||||
users=dict(type="list", elements="dict", required=False, default=[]),
|
|
||||||
contexts=dict(type="list", elements="dict", required=False, default=[]),
|
|
||||||
preferences=dict(type="dict", required=False, default={}),
|
|
||||||
current_context=dict(type="str", required=False),
|
|
||||||
)
|
|
||||||
|
|
||||||
module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
|
|
||||||
|
|
||||||
path = module.params["path"]
|
|
||||||
dest = module.params["dest"] or path
|
|
||||||
|
|
||||||
clusters_input = module.params["clusters"]
|
|
||||||
users_input = module.params["users"]
|
|
||||||
contexts_input = module.params["contexts"]
|
|
||||||
|
|
||||||
preferences = module.params["preferences"]
|
|
||||||
current_context = module.params["current_context"]
|
|
||||||
|
|
||||||
# Load existing kubeconfig
|
|
||||||
try:
|
|
||||||
if not IMP_YAML:
|
|
||||||
module.fail_json(
|
|
||||||
msg=missing_required_lib("pyyaml"),
|
|
||||||
exception=IMP_YAML_ERR,
|
|
||||||
)
|
|
||||||
existing = load_yaml_file(path) if path else {}
|
|
||||||
except Exception as e:
|
|
||||||
module.fail_json(
|
|
||||||
msg="Failed to load existing kubeconfig: %s" % to_native(e),
|
|
||||||
exception=traceback.format_exc(),
|
|
||||||
)
|
|
||||||
|
|
||||||
clusters = merge_by_name(existing.get("clusters", []), clusters_input)
|
|
||||||
users = merge_by_name(existing.get("users", []), users_input)
|
|
||||||
contexts = merge_by_name(existing.get("contexts", []), contexts_input)
|
|
||||||
|
|
||||||
# Build final kubeconfig
|
|
||||||
kubeconfig = {
|
|
||||||
"apiVersion": "v1",
|
|
||||||
"kind": "Config",
|
|
||||||
"preferences": preferences or existing.get("preferences", {}),
|
|
||||||
"clusters": clusters,
|
|
||||||
"users": users,
|
|
||||||
"contexts": contexts,
|
|
||||||
"current-context": current_context or existing.get("current-context") or "",
|
|
||||||
}
|
|
||||||
|
|
||||||
changed = False
|
|
||||||
old_data = {}
|
|
||||||
|
|
||||||
if os.path.exists(dest):
|
|
||||||
try:
|
|
||||||
with open(dest, "r") as f:
|
|
||||||
old_data = yaml.safe_load(f) or {}
|
|
||||||
except Exception as e:
|
|
||||||
module.fail_json(
|
|
||||||
msg="Failed to read destination file: %s" % to_native(e),
|
|
||||||
exception=traceback.format_exc(),
|
|
||||||
)
|
|
||||||
|
|
||||||
old_hash = hash_data(old_data)
|
|
||||||
new_hash = hash_data(kubeconfig)
|
|
||||||
|
|
||||||
if old_hash != new_hash:
|
|
||||||
if not module.check_mode:
|
|
||||||
try:
|
|
||||||
write_file(dest, kubeconfig)
|
|
||||||
except Exception as e:
|
|
||||||
module.fail_json(
|
|
||||||
msg="Failed to write kubeconfig: %s" % to_native(e),
|
|
||||||
exception=traceback.format_exc(),
|
|
||||||
)
|
|
||||||
changed = True
|
|
||||||
|
|
||||||
if isinstance(kubeconfig, dict):
|
|
||||||
module.no_log_values.update(
|
|
||||||
extract_sensitive_values_from_kubeconfig(kubeconfig)
|
|
||||||
)
|
|
||||||
|
|
||||||
module.exit_json(
|
|
||||||
changed=changed,
|
|
||||||
kubeconfig=kubeconfig,
|
|
||||||
dest=dest,
|
|
||||||
msg=(
|
|
||||||
"Kubeconfig file has been updated."
|
|
||||||
if changed
|
|
||||||
else "Kubeconfig file is already up to date."
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
run_module()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -1 +1,4 @@
|
|||||||
disabled # used by test targets helm_vX_XX_XX
|
time=100
|
||||||
|
helm_info
|
||||||
|
helm_repository
|
||||||
|
helm_template
|
||||||
|
|||||||
@@ -9,25 +9,23 @@ chart_test_version: 4.2.4
|
|||||||
chart_test_version_local_path: 1.32.0
|
chart_test_version_local_path: 1.32.0
|
||||||
chart_test_version_upgrade: 4.2.5
|
chart_test_version_upgrade: 4.2.5
|
||||||
chart_test_version_upgrade_local_path: 1.33.0
|
chart_test_version_upgrade_local_path: 1.33.0
|
||||||
chart_test_repo: "https://stenic.github.io/k8status/"
|
chart_test_repo: "https://kubernetes.github.io/ingress-nginx"
|
||||||
chart_test_git_repo: "http://github.com/helm/charts.git"
|
chart_test_git_repo: "http://github.com/helm/charts.git"
|
||||||
chart_test_values:
|
chart_test_values:
|
||||||
revisionHistoryLimit: 0
|
revisionHistoryLimit: 0
|
||||||
myValue: "changed"
|
myValue: "changed"
|
||||||
|
|
||||||
test_namespace:
|
test_namespace:
|
||||||
- "helm-test-crds-{{ helm_version | replace('.', '-') }}"
|
- "helm-test-crds"
|
||||||
- "helm-uninstall-{{ helm_version | replace('.', '-') }}"
|
- "helm-uninstall"
|
||||||
- "helm-read-envvars-{{ helm_version | replace('.', '-') }}"
|
- "helm-read-envvars"
|
||||||
- "helm-dep-update-{{ helm_version | replace('.', '-') }}"
|
- "helm-dep-update"
|
||||||
- "helm-local-path-001-{{ helm_version | replace('.', '-') }}"
|
- "helm-local-path-001"
|
||||||
- "helm-local-path-002-{{ helm_version | replace('.', '-') }}"
|
- "helm-local-path-002"
|
||||||
- "helm-local-path-003-{{ helm_version | replace('.', '-') }}"
|
- "helm-local-path-003"
|
||||||
- "helm-from-repository-{{ helm_version | replace('.', '-') }}"
|
- "helm-from-repository"
|
||||||
- "helm-from-url-{{ helm_version | replace('.', '-') }}"
|
- "helm-from-url"
|
||||||
- "helm-reuse-values-{{ helm_version | replace('.', '-') }}"
|
- "helm-reuse-values"
|
||||||
- "helm-chart-with-space-into-name-{{ helm_version | replace('.', '-') }}"
|
- "helm-chart-with-space-into-name"
|
||||||
- "helm-reset-then-reuse-values-{{ helm_version | replace('.', '-') }}"
|
- "helm-reset-then-reuse-values"
|
||||||
- "helm-insecure-{{ helm_version | replace('.', '-') }}"
|
- "helm-insecure"
|
||||||
- "helm-test-take-ownership-{{ helm_version | replace('.', '-') }}"
|
|
||||||
- "helm-skip-schema-validation-{{ helm_version | replace('.', '-') }}"
|
|
||||||
|
|||||||
@@ -52,9 +52,7 @@ import json
|
|||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.helm import (
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
AnsibleHelmModule,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class HelmReleaseNotFoundError(Exception):
|
class HelmReleaseNotFoundError(Exception):
|
||||||
@@ -62,9 +60,7 @@ class HelmReleaseNotFoundError(Exception):
|
|||||||
super().__init__(message)
|
super().__init__(message)
|
||||||
|
|
||||||
|
|
||||||
def create_pending_install_release(
|
def create_pending_install_release(helm_binary, chart_ref, chart_release, namespace):
|
||||||
module, helm_binary, chart_ref, chart_release, namespace
|
|
||||||
):
|
|
||||||
# create pending-install release
|
# create pending-install release
|
||||||
command = [
|
command = [
|
||||||
helm_binary,
|
helm_binary,
|
||||||
@@ -82,14 +78,13 @@ def create_pending_install_release(
|
|||||||
command = [
|
command = [
|
||||||
helm_binary,
|
helm_binary,
|
||||||
"list",
|
"list",
|
||||||
|
"--all",
|
||||||
"--output=json",
|
"--output=json",
|
||||||
"--namespace",
|
"--namespace",
|
||||||
namespace,
|
namespace,
|
||||||
"--filter",
|
"--filter",
|
||||||
chart_release,
|
chart_release,
|
||||||
]
|
]
|
||||||
if not module.is_helm_v4():
|
|
||||||
command.append("--all")
|
|
||||||
cmd = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
cmd = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
out, err = cmd.communicate()
|
out, err = cmd.communicate()
|
||||||
|
|
||||||
@@ -97,11 +92,11 @@ def create_pending_install_release(
|
|||||||
if not data:
|
if not data:
|
||||||
error = "Release %s not found." % chart_release
|
error = "Release %s not found." % chart_release
|
||||||
raise HelmReleaseNotFoundError(message=error)
|
raise HelmReleaseNotFoundError(message=error)
|
||||||
return data[0]["status"] in ("pending-install", "failed"), data[0]["status"]
|
return data[0]["status"] == "pending-install", data[0]["status"]
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
module = AnsibleHelmModule(
|
module = AnsibleModule(
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
binary_path=dict(type="path", required=True),
|
binary_path=dict(type="path", required=True),
|
||||||
chart_ref=dict(type="str", required=True),
|
chart_ref=dict(type="str", required=True),
|
||||||
@@ -111,7 +106,6 @@ def main():
|
|||||||
)
|
)
|
||||||
|
|
||||||
params = dict(
|
params = dict(
|
||||||
module=module,
|
|
||||||
helm_binary=module.params.get("binary_path"),
|
helm_binary=module.params.get("binary_path"),
|
||||||
chart_release=module.params.get("chart_release"),
|
chart_release=module.params.get("chart_release"),
|
||||||
chart_ref=module.params.get("chart_ref"),
|
chart_ref=module.params.get("chart_ref"),
|
||||||
@@ -122,7 +116,7 @@ def main():
|
|||||||
result, status = create_pending_install_release(**params)
|
result, status = create_pending_install_release(**params)
|
||||||
if not result:
|
if not result:
|
||||||
module.fail_json(
|
module.fail_json(
|
||||||
msg="unable to create pending-install/failed release, current status is %s"
|
msg="unable to create pending-install release, current status is %s"
|
||||||
% status
|
% status
|
||||||
)
|
)
|
||||||
module.exit_json(changed=True, msg="Release created with status '%s'" % status)
|
module.exit_json(changed=True, msg="Release created with status '%s'" % status)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
---
|
---
|
||||||
collections:
|
collections:
|
||||||
- kubernetes.core
|
- kubernetes.core
|
||||||
|
dependencies:
|
||||||
|
- remove_namespace
|
||||||
|
|||||||
7
tests/integration/targets/helm/playbook.yaml
Normal file
7
tests/integration/targets/helm/playbook.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
- connection: local
|
||||||
|
gather_facts: true
|
||||||
|
hosts: localhost
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- helm
|
||||||
15
tests/integration/targets/helm/tasks/install.yml
Normal file
15
tests/integration/targets/helm/tasks/install.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
- name: Init Helm folders
|
||||||
|
file:
|
||||||
|
path: /tmp/helm/
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: Unarchive Helm binary
|
||||||
|
unarchive:
|
||||||
|
src: 'https://get.helm.sh/{{ helm_archive_name | default(helm_default_archive_name) }}'
|
||||||
|
dest: /tmp/helm/
|
||||||
|
remote_src: yes
|
||||||
|
retries: 10
|
||||||
|
delay: 5
|
||||||
|
register: result
|
||||||
|
until: result is not failed
|
||||||
@@ -1,22 +1,10 @@
|
|||||||
---
|
---
|
||||||
- name: Ensure helm is not installed
|
|
||||||
file:
|
|
||||||
path: "{{ item }}"
|
|
||||||
state: absent
|
|
||||||
with_items:
|
|
||||||
- "/tmp/helm"
|
|
||||||
|
|
||||||
- name: Check failed if helm is not installed
|
|
||||||
include_tasks: test_helm_not_installed.yml
|
|
||||||
|
|
||||||
- name: Install Helm v4
|
|
||||||
ansible.builtin.include_role:
|
|
||||||
name: install_helm
|
|
||||||
vars:
|
|
||||||
helm_version: v3.6.0
|
|
||||||
|
|
||||||
- name: Test helm uninstall
|
|
||||||
ansible.builtin.include_tasks: test_helm_uninstall.yml
|
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
include_tasks: run_test.yml
|
include_tasks: run_test.yml
|
||||||
|
loop_control:
|
||||||
|
loop_var: helm_version
|
||||||
|
with_items:
|
||||||
|
- "v3.15.4"
|
||||||
|
- "v3.16.0"
|
||||||
|
- "v3.17.0"
|
||||||
|
- "v4.0.0"
|
||||||
|
|||||||
@@ -1,19 +1,25 @@
|
|||||||
---
|
---
|
||||||
|
- name: Ensure helm is not installed
|
||||||
|
file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
with_items:
|
||||||
|
- "/tmp/helm"
|
||||||
|
|
||||||
|
- name: Check failed if helm is not installed
|
||||||
|
include_tasks: test_helm_not_installed.yml
|
||||||
|
|
||||||
- name: "Install {{ helm_version }}"
|
- name: "Install {{ helm_version }}"
|
||||||
include_role:
|
include_role:
|
||||||
name: install_helm
|
name: install_helm
|
||||||
|
|
||||||
- name: Main helm tests
|
- name: Main helm tests with Helm v3
|
||||||
|
when: helm_version != "v4.0.0"
|
||||||
block:
|
block:
|
||||||
- name: Install helm-diff plugin
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
plugin_path: https://github.com/databus23/helm-diff
|
|
||||||
plugin_version: "{{ helm_version is version('v4.0.0', '>=') | ternary('v3.14.0', 'v3.10.0') }}"
|
|
||||||
verify: false
|
|
||||||
|
|
||||||
- name: "Ensure we honor the environment variables"
|
- name: "Ensure we honor the environment variables"
|
||||||
include_tasks: test_read_envvars.yml
|
include_tasks: test_read_envvars.yml
|
||||||
|
when: helm_version != "v4.0.0"
|
||||||
|
|
||||||
- name: Deploy charts
|
- name: Deploy charts
|
||||||
include_tasks: "tests_chart/{{ test_chart_type }}.yml"
|
include_tasks: "tests_chart/{{ test_chart_type }}.yml"
|
||||||
@@ -33,6 +39,9 @@
|
|||||||
- name: test helm dependency update
|
- name: test helm dependency update
|
||||||
include_tasks: test_up_dep.yml
|
include_tasks: test_up_dep.yml
|
||||||
|
|
||||||
|
- name: Test helm uninstall
|
||||||
|
include_tasks: test_helm_uninstall.yml
|
||||||
|
|
||||||
- name: Test helm install with chart name containing space
|
- name: Test helm install with chart name containing space
|
||||||
include_tasks: test_helm_with_space_into_chart_name.yml
|
include_tasks: test_helm_with_space_into_chart_name.yml
|
||||||
|
|
||||||
@@ -43,21 +52,12 @@
|
|||||||
- name: Test insecure registry flag feature
|
- name: Test insecure registry flag feature
|
||||||
include_tasks: test_helm_insecure.yml
|
include_tasks: test_helm_insecure.yml
|
||||||
|
|
||||||
- name: Test take ownership flag feature
|
- name: Test helm version
|
||||||
include_tasks: test_helm_take_ownership.yml
|
include_tasks: test_helm_version.yml
|
||||||
|
|
||||||
- name: Test helm skip_schema_validation
|
- name: Clean helm install
|
||||||
include_tasks: test_skip_schema_validation.yml
|
file:
|
||||||
|
path: "{{ item }}"
|
||||||
always:
|
|
||||||
- name: Remove helm-diff plugin
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
plugin_name: diff
|
|
||||||
state: absent
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Clean helm install
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: "/tmp/helm/"
|
|
||||||
state: absent
|
state: absent
|
||||||
|
with_items:
|
||||||
|
- "/tmp/helm/"
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
name: test
|
name: test
|
||||||
chart_ref: "{{ chart_test }}"
|
chart_ref: "{{ chart_test }}"
|
||||||
namespace: "helm-test"
|
namespace: "helm-test"
|
||||||
ignore_errors: true
|
ignore_errors: yes
|
||||||
register: helm_missing_binary
|
register: helm_missing_binary
|
||||||
|
|
||||||
- name: Assert that helm is not installed
|
- name: Assert that helm is not installed
|
||||||
|
|||||||
@@ -38,28 +38,6 @@
|
|||||||
- '"--reset-then-reuse-values" not in install.command'
|
- '"--reset-then-reuse-values" not in install.command'
|
||||||
- release_value["status"]["release_values"] == chart_release_values
|
- release_value["status"]["release_values"] == chart_release_values
|
||||||
|
|
||||||
# We need to provide the actual redis password otherwise the update command
|
|
||||||
# will fail with the following:
|
|
||||||
# Error: execution error at (redis/templates/replicas/application.yaml:55:35):
|
|
||||||
# PASSWORDS ERROR: You must provide your current passwords when upgrading the release.
|
|
||||||
# Note that even after reinstallation, old credentials may be needed as they may be kept in persistent volume claims.
|
|
||||||
# Further information can be obtained at https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues/#credential-errors-while-upgrading-chart-releases
|
|
||||||
# 'global.redis.password' must not be empty, please add '--set global.redis.password=$REDIS_PASSWORD' to the command. To get the current value:
|
|
||||||
- name: Retrieve release password
|
|
||||||
kubernetes.core.k8s_info:
|
|
||||||
namespace: "{{ helm_namespace }}"
|
|
||||||
kind: Secret
|
|
||||||
name: test-redis
|
|
||||||
register: redis_secret
|
|
||||||
|
|
||||||
- ansible.builtin.set_fact:
|
|
||||||
chart_reset_then_reuse_values: "{{ chart_reset_then_reuse_values | combine(redis_global_password) }}"
|
|
||||||
vars:
|
|
||||||
redis_global_password:
|
|
||||||
global:
|
|
||||||
redis:
|
|
||||||
password: "{{ redis_secret.resources.0.data['redis-password'] | b64decode }}"
|
|
||||||
|
|
||||||
- name: Upgrade chart using reset_then_reuse_values=true
|
- name: Upgrade chart using reset_then_reuse_values=true
|
||||||
helm:
|
helm:
|
||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
@@ -95,4 +73,3 @@
|
|||||||
kind: Namespace
|
kind: Namespace
|
||||||
name: "{{ helm_namespace }}"
|
name: "{{ helm_namespace }}"
|
||||||
state: absent
|
state: absent
|
||||||
wait: false
|
|
||||||
|
|||||||
@@ -38,21 +38,6 @@
|
|||||||
- '"--reuse-values=True" not in install.command'
|
- '"--reuse-values=True" not in install.command'
|
||||||
- release_value["status"]["release_values"] == chart_release_values
|
- release_value["status"]["release_values"] == chart_release_values
|
||||||
|
|
||||||
- name: Retrieve release password
|
|
||||||
kubernetes.core.k8s_info:
|
|
||||||
namespace: "{{ helm_namespace }}"
|
|
||||||
kind: Secret
|
|
||||||
name: test-redis
|
|
||||||
register: redis_secret
|
|
||||||
|
|
||||||
- ansible.builtin.set_fact:
|
|
||||||
chart_reuse_values: "{{ chart_reuse_values | combine(redis_global_password) }}"
|
|
||||||
vars:
|
|
||||||
redis_global_password:
|
|
||||||
global:
|
|
||||||
redis:
|
|
||||||
password: "{{ redis_secret.resources.0.data['redis-password'] | b64decode }}"
|
|
||||||
|
|
||||||
- name: Upgrade chart using reuse_values=true
|
- name: Upgrade chart using reuse_values=true
|
||||||
helm:
|
helm:
|
||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
|
|||||||
@@ -1,101 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Test helm take ownership
|
|
||||||
vars:
|
|
||||||
helm_namespace: "{{ test_namespace[13] }}"
|
|
||||||
block:
|
|
||||||
|
|
||||||
- name: Initial chart installation (no flag set)
|
|
||||||
helm:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
chart_ref: "{{ chart_test_oci }}"
|
|
||||||
release_name: test-take-ownership
|
|
||||||
release_namespace: "{{ helm_namespace }}"
|
|
||||||
create_namespace: true
|
|
||||||
register: install
|
|
||||||
|
|
||||||
- name: Validate that take-ownership flag is not set
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- install is changed
|
|
||||||
- '"--take-ownership" not in install.command'
|
|
||||||
|
|
||||||
# We need to provide the actual redis password otherwise the update command
|
|
||||||
# will fail with the following:
|
|
||||||
# Error: execution error at (redis/templates/replicas/application.yaml:55:35):
|
|
||||||
# PASSWORDS ERROR: You must provide your current passwords when upgrading the release.
|
|
||||||
# Note that even after reinstallation, old credentials may be needed as they may be kept in persistent volume claims.
|
|
||||||
# Further information can be obtained at https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues/#credential-errors-while-upgrading-chart-releases
|
|
||||||
# 'global.redis.password' must not be empty, please add '--set global.redis.password=$REDIS_PASSWORD' to the command. To get the current value:
|
|
||||||
- name: Retrieve release password
|
|
||||||
kubernetes.core.k8s_info:
|
|
||||||
namespace: "{{ helm_namespace }}"
|
|
||||||
kind: Secret
|
|
||||||
name: test-take-ownership-redis
|
|
||||||
register: redis_secret
|
|
||||||
|
|
||||||
- name: Upgrade chart (take-onwership flag set)
|
|
||||||
helm:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
chart_ref: "{{ chart_test_oci }}"
|
|
||||||
release_name: test-take-ownership
|
|
||||||
release_namespace: "{{ helm_namespace }}"
|
|
||||||
take_ownership: true
|
|
||||||
values:
|
|
||||||
commonLabels:
|
|
||||||
take-onwership: "set"
|
|
||||||
global:
|
|
||||||
redis:
|
|
||||||
password: "{{ redis_secret.resources.0.data['redis-password'] | b64decode }}"
|
|
||||||
register: upgrade
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Validate that take-ownership flag IS set if helm version is >= 3.17.0
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- upgrade is changed
|
|
||||||
- '"--take-ownership" in upgrade.command'
|
|
||||||
when: '"v3.17.0" <= helm_version'
|
|
||||||
|
|
||||||
- name: Validate that feature fails for helm < 3.17.0
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- upgrade is failed
|
|
||||||
- '"take_ownership requires helm >= 3.17.0" in upgrade.msg'
|
|
||||||
when: 'helm_version < "v3.17.0"'
|
|
||||||
|
|
||||||
- name: Upgrade chart (take-onwership flag not set)
|
|
||||||
helm:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
chart_ref: "{{ chart_test_oci }}"
|
|
||||||
release_name: test-take-ownership
|
|
||||||
release_namespace: "{{ helm_namespace }}"
|
|
||||||
values:
|
|
||||||
commonLabels:
|
|
||||||
take-onwership: "not-set"
|
|
||||||
global:
|
|
||||||
redis:
|
|
||||||
password: "{{ redis_secret.resources.0.data['redis-password'] | b64decode }}"
|
|
||||||
register: upgrade
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Validate that take-ownership flag IS set if helm version is >= 3.17.0
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- upgrade is changed
|
|
||||||
- '"--take-ownership" not in upgrade.command'
|
|
||||||
when: '"v3.17.0" <= helm_version'
|
|
||||||
|
|
||||||
- name: Validate that feature fails for helm < 3.17.0
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- upgrade is changed
|
|
||||||
- upgrade.msg is not defined
|
|
||||||
when: 'helm_version < "v3.17.0"'
|
|
||||||
|
|
||||||
always:
|
|
||||||
- name: Remove helm namespace
|
|
||||||
k8s:
|
|
||||||
api_version: v1
|
|
||||||
kind: Namespace
|
|
||||||
name: "{{ helm_namespace }}"
|
|
||||||
state: absent
|
|
||||||
@@ -31,18 +31,26 @@
|
|||||||
- name: assert warning has been raised
|
- name: assert warning has been raised
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- uninstall.warnings is defined
|
- uninstall.warnings
|
||||||
- '"helm uninstall support option --wait for helm release >= 3.7.0" in uninstall.warnings'
|
|
||||||
|
|
||||||
- name: Install Helm v4
|
- name: Create temp directory
|
||||||
ansible.builtin.include_role:
|
tempfile:
|
||||||
name: install_helm
|
state: directory
|
||||||
vars:
|
suffix: .test
|
||||||
helm_version: v4.0.0
|
register: _result
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
helm_tmp_dir: "{{ _result.path }}"
|
||||||
|
|
||||||
|
- name: Unarchive Helm binary
|
||||||
|
unarchive:
|
||||||
|
src: 'https://get.helm.sh/helm-v3.7.0-linux-amd64.tar.gz'
|
||||||
|
dest: "{{ helm_tmp_dir }}"
|
||||||
|
remote_src: yes
|
||||||
|
|
||||||
- name: Install chart
|
- name: Install chart
|
||||||
helm:
|
helm:
|
||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_tmp_dir }}/linux-amd64/helm"
|
||||||
name: "{{ chart_name }}"
|
name: "{{ chart_name }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
@@ -51,7 +59,7 @@
|
|||||||
- name: uninstall chart again using recent version
|
- name: uninstall chart again using recent version
|
||||||
helm:
|
helm:
|
||||||
state: absent
|
state: absent
|
||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_tmp_dir }}/linux-amd64/helm"
|
||||||
name: "{{ chart_name }}"
|
name: "{{ chart_name }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
wait: yes
|
wait: yes
|
||||||
@@ -88,6 +96,12 @@
|
|||||||
- _info.status is undefined
|
- _info.status is undefined
|
||||||
|
|
||||||
always:
|
always:
|
||||||
|
- name: Delete temp directory
|
||||||
|
file:
|
||||||
|
path: "{{ helm_tmp_dir }}"
|
||||||
|
state: absent
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
- name: Remove namespace
|
- name: Remove namespace
|
||||||
k8s:
|
k8s:
|
||||||
kind: Namespace
|
kind: Namespace
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
---
|
---
|
||||||
- name: Test helm skip_schema_validation
|
- name: Test helm reuse_values
|
||||||
vars:
|
vars:
|
||||||
helm_namespace: "{{ test_namespace[14] }}"
|
helm_namespace: "{{ test_namespace[12] }}"
|
||||||
chart_release_values:
|
chart_release_values:
|
||||||
replica:
|
replica:
|
||||||
replicaCount: 3
|
replicaCount: 3
|
||||||
master:
|
master:
|
||||||
count: 1
|
count: 1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
|
chart_reuse_values:
|
||||||
|
replica:
|
||||||
|
replicaCount: 1
|
||||||
|
master:
|
||||||
|
count: 3
|
||||||
block:
|
block:
|
||||||
- name: Chart installation
|
- name: Initial chart installation
|
||||||
helm:
|
helm:
|
||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
chart_ref: oci://registry-1.docker.io/bitnamicharts/redis
|
chart_ref: oci://registry-1.docker.io/bitnamicharts/redis
|
||||||
@@ -17,27 +22,21 @@
|
|||||||
release_namespace: "{{ helm_namespace }}"
|
release_namespace: "{{ helm_namespace }}"
|
||||||
create_namespace: true
|
create_namespace: true
|
||||||
release_values: "{{ chart_release_values }}"
|
release_values: "{{ chart_release_values }}"
|
||||||
skip_schema_validation: true
|
|
||||||
register: install
|
register: install
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
|
when: helm_version == "v4.0.0"
|
||||||
|
|
||||||
- name: Debug install result
|
- name: Debug install result
|
||||||
debug:
|
debug:
|
||||||
var: install
|
var: install
|
||||||
|
when: helm_version == "v4.0.0"
|
||||||
|
|
||||||
- name: Validate skip_schema_validation with helm >= 3.16.0 works
|
- name: Ensure helm installation was failed for v4.0.0
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- install is changed
|
|
||||||
- "'--skip-schema-validation' in install.command"
|
|
||||||
when: "helm_version is ansible.builtin.version('v3.16.0', '>=')"
|
|
||||||
|
|
||||||
- name: Validate skip_schema_validation with helm < 3.16.0 fails
|
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- install is failed
|
- install is failed
|
||||||
- "'skip_schema_validation requires helm >= 3.16.0' in install.msg"
|
- "'Helm version must be >=3.0.0,<4.0.0' in install.msg"
|
||||||
when: "helm_version is ansible.builtin.version('v3.16.0', '<')"
|
when: helm_version == "v4.0.0"
|
||||||
|
|
||||||
always:
|
always:
|
||||||
- name: Remove helm namespace
|
- name: Remove helm namespace
|
||||||
@@ -30,9 +30,9 @@
|
|||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: "{{ chart_release_name }}"
|
name: "{{ chart_release_name }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
chart_version: "{{ chart_test_version }}"
|
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
ignore_errors: true
|
ignore_errors: yes
|
||||||
register: install_fail
|
register: install_fail
|
||||||
|
|
||||||
- name: "Assert that Install fail {{ chart_test }} from {{ source }}"
|
- name: "Assert that Install fail {{ chart_test }} from {{ source }}"
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: "{{ chart_release_name }}"
|
name: "{{ chart_release_name }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
chart_version: "{{ chart_test_version }}"
|
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
create_namespace: true
|
create_namespace: true
|
||||||
register: install_check_mode
|
register: install_check_mode
|
||||||
@@ -64,18 +64,17 @@
|
|||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: "{{ chart_release_name }}"
|
name: "{{ chart_release_name }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
chart_version: "{{ chart_test_version }}"
|
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
create_namespace: true
|
create_namespace: true
|
||||||
register: install
|
register: install
|
||||||
|
|
||||||
- name: "Assert that {{ chart_test }} chart version {{ chart_test_version }} is installed from {{ source }}"
|
- name: "Assert that {{ chart_test }} chart is installed from {{ source }}"
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- install is changed
|
- install is changed
|
||||||
- install.status.chart == chart_test+"-"+chart_test_version
|
- install.status.chart == chart_test+"-"+chart_test_version
|
||||||
- install.status.status | lower == 'deployed'
|
- install.status.status | lower == 'deployed'
|
||||||
- install.status.release_values == {}
|
|
||||||
|
|
||||||
- name: Check helm_info content
|
- name: Check helm_info content
|
||||||
helm_info:
|
helm_info:
|
||||||
@@ -93,7 +92,7 @@
|
|||||||
- deployed
|
- deployed
|
||||||
register: release_state_content_info
|
register: release_state_content_info
|
||||||
|
|
||||||
- name: "Assert that {{ chart_test }} chart version {{ chart_test_version }} is installed from {{ source }} with helm_info"
|
- name: "Assert that {{ chart_test }} is installed from {{ source }} with helm_info"
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- content_info.status.chart == chart_test+"-"+chart_test_version
|
- content_info.status.chart == chart_test+"-"+chart_test_version
|
||||||
@@ -105,10 +104,9 @@
|
|||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: "{{ chart_release_name }}"
|
name: "{{ chart_release_name }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
chart_version: "{{ chart_test_version }}"
|
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
register: install
|
register: install
|
||||||
diff: true
|
|
||||||
|
|
||||||
- name: Assert idempotency
|
- name: Assert idempotency
|
||||||
assert:
|
assert:
|
||||||
@@ -122,7 +120,7 @@
|
|||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: "{{ chart_release_name }}"
|
name: "{{ chart_release_name }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
chart_version: "{{ chart_test_version }}"
|
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
values: "{{ chart_test_values }}"
|
values: "{{ chart_test_values }}"
|
||||||
register: install
|
register: install
|
||||||
@@ -133,18 +131,17 @@
|
|||||||
- install is changed
|
- install is changed
|
||||||
- install.status.status | lower == 'deployed'
|
- install.status.status | lower == 'deployed'
|
||||||
- install.status.chart == chart_test+"-"+chart_test_version
|
- install.status.chart == chart_test+"-"+chart_test_version
|
||||||
- install.status['release_values'] == chart_test_values
|
- "install.status['release_values'].revisionHistoryLimit == 0"
|
||||||
|
|
||||||
- name: Check idempotency after adding vars
|
- name: Check idempotency after adding vars
|
||||||
helm:
|
helm:
|
||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: "{{ chart_release_name }}"
|
name: "{{ chart_release_name }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
chart_version: "{{ chart_test_version }}"
|
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
values: "{{ chart_test_values }}"
|
values: "{{ chart_test_values }}"
|
||||||
register: install
|
register: install
|
||||||
diff: true
|
|
||||||
|
|
||||||
- name: Assert idempotency after add vars
|
- name: Assert idempotency after add vars
|
||||||
assert:
|
assert:
|
||||||
@@ -152,14 +149,14 @@
|
|||||||
- install is not changed
|
- install is not changed
|
||||||
- install.status.status | lower == 'deployed'
|
- install.status.status | lower == 'deployed'
|
||||||
- install.status.chart == chart_test+"-"+chart_test_version
|
- install.status.chart == chart_test+"-"+chart_test_version
|
||||||
- install.status['release_values'] == chart_test_values
|
- "install.status['release_values'].revisionHistoryLimit == 0"
|
||||||
|
|
||||||
- name: "Remove Vars to {{ chart_test }} from {{ source }}"
|
- name: "Remove Vars to {{ chart_test }} from {{ source }}"
|
||||||
helm:
|
helm:
|
||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: "{{ chart_release_name }}"
|
name: "{{ chart_release_name }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
chart_version: "{{ chart_test_version }}"
|
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
register: install
|
register: install
|
||||||
|
|
||||||
@@ -176,10 +173,9 @@
|
|||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: "{{ chart_release_name }}"
|
name: "{{ chart_release_name }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
chart_version: "{{ chart_test_version }}"
|
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
register: install
|
register: install
|
||||||
diff: true
|
|
||||||
|
|
||||||
- name: Assert idempotency after removing vars
|
- name: Assert idempotency after removing vars
|
||||||
assert:
|
assert:
|
||||||
@@ -194,7 +190,7 @@
|
|||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: "{{ chart_release_name }}"
|
name: "{{ chart_release_name }}"
|
||||||
chart_ref: "{{ chart_source_upgrade | default(chart_source) }}"
|
chart_ref: "{{ chart_source_upgrade | default(chart_source) }}"
|
||||||
chart_version: "{{ chart_test_version_upgrade }}"
|
chart_version: "{{ chart_source_version_upgrade | default(omit) }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
register: install
|
register: install
|
||||||
|
|
||||||
@@ -210,10 +206,9 @@
|
|||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: "{{ chart_release_name }}"
|
name: "{{ chart_release_name }}"
|
||||||
chart_ref: "{{ chart_source_upgrade | default(chart_source) }}"
|
chart_ref: "{{ chart_source_upgrade | default(chart_source) }}"
|
||||||
chart_version: "{{ chart_test_version_upgrade }}"
|
chart_version: "{{ chart_source_version_upgrade | default(omit) }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
register: install
|
register: install
|
||||||
diff: true
|
|
||||||
|
|
||||||
- name: Assert idempotency after upgrade
|
- name: Assert idempotency after upgrade
|
||||||
assert:
|
assert:
|
||||||
@@ -242,7 +237,6 @@
|
|||||||
name: "{{ chart_release_name }}"
|
name: "{{ chart_release_name }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
register: install
|
register: install
|
||||||
diff: true
|
|
||||||
|
|
||||||
- name: Assert idempotency
|
- name: Assert idempotency
|
||||||
assert:
|
assert:
|
||||||
@@ -255,7 +249,7 @@
|
|||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: "{{ chart_release_replaced_name }}"
|
name: "{{ chart_release_replaced_name }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
chart_version: "{{ chart_test_version }}"
|
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
register: install
|
register: install
|
||||||
|
|
||||||
@@ -283,7 +277,7 @@
|
|||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: "{{ chart_release_replaced_name }}"
|
name: "{{ chart_release_replaced_name }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
chart_version: "{{ chart_test_version }}"
|
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
replace: True
|
replace: True
|
||||||
register: install
|
register: install
|
||||||
@@ -311,7 +305,7 @@
|
|||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: "{{ chart_release_name }}"
|
name: "{{ chart_release_name }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
chart_version: "{{ chart_test_version }}"
|
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
values_files:
|
values_files:
|
||||||
- "{{ role_path }}/files/values.yaml"
|
- "{{ role_path }}/files/values.yaml"
|
||||||
@@ -330,7 +324,7 @@
|
|||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: "{{ chart_release_name }}"
|
name: "{{ chart_release_name }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
chart_version: "{{ chart_test_version }}"
|
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
values_files:
|
values_files:
|
||||||
- "{{ role_path }}/files/values.yaml"
|
- "{{ role_path }}/files/values.yaml"
|
||||||
@@ -352,7 +346,7 @@
|
|||||||
helm_template:
|
helm_template:
|
||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
chart_version: "{{ chart_test_version }}"
|
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||||
output_dir: "{{ temp_dir }}"
|
output_dir: "{{ temp_dir }}"
|
||||||
values_files:
|
values_files:
|
||||||
- "{{ role_path }}/files/values.yaml"
|
- "{{ role_path }}/files/values.yaml"
|
||||||
@@ -378,7 +372,7 @@
|
|||||||
helm_template:
|
helm_template:
|
||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
chart_version: "{{ chart_test_version }}"
|
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||||
disable_hook: True
|
disable_hook: True
|
||||||
release_name: "myrelease"
|
release_name: "myrelease"
|
||||||
release_namespace: "myreleasenamespace"
|
release_namespace: "myreleasenamespace"
|
||||||
@@ -404,7 +398,7 @@
|
|||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: "{{ chart_release_name }}"
|
name: "{{ chart_release_name }}"
|
||||||
chart_ref: "{{ chart_source }}"
|
chart_ref: "{{ chart_source }}"
|
||||||
chart_version: "{{ chart_test_version }}"
|
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
create_namespace: true
|
create_namespace: true
|
||||||
context: does-not-exist
|
context: does-not-exist
|
||||||
@@ -423,7 +417,6 @@
|
|||||||
state: absent
|
state: absent
|
||||||
path: "{{ temp_dir }}"
|
path: "{{ temp_dir }}"
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
when: temp_dir is defined
|
|
||||||
|
|
||||||
- name: Remove helm namespace
|
- name: Remove helm namespace
|
||||||
k8s:
|
k8s:
|
||||||
|
|||||||
@@ -5,36 +5,16 @@
|
|||||||
name: test_helm
|
name: test_helm
|
||||||
repo_url: "{{ chart_test_repo }}"
|
repo_url: "{{ chart_test_repo }}"
|
||||||
|
|
||||||
- name: Create temporary file to save values in
|
- name: Install Chart from repository
|
||||||
ansible.builtin.tempfile:
|
include_tasks: "../tests_chart.yml"
|
||||||
suffix: .helm_values
|
vars:
|
||||||
register: value_file
|
|
||||||
|
|
||||||
- vars:
|
|
||||||
source: repository
|
source: repository
|
||||||
chart_test: k8status
|
chart_source: "test_helm/{{ chart_test }}"
|
||||||
chart_source: "test_helm/k8status"
|
chart_source_version: "{{ chart_test_version }}"
|
||||||
chart_test_version: "0.16.1"
|
chart_source_version_upgrade: "{{ chart_test_version_upgrade }}"
|
||||||
chart_test_version_upgrade: "0.16.2"
|
|
||||||
helm_namespace: "{{ test_namespace[7] }}"
|
helm_namespace: "{{ test_namespace[7] }}"
|
||||||
chart_test_values:
|
|
||||||
replicaCount: 3
|
|
||||||
block:
|
|
||||||
- name: Save values into file
|
|
||||||
ansible.builtin.copy:
|
|
||||||
content: "{{ chart_test_values }}"
|
|
||||||
dest: "{{ value_file.path }}"
|
|
||||||
|
|
||||||
- name: Install Chart from repository
|
- name: Remove chart repo
|
||||||
ansible.builtin.include_tasks: "../tests_chart.yml"
|
|
||||||
|
|
||||||
always:
|
|
||||||
- name: Remove temporary file
|
|
||||||
ansible.builtin.file:
|
|
||||||
state: absent
|
|
||||||
path: "{{ value_file.path }}"
|
|
||||||
|
|
||||||
- name: Remove chart repo
|
|
||||||
helm_repository:
|
helm_repository:
|
||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
name: test_helm
|
name: test_helm
|
||||||
|
|||||||
@@ -3,11 +3,6 @@
|
|||||||
include_tasks: "../tests_chart.yml"
|
include_tasks: "../tests_chart.yml"
|
||||||
vars:
|
vars:
|
||||||
source: url
|
source: url
|
||||||
chart_test: "k8status"
|
chart_source: "https://github.com/kubernetes/ingress-nginx/releases/download/helm-chart-{{ chart_test_version }}/{{ chart_test }}-{{ chart_test_version }}.tgz"
|
||||||
chart_test_values:
|
chart_source_upgrade: "https://github.com/kubernetes/ingress-nginx/releases/download/helm-chart-{{ chart_test_version_upgrade }}/{{ chart_test }}-{{ chart_test_version_upgrade }}.tgz"
|
||||||
replicaCount: 3
|
|
||||||
chart_test_version: "0.16.1"
|
|
||||||
chart_test_version_upgrade: "0.16.2"
|
|
||||||
chart_source: https://github.com/stenic/k8status/releases/download/k8status-0.16.1/k8status-0.16.1.tgz
|
|
||||||
chart_source_upgrade: https://github.com/stenic/k8status/releases/download/k8status-0.16.2/k8status-0.16.2.tgz
|
|
||||||
helm_namespace: "{{ test_namespace[8] }}"
|
helm_namespace: "{{ test_namespace[8] }}"
|
||||||
|
|||||||
@@ -239,7 +239,6 @@
|
|||||||
vars:
|
vars:
|
||||||
chart_local_path: '{{ _tmpd.path }}/test-chart-deployment-time'
|
chart_local_path: '{{ _tmpd.path }}/test-chart-deployment-time'
|
||||||
chart_repo_path: 'testing'
|
chart_repo_path: 'testing'
|
||||||
helm_binary_path: "{{ helm_binary }}"
|
|
||||||
always:
|
always:
|
||||||
- name: Delete temporary directory
|
- name: Delete temporary directory
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
|
|||||||
@@ -92,11 +92,25 @@
|
|||||||
path: /tmp/helm/
|
path: /tmp/helm/
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: Install old version of helm
|
- name: Init Helm folders
|
||||||
ansible.builtin.include_role:
|
file:
|
||||||
name: install_helm
|
path: /tmp/helm
|
||||||
vars:
|
state: directory
|
||||||
helm_version: "v3.8.0"
|
|
||||||
|
- name: Set Helm old version
|
||||||
|
set_fact:
|
||||||
|
helm_archive_name: "helm-v3.8.0-linux-amd64.tar.gz"
|
||||||
|
helm_diff_old_version: "3.8.0"
|
||||||
|
|
||||||
|
- name: Unarchive Helm binary
|
||||||
|
unarchive:
|
||||||
|
src: "https://get.helm.sh/{{ helm_archive_name | default(helm_default_archive_name) }}"
|
||||||
|
dest: /tmp/helm/
|
||||||
|
remote_src: yes
|
||||||
|
retries: 10
|
||||||
|
delay: 5
|
||||||
|
register: result
|
||||||
|
until: result is not failed
|
||||||
|
|
||||||
- name: Upgrade helm release (with reset_then_reuse_values=true)
|
- name: Upgrade helm release (with reset_then_reuse_values=true)
|
||||||
kubernetes.core.helm:
|
kubernetes.core.helm:
|
||||||
@@ -126,7 +140,7 @@
|
|||||||
binary_path: "{{ helm_binary }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
state: present
|
state: present
|
||||||
plugin_path: https://github.com/databus23/helm-diff
|
plugin_path: https://github.com/databus23/helm-diff
|
||||||
plugin_version: "3.8.0"
|
plugin_version: "{{ helm_diff_old_version }}"
|
||||||
|
|
||||||
- name: Upgrade helm release (with reset_then_reuse_values=true)
|
- name: Upgrade helm release (with reset_then_reuse_values=true)
|
||||||
kubernetes.core.helm:
|
kubernetes.core.helm:
|
||||||
@@ -152,11 +166,6 @@
|
|||||||
- '"reset_then_reuse_values requires helm diff >= 3.9.12, current version is" in helm_upgrade.msg'
|
- '"reset_then_reuse_values requires helm diff >= 3.9.12, current version is" in helm_upgrade.msg'
|
||||||
|
|
||||||
always:
|
always:
|
||||||
- name: Delete Helm folders
|
|
||||||
file:
|
|
||||||
path: /tmp/helm/
|
|
||||||
state: absent
|
|
||||||
|
|
||||||
- name: Remove temporary directory
|
- name: Remove temporary directory
|
||||||
file:
|
file:
|
||||||
path: "{{ helm_dir.path }}"
|
path: "{{ helm_dir.path }}"
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
---
|
---
|
||||||
|
helm_binary: "/tmp/helm/{{ ansible_system | lower }}-amd64/helm"
|
||||||
default_kubeconfig_path: "~/.kube/config"
|
default_kubeconfig_path: "~/.kube/config"
|
||||||
test_namespace:
|
test_namespace:
|
||||||
- "helm-in-memory-kubeconfig"
|
- "helm-in-memory-kubeconfig"
|
||||||
- "helm-kubeconfig-with-ca-cert"
|
- "helm-kubeconfig-with-ca-cert"
|
||||||
- "helm-kubeconfig-with-insecure-skip-tls-verify"
|
- "helm-kubeconfig-with-insecure-skip-tls-verify"
|
||||||
helm_versions:
|
|
||||||
- v3.10.3
|
|
||||||
- v3.16.4
|
|
||||||
- v4.0.0
|
|
||||||
|
|||||||
4
tests/integration/targets/helm_kubeconfig/meta/main.yml
Normal file
4
tests/integration/targets/helm_kubeconfig/meta/main.yml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- remove_namespace
|
||||||
|
- install_helm
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- _install is failed
|
- _install is failed
|
||||||
- '"error: kubernetes cluster unreachable" in _install.msg | lower()'
|
- '"Error: Kubernetes cluster unreachable" in _install.msg'
|
||||||
|
|
||||||
- name: Test helm modules using in-memory kubeconfig
|
- name: Test helm modules using in-memory kubeconfig
|
||||||
include_tasks: "tests_helm_auth.yml"
|
include_tasks: "tests_helm_auth.yml"
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- _install is failed
|
- _install is failed
|
||||||
- '"error: kubernetes cluster unreachable" in _install.msg | lower()'
|
- '"Error: Kubernetes cluster unreachable" in _install.msg'
|
||||||
|
|
||||||
- name: Test helm modules using in-memory kubeconfig
|
- name: Test helm modules using in-memory kubeconfig
|
||||||
include_tasks: "tests_helm_auth.yml"
|
include_tasks: "tests_helm_auth.yml"
|
||||||
|
|||||||
@@ -1,5 +1,21 @@
|
|||||||
---
|
---
|
||||||
- ansible.builtin.include_tasks: run_tests.yml
|
- name: Test helm with in-memory kubeconfig
|
||||||
loop: "{{ helm_versions }}"
|
include_tasks: "from_in_memory_kubeconfig.yml"
|
||||||
loop_control:
|
loop_control:
|
||||||
loop_var: helm_version
|
loop_var: test_helm_version
|
||||||
|
with_items:
|
||||||
|
- "v3.10.3"
|
||||||
|
|
||||||
|
- name: Test helm with custom kubeconfig and validate_certs=false
|
||||||
|
include_tasks: "from_kubeconfig_with_validate_certs.yml"
|
||||||
|
loop_control:
|
||||||
|
loop_var: test_helm_version
|
||||||
|
with_items:
|
||||||
|
- "v3.10.3"
|
||||||
|
|
||||||
|
- name: Test helm with custom kubeconfig and ca_cert
|
||||||
|
include_tasks: "from_kubeconfig_with_cacert.yml"
|
||||||
|
loop_control:
|
||||||
|
loop_var: test_helm_version
|
||||||
|
with_items:
|
||||||
|
- "v3.10.3"
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Run tests with helm version "{{ helm_version }}"
|
|
||||||
block:
|
|
||||||
- name: "Install Helm"
|
|
||||||
ansible.builtin.include_role:
|
|
||||||
name: install_helm
|
|
||||||
|
|
||||||
- name: Test helm with in-memory kubeconfig
|
|
||||||
ansible.builtin.include_tasks: "from_in_memory_kubeconfig.yml"
|
|
||||||
|
|
||||||
- name: Test helm with custom kubeconfig and validate_certs=false
|
|
||||||
include_tasks: "from_kubeconfig_with_validate_certs.yml"
|
|
||||||
|
|
||||||
- name: Test helm with custom kubeconfig and ca_cert
|
|
||||||
include_tasks: "from_kubeconfig_with_cacert.yml"
|
|
||||||
@@ -5,6 +5,16 @@
|
|||||||
suffix: .helm
|
suffix: .helm
|
||||||
register: _dir
|
register: _dir
|
||||||
|
|
||||||
|
- name: Install helm binary
|
||||||
|
block:
|
||||||
|
- name: "Install {{ test_helm_version }}"
|
||||||
|
include_role:
|
||||||
|
name: install_helm
|
||||||
|
vars:
|
||||||
|
helm_version: "{{ test_helm_version }}"
|
||||||
|
|
||||||
|
when: test_helm_version is defined
|
||||||
|
|
||||||
- set_fact:
|
- set_fact:
|
||||||
saved_kubeconfig_path: "{{ _dir.path }}/config"
|
saved_kubeconfig_path: "{{ _dir.path }}/config"
|
||||||
|
|
||||||
@@ -34,7 +44,6 @@
|
|||||||
ca_cert: "{{ test_ca_cert | default(omit) }}"
|
ca_cert: "{{ test_ca_cert | default(omit) }}"
|
||||||
state: present
|
state: present
|
||||||
plugin_path: https://github.com/hydeenoble/helm-subenv
|
plugin_path: https://github.com/hydeenoble/helm-subenv
|
||||||
verify: false
|
|
||||||
register: plugin
|
register: plugin
|
||||||
|
|
||||||
- assert:
|
- assert:
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
redis*
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
helm_template
|
|
||||||
helm_pull
|
|
||||||
helm
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
[all]
|
|
||||||
helm-3.12.3 helm_version=v3.12.3 test_namespace=helm-plain-http-v3-12-3 tests_should_failed=true
|
|
||||||
helm-3.18.2 helm_version=v3.18.2 test_namespace=helm-plain-http-v3-18-2 tests_should_failed=false
|
|
||||||
helm-4.0.0 helm_version=v4.0.0 test_namespace=helm-plain-http-v4-0-0 tests_should_failed=false
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
- name: Run test for helm plain http option
|
|
||||||
hosts: all
|
|
||||||
gather_facts: true
|
|
||||||
strategy: free
|
|
||||||
|
|
||||||
vars:
|
|
||||||
ansible_connection: local
|
|
||||||
ansible_python_interpreter: "{{ ansible_playbook_python }}"
|
|
||||||
chart_test_oci: "oci://registry-1.docker.io/bitnamicharts/redis"
|
|
||||||
|
|
||||||
roles:
|
|
||||||
- role: setup_namespace
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ansible.builtin.include_tasks: tasks/test.yaml
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Run test for helm
|
|
||||||
block:
|
|
||||||
- name: Create temporary directory to install chart In
|
|
||||||
ansible.builtin.tempfile:
|
|
||||||
state: directory
|
|
||||||
suffix: .helm
|
|
||||||
register: install_path
|
|
||||||
|
|
||||||
- name: Install required helm version
|
|
||||||
ansible.builtin.include_role:
|
|
||||||
name: install_helm
|
|
||||||
vars:
|
|
||||||
helm_install_path: "{{ install_path.path }}"
|
|
||||||
|
|
||||||
# helm
|
|
||||||
- name: Run helm with plain_http
|
|
||||||
kubernetes.core.helm:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
chart_ref: "{{ chart_test_oci }}"
|
|
||||||
release_name: test-secure
|
|
||||||
release_namespace: "{{ test_namespace }}"
|
|
||||||
create_namespace: true
|
|
||||||
plain_http: true
|
|
||||||
register: install_chart
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Ensure module failed as expected
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- install_chart is failed
|
|
||||||
- '"plain_http requires helm >= 3.13.0" in install_chart.msg'
|
|
||||||
when: tests_should_failed | bool
|
|
||||||
|
|
||||||
- name: Ensure the result command contains the expected option
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- install_chart is not failed
|
|
||||||
- '"--plain-http" in install_chart.command'
|
|
||||||
when: not (tests_should_failed | bool)
|
|
||||||
|
|
||||||
# helm_pull
|
|
||||||
- name: Trying to download helm chart with option plain_http
|
|
||||||
kubernetes.core.helm_pull:
|
|
||||||
chart_ref: "{{ chart_test_oci }}"
|
|
||||||
destination: "{{ playbook_dir }}"
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
plain_http: true
|
|
||||||
register: pull_chart
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Ensure module failed as expected
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- pull_chart is failed
|
|
||||||
- '"plain_http requires helm >= 3.13.0" in pull_chart.msg'
|
|
||||||
when: tests_should_failed | bool
|
|
||||||
|
|
||||||
- name: Ensure the result command contains the expected option
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- pull_chart is not failed
|
|
||||||
- '"--plain-http" in pull_chart.command'
|
|
||||||
when: not (tests_should_failed | bool)
|
|
||||||
|
|
||||||
# helm_template
|
|
||||||
- name: Test helm render template
|
|
||||||
kubernetes.core.helm_template:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
chart_ref: "{{ chart_test_oci }}"
|
|
||||||
output_dir: "{{ playbook_dir }}"
|
|
||||||
plain_http: true
|
|
||||||
register: template
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Ensure module failed as expected
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- template is failed
|
|
||||||
- '"plain_http requires helm >= 3.13.0" in template.msg'
|
|
||||||
when: tests_should_failed | bool
|
|
||||||
|
|
||||||
- name: Ensure the result command contains the expected option
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- template is not failed
|
|
||||||
- '"--plain-http" in template.command'
|
|
||||||
when: not (tests_should_failed | bool)
|
|
||||||
|
|
||||||
always:
|
|
||||||
- name: Delete temporary file
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: "{{ install_path.path }}"
|
|
||||||
state: absent
|
|
||||||
ignore_errors: true
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -eux
|
|
||||||
export ANSIBLE_ROLES_PATH=../
|
|
||||||
ansible-playbook playbooks/play.yaml -i inventory.ini "$@"
|
|
||||||
3
tests/integration/targets/helm_plugin/meta/main.yml
Normal file
3
tests/integration/targets/helm_plugin/meta/main.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- install_helm
|
||||||
@@ -1,8 +1,165 @@
|
|||||||
---
|
---
|
||||||
- name: Run tests
|
- name: Install env plugin in check mode
|
||||||
include_tasks: run_tests.yml
|
helm_plugin:
|
||||||
loop_control:
|
binary_path: "{{ helm_binary }}"
|
||||||
loop_var: helm_version
|
state: present
|
||||||
with_items:
|
plugin_path: https://github.com/adamreese/helm-env
|
||||||
- "v3.17.0"
|
register: check_install_env
|
||||||
- "v4.0.0"
|
check_mode: true
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- check_install_env.changed
|
||||||
|
|
||||||
|
- name: Install env plugin
|
||||||
|
helm_plugin:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
state: present
|
||||||
|
plugin_path: https://github.com/adamreese/helm-env
|
||||||
|
register: install_env
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- install_env.changed
|
||||||
|
|
||||||
|
- name: Gather info about all plugin
|
||||||
|
helm_plugin_info:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
register: plugin_info
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- plugin_info.plugin_list is defined
|
||||||
|
|
||||||
|
- name: Install env plugin again
|
||||||
|
helm_plugin:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
state: present
|
||||||
|
plugin_path: https://github.com/adamreese/helm-env
|
||||||
|
register: install_env
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- not install_env.changed
|
||||||
|
|
||||||
|
- name: Uninstall env plugin in check mode
|
||||||
|
helm_plugin:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
state: absent
|
||||||
|
plugin_name: env
|
||||||
|
register: check_uninstall_env
|
||||||
|
check_mode: true
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- check_uninstall_env.changed
|
||||||
|
|
||||||
|
- name: Uninstall env plugin
|
||||||
|
helm_plugin:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
state: absent
|
||||||
|
plugin_name: env
|
||||||
|
register: uninstall_env
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- uninstall_env.changed
|
||||||
|
|
||||||
|
- name: Uninstall env plugin again
|
||||||
|
helm_plugin:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
state: absent
|
||||||
|
plugin_name: env
|
||||||
|
register: uninstall_env
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- not uninstall_env.changed
|
||||||
|
|
||||||
|
# https://github.com/ansible-collections/community.kubernetes/issues/399
|
||||||
|
- block:
|
||||||
|
- name: Copy required plugin files
|
||||||
|
copy:
|
||||||
|
src: "files/sample_plugin"
|
||||||
|
dest: "/tmp/helm_plugin_test/"
|
||||||
|
|
||||||
|
- name: Install sample_plugin from the directory
|
||||||
|
helm_plugin:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
state: present
|
||||||
|
plugin_path: "/tmp/helm_plugin_test/sample_plugin"
|
||||||
|
register: sample_plugin_output
|
||||||
|
|
||||||
|
- name: Assert that sample_plugin is installed or not
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- sample_plugin_output.changed
|
||||||
|
|
||||||
|
- name: Gather Helm plugin info
|
||||||
|
helm_plugin_info:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
register: r
|
||||||
|
|
||||||
|
- name: Set sample_plugin version
|
||||||
|
set_fact:
|
||||||
|
plugin_version: "{{ ( r.plugin_list | selectattr('name', 'equalto', plugin_name) | list )[0].version }}"
|
||||||
|
vars:
|
||||||
|
plugin_name: "sample_plugin"
|
||||||
|
|
||||||
|
- name: Assert if sample_plugin with multiline comment is installed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- plugin_version == "0.0.1"
|
||||||
|
always:
|
||||||
|
- name: Uninstall sample_plugin
|
||||||
|
helm_plugin:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
state: absent
|
||||||
|
plugin_name: sample_plugin
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: uninstall helm plugin secrets
|
||||||
|
helm_plugin:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
plugin_name: secrets
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: install helm-secrets on a specific version
|
||||||
|
helm_plugin:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
plugin_path: https://github.com/jkroepke/helm-secrets
|
||||||
|
plugin_version: 3.4.1
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: list helm plugin
|
||||||
|
helm_plugin_info:
|
||||||
|
plugin_name: secrets
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
register: plugin_list
|
||||||
|
|
||||||
|
- name: assert that secrets has been installed with specified version
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- plugin_list.plugin_list[0].version == "3.4.1"
|
||||||
|
|
||||||
|
- name: Update helm plugin version to latest
|
||||||
|
helm_plugin:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
plugin_name: secrets
|
||||||
|
state: latest
|
||||||
|
register: _update
|
||||||
|
|
||||||
|
- name: assert update was performed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- _update.changed
|
||||||
|
- '"Updated plugin: secrets" in _update.stdout'
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Uninstall sample_plugin
|
||||||
|
helm_plugin:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
state: absent
|
||||||
|
plugin_name: secrets
|
||||||
|
ignore_errors: yes
|
||||||
|
|||||||
@@ -1,195 +0,0 @@
|
|||||||
---
|
|
||||||
- name: "Install {{ helm_version }}"
|
|
||||||
include_role:
|
|
||||||
name: install_helm
|
|
||||||
|
|
||||||
- block:
|
|
||||||
- name: Install env plugin in check mode
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
state: present
|
|
||||||
plugin_path: https://github.com/adamreese/helm-env
|
|
||||||
verify: false
|
|
||||||
register: check_install_env
|
|
||||||
check_mode: true
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- check_install_env.changed
|
|
||||||
|
|
||||||
- name: Install env plugin
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
state: present
|
|
||||||
plugin_path: https://github.com/adamreese/helm-env
|
|
||||||
verify: false
|
|
||||||
register: install_env
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- install_env.changed
|
|
||||||
|
|
||||||
- name: Gather info about all plugin
|
|
||||||
helm_plugin_info:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
register: plugin_info
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- plugin_info.plugin_list is defined
|
|
||||||
|
|
||||||
- name: Install env plugin again
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
state: present
|
|
||||||
plugin_path: https://github.com/adamreese/helm-env
|
|
||||||
verify: false
|
|
||||||
register: install_env
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- not install_env.changed
|
|
||||||
|
|
||||||
- name: Uninstall env plugin in check mode
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
state: absent
|
|
||||||
plugin_name: env
|
|
||||||
verify: false
|
|
||||||
register: check_uninstall_env
|
|
||||||
check_mode: true
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- check_uninstall_env.changed
|
|
||||||
|
|
||||||
- name: Uninstall env plugin
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
state: absent
|
|
||||||
plugin_name: env
|
|
||||||
register: uninstall_env
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- uninstall_env.changed
|
|
||||||
|
|
||||||
- name: Uninstall env plugin again
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
state: absent
|
|
||||||
plugin_name: env
|
|
||||||
register: uninstall_env
|
|
||||||
|
|
||||||
- assert:
|
|
||||||
that:
|
|
||||||
- not uninstall_env.changed
|
|
||||||
|
|
||||||
always:
|
|
||||||
- name: Uninstall env plugin
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
state: absent
|
|
||||||
plugin_name: env
|
|
||||||
|
|
||||||
# https://github.com/ansible-collections/community.kubernetes/issues/399
|
|
||||||
- block:
|
|
||||||
- name: Copy required plugin files
|
|
||||||
copy:
|
|
||||||
src: "files/sample_plugin"
|
|
||||||
dest: "/tmp/helm_plugin_test/"
|
|
||||||
|
|
||||||
- name: Install sample_plugin from the directory
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
state: present
|
|
||||||
plugin_path: "/tmp/helm_plugin_test/sample_plugin"
|
|
||||||
register: sample_plugin_output
|
|
||||||
|
|
||||||
- name: Assert that sample_plugin is installed or not
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- sample_plugin_output.changed
|
|
||||||
|
|
||||||
- name: Gather Helm plugin info
|
|
||||||
helm_plugin_info:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
register: r
|
|
||||||
|
|
||||||
- name: Set sample_plugin version
|
|
||||||
set_fact:
|
|
||||||
plugin_version: "{{ ( r.plugin_list | selectattr('name', 'equalto', plugin_name) | list )[0].version }}"
|
|
||||||
vars:
|
|
||||||
plugin_name: "sample_plugin"
|
|
||||||
|
|
||||||
- name: Assert if sample_plugin with multiline comment is installed
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- plugin_version == "0.0.1"
|
|
||||||
always:
|
|
||||||
- name: Uninstall sample_plugin
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
state: absent
|
|
||||||
plugin_name: sample_plugin
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- block:
|
|
||||||
- name: uninstall helm plugin unittest
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
plugin_name: unittest
|
|
||||||
state: absent
|
|
||||||
|
|
||||||
- name: install helm-unittest on a specific version
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
plugin_path: https://github.com/helm-unittest/helm-unittest
|
|
||||||
plugin_version: v1.0.1
|
|
||||||
verify: false
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: list helm plugin
|
|
||||||
helm_plugin_info:
|
|
||||||
plugin_name: unittest
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
register: plugin_list
|
|
||||||
|
|
||||||
- name: assert that unittest has been installed with specified version
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- plugin_list.plugin_list[0].version == "1.0.1"
|
|
||||||
|
|
||||||
- name: Update helm plugin version to latest (check mode)
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
plugin_name: unittest
|
|
||||||
state: latest
|
|
||||||
register: _update_checkmode
|
|
||||||
check_mode: true
|
|
||||||
|
|
||||||
- name: Assert that module reported change while running in check mode
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- _update_checkmode.changed
|
|
||||||
- '"Updated plugin: unittest" not in _update_checkmode.stdout'
|
|
||||||
|
|
||||||
- name: Update helm plugin version to latest
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
plugin_name: unittest
|
|
||||||
state: latest
|
|
||||||
register: _update
|
|
||||||
|
|
||||||
- name: assert update was performed
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- _update.changed
|
|
||||||
- '"Updated plugin: unittest" in _update.stdout'
|
|
||||||
|
|
||||||
always:
|
|
||||||
- name: Uninstall sample_plugin
|
|
||||||
helm_plugin:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
state: absent
|
|
||||||
plugin_name: unittest
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
- 3.8.0
|
- 3.8.0
|
||||||
- 3.1.0
|
- 3.1.0
|
||||||
- 3.0.0
|
- 3.0.0
|
||||||
- 4.0.0
|
- 2.3.0
|
||||||
|
|
||||||
- block:
|
- block:
|
||||||
- name: Create temp directory for helm tests
|
- name: Create temp directory for helm tests
|
||||||
@@ -20,13 +20,37 @@
|
|||||||
- set_fact:
|
- set_fact:
|
||||||
destination: "{{ temp_dir }}"
|
destination: "{{ temp_dir }}"
|
||||||
|
|
||||||
- name: Install Helm versions
|
- name: Create Helm directories
|
||||||
ansible.builtin.include_role:
|
file:
|
||||||
name: install_helm
|
state: directory
|
||||||
loop: "{{ helm_versions }}"
|
path: "{{ temp_dir }}/{{ item }}"
|
||||||
|
with_items: "{{ helm_versions }}"
|
||||||
|
|
||||||
|
- name: Unarchive Helm binary
|
||||||
|
unarchive:
|
||||||
|
src: "https://get.helm.sh/helm-v{{ item }}-linux-amd64.tar.gz"
|
||||||
|
dest: "{{ temp_dir }}/{{ item }}"
|
||||||
|
remote_src: yes
|
||||||
|
with_items: "{{ helm_versions }}"
|
||||||
|
|
||||||
|
# Testing helm pull with helm version == 2.3.0
|
||||||
|
- block:
|
||||||
|
- name: Assert that helm pull failed with helm <= 3.0.0
|
||||||
|
helm_pull:
|
||||||
|
binary_path: "{{ helm_path }}"
|
||||||
|
chart_ref: https://github.com/grafana/helm-charts/releases/download/grafana-5.6.0/grafana-5.6.0.tgz
|
||||||
|
destination: "{{ destination }}"
|
||||||
|
ignore_errors: true
|
||||||
|
register: _result
|
||||||
|
|
||||||
|
- name: assert that module failed with proper message
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- _result is failed
|
||||||
|
- _result.msg == "Helm version must be >=3.0.0,<4.0.0, current version is 2.3.0"
|
||||||
|
|
||||||
vars:
|
vars:
|
||||||
helm_version: "v{{ item }}"
|
helm_path: "{{ temp_dir }}/2.3.0/linux-amd64/helm"
|
||||||
helm_install_path: "{{ temp_dir }}/{{ item }}"
|
|
||||||
|
|
||||||
# Testing helm pull with helm version == 3.0.0
|
# Testing helm pull with helm version == 3.0.0
|
||||||
- block:
|
- block:
|
||||||
@@ -79,7 +103,7 @@
|
|||||||
- _result.msg == "Parameter chart_ca_cert requires helm >= 3.1.0, current version is 3.0.0"
|
- _result.msg == "Parameter chart_ca_cert requires helm >= 3.1.0, current version is 3.0.0"
|
||||||
|
|
||||||
vars:
|
vars:
|
||||||
helm_path: "{{ temp_dir }}/3.0.0/helm"
|
helm_path: "{{ temp_dir }}/3.0.0/linux-amd64/helm"
|
||||||
|
|
||||||
# Testing helm pull with helm version == 3.1.0
|
# Testing helm pull with helm version == 3.1.0
|
||||||
- block:
|
- block:
|
||||||
@@ -119,7 +143,7 @@
|
|||||||
- _result.msg == "Parameter skip_tls_certs_check requires helm >= 3.3.0, current version is 3.1.0"
|
- _result.msg == "Parameter skip_tls_certs_check requires helm >= 3.3.0, current version is 3.1.0"
|
||||||
|
|
||||||
vars:
|
vars:
|
||||||
helm_path: "{{ temp_dir }}/3.1.0/helm"
|
helm_path: "{{ temp_dir }}/3.1.0/linux-amd64/helm"
|
||||||
|
|
||||||
# Testing helm pull with helm version == 3.8.0
|
# Testing helm pull with helm version == 3.8.0
|
||||||
- block:
|
- block:
|
||||||
@@ -293,7 +317,7 @@
|
|||||||
- _chart_after_force.stat.isdir
|
- _chart_after_force.stat.isdir
|
||||||
|
|
||||||
vars:
|
vars:
|
||||||
helm_path: "{{ temp_dir }}/3.8.0/helm"
|
helm_path: "{{ temp_dir }}/3.8.0/linux-amd64/helm"
|
||||||
|
|
||||||
|
|
||||||
always:
|
always:
|
||||||
|
|||||||
@@ -5,9 +5,5 @@ username: testuser
|
|||||||
password: testpassword
|
password: testpassword
|
||||||
wrong_password: 'WrongPassword'
|
wrong_password: 'WrongPassword'
|
||||||
registry_name: oci_registry
|
registry_name: oci_registry
|
||||||
registry_port: 5002
|
registry_port: 5000
|
||||||
test_chart: https://github.com/grafana/helm-charts/releases/download/k8s-monitoring-1.6.8/k8s-monitoring-1.6.8.tgz
|
test_chart: https://github.com/grafana/helm-charts/releases/download/k8s-monitoring-1.6.8/k8s-monitoring-1.6.8.tgz
|
||||||
helm_versions:
|
|
||||||
- v3.17.0
|
|
||||||
- v3.20.0
|
|
||||||
- v4.0.0
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
- install_helm
|
||||||
182
tests/integration/targets/helm_registry_auth/tasks/main.yaml
Normal file
182
tests/integration/targets/helm_registry_auth/tasks/main.yaml
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
---
|
||||||
|
- 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 idempotency of logout with helm < 3.18.0
|
||||||
|
when: _helm_version.stdout is ansible.builtin.version('v3.18.0', '<')
|
||||||
|
block:
|
||||||
|
|
||||||
|
- 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 or 'basic credential not found' 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' in _helm_registry_auth_wrong.stderr"
|
||||||
|
- "'unauthorized' in _helm_registry_auth_wrong.stderr | lower"
|
||||||
|
- "'{{ 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
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Run tests for helm_registry_auth with different helm versions
|
|
||||||
block:
|
|
||||||
- name: Create temporary directory to install helm binaries
|
|
||||||
ansible.builtin.tempfile:
|
|
||||||
state: directory
|
|
||||||
suffix: .helm
|
|
||||||
register: _tmpdir
|
|
||||||
|
|
||||||
- name: Ensure that Docker demon is running
|
|
||||||
ansible.builtin.command: "docker info"
|
|
||||||
register: _docker_info
|
|
||||||
failed_when: _docker_info.rc != 0
|
|
||||||
|
|
||||||
- name: Copy htpasswd to the tmpfile directory
|
|
||||||
ansible.builtin.copy:
|
|
||||||
src: registry.password
|
|
||||||
dest: "{{ _tmpdir.path }}/registry.password"
|
|
||||||
|
|
||||||
- name: Pull test helm chart
|
|
||||||
ansible.builtin.uri:
|
|
||||||
url: "{{ test_chart }}"
|
|
||||||
dest: "{{ _tmpdir.path }}/k8s-monitoring-1.6.8.tgz"
|
|
||||||
return_content: no
|
|
||||||
status_code: 200
|
|
||||||
|
|
||||||
- name: Setup the registry
|
|
||||||
ansible.builtin.command: >-
|
|
||||||
docker run -d --rm
|
|
||||||
-p {{ registry_port }}:5000
|
|
||||||
--name "{{ registry_name }}"
|
|
||||||
-v "{{ _tmpdir.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: Run tests
|
|
||||||
ansible.builtin.include_tasks: run_tests.yml
|
|
||||||
loop: "{{ helm_versions }}"
|
|
||||||
loop_control:
|
|
||||||
loop_var: helm_version
|
|
||||||
|
|
||||||
always:
|
|
||||||
- name: Stop and remove the registry
|
|
||||||
ansible.builtin.command: docker stop {{ registry_name }}
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Delete temporary directory
|
|
||||||
ansible.builtin.file:
|
|
||||||
state: absent
|
|
||||||
path: "{{ _tmpdir.path }}"
|
|
||||||
ignore_errors: true
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
---
|
|
||||||
- block:
|
|
||||||
- name: Install helm versions
|
|
||||||
ansible.builtin.include_role:
|
|
||||||
name: install_helm
|
|
||||||
|
|
||||||
# - name: Test the registry with correct credentials to ensure that the registry is running
|
|
||||||
# ansible.builtin.shell: >-
|
|
||||||
# echo {{ password | quote }} | {{ helm_binary }} registry login localhost:{{ registry_port }}
|
|
||||||
# -u {{ username }} --password-stdin --plain-http
|
|
||||||
# register: _login_correct
|
|
||||||
# failed_when: _login_correct.rc != 0
|
|
||||||
|
|
||||||
# - name: Clean up credentials to run test on clean environment
|
|
||||||
# ansible.builtin.shell: >-
|
|
||||||
# {{ helm_binary }} registry logout localhost:{{ registry_port }}
|
|
||||||
# register: _logout
|
|
||||||
# failed_when: _logout.rc != 0
|
|
||||||
|
|
||||||
- name: Test module helm_registry_auth with correct credentials
|
|
||||||
helm_registry_auth:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
username: "{{ username }}"
|
|
||||||
password: "{{ password }}"
|
|
||||||
host: localhost:{{ registry_port }}
|
|
||||||
plain_http: true
|
|
||||||
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.stdout_lines + _helm_registry_auth_correct.stderr_lines"
|
|
||||||
- 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_binary }} push --plain-http "{{ _tmpdir.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 | string + '/test/k8s-monitoring' in _save_chart.stderr"
|
|
||||||
|
|
||||||
- name: Test logout
|
|
||||||
helm_registry_auth:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
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: Ensure that not able to push to the registry
|
|
||||||
ansible.builtin.shell: >-
|
|
||||||
{{ helm_binary }} push --plain-http "{{ _tmpdir.path }}/k8s-monitoring-1.6.8.tgz" oci://localhost:{{ registry_port }}/test/
|
|
||||||
register: _save_chart
|
|
||||||
failed_when: _save_chart.rc == 0
|
|
||||||
|
|
||||||
- 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 or 'basic credential not found' in _save_chart.stderr"
|
|
||||||
- "_save_chart.rc != 0"
|
|
||||||
|
|
||||||
- name: Test idempotency of logout with helm < 3.18.0
|
|
||||||
when: helm_version is ansible.builtin.version('v3.18.0', '<')
|
|
||||||
block:
|
|
||||||
|
|
||||||
- name: Test logout idempotency
|
|
||||||
helm_registry_auth:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
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: Test module helm_registry_auth with wrong credentials
|
|
||||||
helm_registry_auth:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
username: "{{ username }}"
|
|
||||||
password: "{{ wrong_password }}"
|
|
||||||
host: localhost:{{ registry_port }}
|
|
||||||
state: present
|
|
||||||
plain_http: true
|
|
||||||
register: _helm_registry_auth_wrong
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Assert that the registry is not logged in and auth data is not saved
|
|
||||||
ansible.builtin.assert:
|
|
||||||
that:
|
|
||||||
- "'401' in _helm_registry_auth_wrong.stderr"
|
|
||||||
- "'unauthorized' in _helm_registry_auth_wrong.stderr | lower"
|
|
||||||
- "'{{ 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"
|
|
||||||
@@ -1,2 +1,5 @@
|
|||||||
time=1
|
time=20
|
||||||
helm_repository
|
helm_repository
|
||||||
|
helm_info
|
||||||
|
helm
|
||||||
|
helm_template
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
---
|
---
|
||||||
chart_test_repo: "https://kubernetes.github.io/ingress-nginx"
|
chart_test_repo: "https://kubernetes.github.io/ingress-nginx"
|
||||||
helm_versions:
|
helm_binary: "/tmp/helm/{{ ansible_system | lower }}-amd64/helm"
|
||||||
- v3.20.0
|
|
||||||
- v4.0.0
|
|
||||||
|
|||||||
5
tests/integration/targets/helm_repository/meta/main.yml
Normal file
5
tests/integration/targets/helm_repository/meta/main.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
collections:
|
||||||
|
- kubernetes.core
|
||||||
|
dependencies:
|
||||||
|
- install_helm
|
||||||
@@ -1,6 +1,101 @@
|
|||||||
---
|
---
|
||||||
- name: Run test for helm_repository module
|
- name: "Ensure test_helm_repo doesn't exist"
|
||||||
ansible.builtin.include_tasks: run_tests.yml
|
helm_repository:
|
||||||
loop: "{{ helm_versions }}"
|
binary_path: "{{ helm_binary }}"
|
||||||
loop_control:
|
name: test_helm_repo
|
||||||
loop_var: helm_version
|
state: absent
|
||||||
|
|
||||||
|
- name: Add test_helm_repo chart repository
|
||||||
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
name: test_helm_repo
|
||||||
|
repo_url: "{{ chart_test_repo }}"
|
||||||
|
register: repository
|
||||||
|
|
||||||
|
- name: Assert that test_helm_repo repository is added
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- repository is changed
|
||||||
|
- '"--insecure-skip-tls-verify" not in repository.command'
|
||||||
|
|
||||||
|
- name: Check idempotency
|
||||||
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
name: test_helm_repo
|
||||||
|
repo_url: "{{ chart_test_repo }}"
|
||||||
|
register: repository
|
||||||
|
|
||||||
|
- name: Assert idempotency
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- repository is not changed
|
||||||
|
|
||||||
|
- name: Failed to add repository with the same name
|
||||||
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
name: test_helm_repo
|
||||||
|
repo_url: "https://other-charts.url"
|
||||||
|
register: repository_errors
|
||||||
|
ignore_errors: yes
|
||||||
|
|
||||||
|
- name: Assert that adding repository with the same name failed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- repository_errors is failed
|
||||||
|
|
||||||
|
- name: Succesfully add repository with the same name when forcing
|
||||||
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
name: test_helm_repo
|
||||||
|
repo_url: "{{ chart_test_repo }}"
|
||||||
|
force: true
|
||||||
|
register: repository
|
||||||
|
|
||||||
|
- name: Assert that test_helm_repo repository is changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- repository is changed
|
||||||
|
|
||||||
|
- name: Remove test_helm_repo chart repository
|
||||||
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
name: test_helm_repo
|
||||||
|
state: absent
|
||||||
|
register: repository
|
||||||
|
|
||||||
|
- name: Assert that test_helm_repo repository is removed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- repository is changed
|
||||||
|
|
||||||
|
- name: Check idempotency after remove
|
||||||
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
name: test_helm_repo
|
||||||
|
state: absent
|
||||||
|
register: repository
|
||||||
|
|
||||||
|
- name: Assert idempotency
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- repository is not changed
|
||||||
|
|
||||||
|
- name: Add test_helm_repo chart repository as insecure
|
||||||
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
name: test_helm_repo
|
||||||
|
repo_url: "{{ chart_test_repo }}"
|
||||||
|
insecure_skip_tls_verify: true
|
||||||
|
register: repository
|
||||||
|
|
||||||
|
- name: Assert that repository added and flag set
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- repository is changed
|
||||||
|
- '"--insecure-skip-tls-verify" in repository.command'
|
||||||
|
|
||||||
|
- name: Clean test_helm_repo chart repository
|
||||||
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
name: test_helm_repo
|
||||||
|
state: absent
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
---
|
|
||||||
- name: "Install helm version {{ helm_version }}"
|
|
||||||
ansible.builtin.include_role:
|
|
||||||
name: install_helm
|
|
||||||
|
|
||||||
- name: "Ensure test_helm_repo doesn't exist"
|
|
||||||
helm_repository:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
name: test_helm_repo
|
|
||||||
state: absent
|
|
||||||
|
|
||||||
- name: Add test_helm_repo chart repository
|
|
||||||
helm_repository:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
name: test_helm_repo
|
|
||||||
repo_url: "{{ chart_test_repo }}"
|
|
||||||
register: repository
|
|
||||||
|
|
||||||
- name: Assert that test_helm_repo repository is added
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- repository is changed
|
|
||||||
- '"--insecure-skip-tls-verify" not in repository.command'
|
|
||||||
|
|
||||||
- name: Check idempotency
|
|
||||||
helm_repository:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
name: test_helm_repo
|
|
||||||
repo_url: "{{ chart_test_repo }}"
|
|
||||||
register: repository
|
|
||||||
|
|
||||||
- name: Assert idempotency
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- repository is not changed
|
|
||||||
|
|
||||||
- name: Failed to add repository with the same name
|
|
||||||
helm_repository:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
name: test_helm_repo
|
|
||||||
repo_url: "https://other-charts.url"
|
|
||||||
register: repository_errors
|
|
||||||
ignore_errors: true
|
|
||||||
|
|
||||||
- name: Assert that adding repository with the same name failed
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- repository_errors is failed
|
|
||||||
|
|
||||||
- name: Succesfully add repository with the same name when forcing
|
|
||||||
helm_repository:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
name: test_helm_repo
|
|
||||||
repo_url: "{{ chart_test_repo }}"
|
|
||||||
force: true
|
|
||||||
register: repository
|
|
||||||
|
|
||||||
- name: Assert that test_helm_repo repository is changed
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- repository is changed
|
|
||||||
|
|
||||||
- name: Remove test_helm_repo chart repository
|
|
||||||
helm_repository:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
name: test_helm_repo
|
|
||||||
state: absent
|
|
||||||
register: repository
|
|
||||||
|
|
||||||
- name: Assert that test_helm_repo repository is removed
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- repository is changed
|
|
||||||
|
|
||||||
- name: Check idempotency after remove
|
|
||||||
helm_repository:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
name: test_helm_repo
|
|
||||||
state: absent
|
|
||||||
register: repository
|
|
||||||
|
|
||||||
- name: Assert idempotency
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- repository is not changed
|
|
||||||
|
|
||||||
- name: Add test_helm_repo chart repository as insecure
|
|
||||||
helm_repository:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
name: test_helm_repo
|
|
||||||
repo_url: "{{ chart_test_repo }}"
|
|
||||||
insecure_skip_tls_verify: true
|
|
||||||
register: repository
|
|
||||||
|
|
||||||
- name: Assert that repository added and flag set
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- repository is changed
|
|
||||||
- '"--insecure-skip-tls-verify" in repository.command'
|
|
||||||
|
|
||||||
- name: Clean test_helm_repo chart repository
|
|
||||||
helm_repository:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
name: test_helm_repo
|
|
||||||
state: absent
|
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
---
|
---
|
||||||
|
helm_binary: "/tmp/helm/{{ ansible_system | lower }}-amd64/helm"
|
||||||
helm_namespace: helm-set-values
|
helm_namespace: helm-set-values
|
||||||
helm_versions:
|
|
||||||
- v3.10.3
|
|
||||||
- v4.0.0
|
|
||||||
|
|||||||
@@ -25,14 +25,79 @@
|
|||||||
- user_values.status["release_values"]["phase"] == "integration"
|
- user_values.status["release_values"]["phase"] == "integration"
|
||||||
- user_values.status["release_values"]["versioned"] is false
|
- user_values.status["release_values"]["versioned"] is false
|
||||||
|
|
||||||
- block:
|
# install chart using set_values and release_values
|
||||||
- name: create temporary file to save values in
|
- name: Install helm binary (> 3.10.0) requires to use set-json
|
||||||
|
include_role:
|
||||||
|
name: install_helm
|
||||||
|
vars:
|
||||||
|
helm_version: "v3.10.3"
|
||||||
|
|
||||||
|
- name: Install helm using set_values parameters
|
||||||
|
helm:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
chart_ref: oci://registry-1.docker.io/bitnamicharts/apache
|
||||||
|
release_name: test-apache
|
||||||
|
release_namespace: "{{ helm_namespace }}"
|
||||||
|
create_namespace: true
|
||||||
|
set_values:
|
||||||
|
- value: 'master.image={"registry": "docker.io", "repository": "bitnami/apache", "tag": "2.4.54-debian-11-r74"}'
|
||||||
|
value_type: json
|
||||||
|
release_values:
|
||||||
|
replicaCount: 3
|
||||||
|
|
||||||
|
- name: Get release info
|
||||||
|
helm_info:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
release_name: test-apache
|
||||||
|
release_namespace: "{{ helm_namespace }}"
|
||||||
|
register: values
|
||||||
|
|
||||||
|
- name: Assert that release was created with user-defined variables
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- values.status["release_values"].replicaCount == 3
|
||||||
|
- values.status["release_values"].master.image.registry == "docker.io"
|
||||||
|
- values.status["release_values"].master.image.repository == "bitnami/apache"
|
||||||
|
- values.status["release_values"].master.image.tag == "2.4.54-debian-11-r74"
|
||||||
|
|
||||||
|
# install chart using set_values and values_files
|
||||||
|
- name: create temporary file to save values in
|
||||||
tempfile:
|
tempfile:
|
||||||
suffix: .yml
|
suffix: .yml
|
||||||
register: ymlfile
|
register: ymlfile
|
||||||
|
|
||||||
- ansible.builtin.include_tasks: run_tests.yml
|
- block:
|
||||||
loop: "{{ helm_versions }}"
|
- name: copy content into values file
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
---
|
||||||
|
mode: distributed
|
||||||
|
dest: "{{ ymlfile.path }}"
|
||||||
|
|
||||||
|
- name: Install helm using set_values parameters
|
||||||
|
helm:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
chart_ref: oci://registry-1.docker.io/bitnamicharts/minio
|
||||||
|
release_name: test-minio
|
||||||
|
release_namespace: "{{ helm_namespace }}"
|
||||||
|
create_namespace: true
|
||||||
|
set_values:
|
||||||
|
- value: 'disableWebUI=true'
|
||||||
|
values_files:
|
||||||
|
- "{{ ymlfile.path }}"
|
||||||
|
|
||||||
|
- name: Get release info
|
||||||
|
helm_info:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
release_name: test-minio
|
||||||
|
release_namespace: "{{ helm_namespace }}"
|
||||||
|
register: values
|
||||||
|
|
||||||
|
- name: Assert that release was created with user-defined variables
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- values.status["release_values"].mode == "distributed"
|
||||||
|
- values.status["release_values"].disableWebUI is true
|
||||||
|
|
||||||
always:
|
always:
|
||||||
- name: Delete temporary file
|
- name: Delete temporary file
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
---
|
|
||||||
# install chart using set_values and release_values
|
|
||||||
- name: 'Install helm binary (> 3.10.0) requires to use set-json (helm_version={{ item }})'
|
|
||||||
include_role:
|
|
||||||
name: install_helm
|
|
||||||
vars:
|
|
||||||
helm_version: "{{ item }}"
|
|
||||||
|
|
||||||
- name: Install helm using set_values parameters
|
|
||||||
helm:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
chart_ref: oci://registry-1.docker.io/bitnamicharts/apache
|
|
||||||
release_name: 'test-apache-{{ item }}'
|
|
||||||
release_namespace: "{{ helm_namespace }}"
|
|
||||||
create_namespace: true
|
|
||||||
set_values:
|
|
||||||
- value: 'master.image={"registry": "docker.io", "repository": "bitnami/apache", "tag": "2.4.54-debian-11-r74"}'
|
|
||||||
value_type: json
|
|
||||||
release_values:
|
|
||||||
replicaCount: 3
|
|
||||||
|
|
||||||
- name: Get release info
|
|
||||||
helm_info:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
release_name: 'test-apache-{{ item }}'
|
|
||||||
release_namespace: "{{ helm_namespace }}"
|
|
||||||
register: values
|
|
||||||
|
|
||||||
- name: Assert that release was created with user-defined variables
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- values.status["release_values"].replicaCount == 3
|
|
||||||
- values.status["release_values"].master.image.registry == "docker.io"
|
|
||||||
- values.status["release_values"].master.image.repository == "bitnami/apache"
|
|
||||||
- values.status["release_values"].master.image.tag == "2.4.54-debian-11-r74"
|
|
||||||
|
|
||||||
# install chart using set_values and values_files
|
|
||||||
- name: copy content into values file
|
|
||||||
copy:
|
|
||||||
content: |
|
|
||||||
---
|
|
||||||
mode: distributed
|
|
||||||
dest: "{{ ymlfile.path }}"
|
|
||||||
|
|
||||||
- name: Install helm using set_values parameters
|
|
||||||
helm:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
chart_ref: oci://registry-1.docker.io/bitnamicharts/minio
|
|
||||||
release_name: 'test-minio-{{ item }}'
|
|
||||||
release_namespace: "{{ helm_namespace }}"
|
|
||||||
create_namespace: true
|
|
||||||
set_values:
|
|
||||||
- value: 'disableWebUI=true'
|
|
||||||
values_files:
|
|
||||||
- "{{ ymlfile.path }}"
|
|
||||||
|
|
||||||
- name: Get release info
|
|
||||||
helm_info:
|
|
||||||
binary_path: "{{ helm_binary }}"
|
|
||||||
release_name: 'test-minio-{{ item }}'
|
|
||||||
release_namespace: "{{ helm_namespace }}"
|
|
||||||
register: values
|
|
||||||
|
|
||||||
- name: Assert that release was created with user-defined variables
|
|
||||||
assert:
|
|
||||||
that:
|
|
||||||
- values.status["release_values"].mode == "distributed"
|
|
||||||
- values.status["release_values"].disableWebUI is true
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
helm
|
|
||||||
helm_template
|
|
||||||
helm_info
|
|
||||||
helm_repository
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
[all]
|
|
||||||
v3.15.4
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
- name: Run tests for Helm v3.15.4
|
|
||||||
hosts: all
|
|
||||||
connection: local
|
|
||||||
gather_facts: true
|
|
||||||
|
|
||||||
vars:
|
|
||||||
ansible_python_interpreter: "{{ ansible_playbook_python }}"
|
|
||||||
helm_version: "{{ inventory_hostname }}"
|
|
||||||
|
|
||||||
roles:
|
|
||||||
- role: helm
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -eux
|
|
||||||
export ANSIBLE_ROLES_PATH=../
|
|
||||||
ansible-playbook play.yaml -i inventory.ini "$@"
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user