mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-05-11 20:12:18 +00:00
Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6dadd06252 | ||
|
|
69dc7d5c5d | ||
|
|
2fa1c2c6e5 | ||
|
|
f2623dd3cf | ||
|
|
8772d8c997 | ||
|
|
a32108f64f | ||
|
|
365e5e9159 | ||
|
|
448a68da3d | ||
|
|
46acab9c4c | ||
|
|
fdb77182c8 | ||
|
|
fa3d94f793 | ||
|
|
9ec27cf37c | ||
|
|
10cb241256 | ||
|
|
92e1f581fe | ||
|
|
7f69aff0d6 | ||
|
|
8c65ac066d | ||
|
|
1d962fb932 | ||
|
|
27ce23aa72 | ||
|
|
993652b581 | ||
|
|
9bd9d22db3 | ||
|
|
0593426918 | ||
|
|
8fa5b201a4 | ||
|
|
94c1f57f36 | ||
|
|
d0b97319a5 | ||
|
|
38d5c81051 | ||
|
|
914a16ec5c | ||
|
|
cb2070c93f | ||
|
|
b594d35931 | ||
|
|
00699ac3e5 | ||
|
|
d329e7ee42 | ||
|
|
d4fc22c74e | ||
|
|
b648f45e90 | ||
|
|
2cb5d6c316 | ||
|
|
0e7229cf8d | ||
|
|
9ec6912325 | ||
|
|
7cdf0d03f5 | ||
|
|
91df2f10bc | ||
|
|
1943dfc3d9 | ||
|
|
eb731cd3a5 | ||
|
|
ecc64cace1 | ||
|
|
bc0de24cba | ||
|
|
9f60b151ba | ||
|
|
159a63af97 | ||
|
|
6efabd3418 | ||
|
|
aee847431a | ||
|
|
6609abdd5a | ||
|
|
219c747a24 | ||
|
|
7559b65946 | ||
|
|
c8a33c7180 | ||
|
|
52f2cb5587 | ||
|
|
513ff66fcf | ||
|
|
fca0dc0485 | ||
|
|
cd686316e9 | ||
|
|
b8e9873f64 | ||
|
|
4c305e73f0 | ||
|
|
c8a9326306 | ||
|
|
445d367059 | ||
|
|
fdb8af7ca9 | ||
|
|
a89f19b4e5 | ||
|
|
5bc53dba7c | ||
|
|
b07fbd6271 | ||
|
|
44a2fc392a | ||
|
|
6265a3e7ce | ||
|
|
0afd257dd0 | ||
|
|
d192157ed8 | ||
|
|
6a04f42d0b | ||
|
|
5064d722c3 | ||
|
|
fb80d973c4 | ||
|
|
8363a4debf | ||
|
|
0c5233a650 | ||
|
|
c0666a5137 | ||
|
|
072a08091b | ||
|
|
cbadbe32f9 | ||
|
|
966fa7e906 | ||
|
|
485eae3b10 | ||
|
|
a4c1bd8541 | ||
|
|
8858b19121 | ||
|
|
6360763098 | ||
|
|
ac943e9890 | ||
|
|
0408aa9328 | ||
|
|
874fbfedd5 | ||
|
|
d8d9133912 | ||
|
|
86d9a3f45f | ||
|
|
fb25ff44f1 | ||
|
|
600c10dffb | ||
|
|
9f7c865c9c | ||
|
|
23e94b60c1 | ||
|
|
1955989278 | ||
|
|
7c4ec3b982 | ||
|
|
8d15489ec2 | ||
|
|
3dcdcbc85d | ||
|
|
fe9c12326d |
@@ -2,5 +2,8 @@
|
||||
profile: production
|
||||
|
||||
exclude_paths:
|
||||
- .ansible/
|
||||
- .github/
|
||||
- tests/integration
|
||||
- tests/unit
|
||||
- tests/sanity
|
||||
|
||||
6
.ansible-lint-ignore
Normal file
6
.ansible-lint-ignore
Normal file
@@ -0,0 +1,6 @@
|
||||
# https://docs.ansible.com/ansible-lint/docs/rules/
|
||||
# no-changed-when is not requried for examples
|
||||
plugins/connection/kubectl.py no-changed-when
|
||||
# false positive result
|
||||
plugins/connection/kubectl.py var-naming[no-reserved]
|
||||
plugins/connection/kubectl.py jinja[invalid]
|
||||
60
.github/stale.yml
vendored
60
.github/stale.yml
vendored
@@ -1,60 +0,0 @@
|
||||
---
|
||||
# Configuration for probot-stale - https://github.com/probot/stale
|
||||
|
||||
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
||||
daysUntilStale: 90
|
||||
|
||||
# Number of days of inactivity before an Issue or Pull Request with the stale
|
||||
# label is closed. Set to false to disable. If disabled, issues still need to be
|
||||
# closed manually, but will remain marked as stale.
|
||||
daysUntilClose: 30
|
||||
|
||||
# Only issues or pull requests with all of these labels are check if stale.
|
||||
# Defaults to `[]` (disabled)
|
||||
onlyLabels: []
|
||||
|
||||
# Issues or Pull Requests with these labels will never be considered stale. Set
|
||||
# to `[]` to disable
|
||||
exemptLabels:
|
||||
- security
|
||||
- planned
|
||||
- priority/critical
|
||||
- lifecycle/frozen
|
||||
- verified
|
||||
|
||||
# Set to true to ignore issues in a project (defaults to false)
|
||||
exemptProjects: false
|
||||
|
||||
# Set to true to ignore issues in a milestone (defaults to false)
|
||||
exemptMilestones: true
|
||||
|
||||
# Set to true to ignore issues with an assignee (defaults to false)
|
||||
exemptAssignees: false
|
||||
|
||||
# Label to use when marking as stale
|
||||
staleLabel: lifecycle/stale
|
||||
|
||||
# Limit the number of actions per hour, from 1-30. Default is 30
|
||||
limitPerRun: 30
|
||||
|
||||
pulls:
|
||||
markComment: |-
|
||||
PRs go stale after 90 days of inactivity.
|
||||
If there is no further activity, the PR will be closed in another 30 days.
|
||||
|
||||
unmarkComment: >-
|
||||
This pull request is no longer stale.
|
||||
|
||||
closeComment: >-
|
||||
This pull request has been closed due to inactivity.
|
||||
|
||||
issues:
|
||||
markComment: |-
|
||||
Issues go stale after 90 days of inactivity.
|
||||
If there is no further activity, the issue will be closed in another 30 days.
|
||||
|
||||
unmarkComment: >-
|
||||
This issue is no longer stale.
|
||||
|
||||
closeComment: >-
|
||||
This issue has been closed due to inactivity.
|
||||
19
.github/workflows/integration-tests.yaml
vendored
19
.github/workflows/integration-tests.yaml
vendored
@@ -26,6 +26,7 @@ jobs:
|
||||
with:
|
||||
path: ${{ env.source_dir }}
|
||||
fetch-depth: "0"
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: list changes for pull request
|
||||
id: splitter
|
||||
@@ -50,6 +51,7 @@ jobs:
|
||||
source: "./source"
|
||||
cloud_common: "./cloudcommon"
|
||||
ansible_posix: "./ansible_posix"
|
||||
community_general: "./community_general"
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -61,7 +63,7 @@ jobs:
|
||||
- true
|
||||
- false
|
||||
workflow-id: ${{ fromJson(needs.splitter.outputs.test_jobs) }}
|
||||
name: "integration-py${{ matrix.python-version }}-${{ matrix.ansible-version }}-${{ matrix.workflow-id }}"
|
||||
name: "integration-py${{ matrix.python-version }}-${{ matrix.ansible-version }}-${{ matrix.workflow-id }}-enable_turbo=${{ matrix.enable-turbo-mode }}"
|
||||
steps:
|
||||
- name: Read target
|
||||
id: read-targets
|
||||
@@ -118,6 +120,13 @@ jobs:
|
||||
path: ${{ env.ansible_posix }}
|
||||
ref: main
|
||||
|
||||
- name: checkout ansible-collections/community.general
|
||||
uses: ansible-network/github_actions/.github/actions/checkout_dependency@main
|
||||
with:
|
||||
repository: ansible-collections/community.general
|
||||
path: ${{ env.community_general }}
|
||||
ref: main
|
||||
|
||||
- name: install cloud.common collection
|
||||
uses: ansible-network/github_actions/.github/actions/build_install_collection@main
|
||||
with:
|
||||
@@ -130,8 +139,16 @@ jobs:
|
||||
install_python_dependencies: true
|
||||
source_path: ${{ env.ansible_posix }}
|
||||
|
||||
- name: install community.general collection
|
||||
uses: ansible-network/github_actions/.github/actions/build_install_collection@main
|
||||
with:
|
||||
install_python_dependencies: false
|
||||
source_path: ${{ env.community_general }}
|
||||
|
||||
- name: create kubernetes cluster
|
||||
uses: helm/kind-action@v1.8.0
|
||||
with:
|
||||
node_image: "kindest/node:v1.29.2"
|
||||
|
||||
- name: Run integration tests
|
||||
uses: ansible-network/github_actions/.github/actions/ansible_test_integration@main
|
||||
|
||||
7
.github/workflows/linters.yaml
vendored
7
.github/workflows/linters.yaml
vendored
@@ -19,6 +19,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run ansible-lint
|
||||
uses: ansible/ansible-lint@v6.21.0
|
||||
- name: run-ansible-lint
|
||||
uses: ansible/ansible-lint@main
|
||||
with:
|
||||
gh_action_ref: "v25.5.0"
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -13,6 +13,7 @@ changelogs/.plugin-cache.yaml
|
||||
tests/output
|
||||
tests/integration/cloud-config-*
|
||||
.cache
|
||||
.ansible
|
||||
|
||||
# Helm charts
|
||||
tests/integration/*-chart-*.tgz
|
||||
@@ -20,3 +21,6 @@ tests/integration/*-chart-*.tgz
|
||||
# ansible-test generated file
|
||||
tests/integration/inventory
|
||||
tests/integration/*-*.yml
|
||||
|
||||
# VS Code settings
|
||||
.vscode/
|
||||
|
||||
@@ -5,16 +5,25 @@ rules:
|
||||
braces:
|
||||
max-spaces-inside: 1
|
||||
level: error
|
||||
|
||||
brackets:
|
||||
max-spaces-inside: 1
|
||||
level: error
|
||||
comments:
|
||||
min-spaces-from-content: 1
|
||||
comments-indentation: false
|
||||
document-start: disable
|
||||
line-length: disable
|
||||
truthy: disable
|
||||
indentation:
|
||||
spaces: 2
|
||||
indent-sequences: consistent
|
||||
octal-values:
|
||||
forbid-implicit-octal: true
|
||||
forbid-explicit-octal: true
|
||||
ignore: |
|
||||
.cache
|
||||
.tox
|
||||
.ansible
|
||||
tests/output
|
||||
plugins/connection/kubectl.py
|
||||
|
||||
281
CHANGELOG.rst
281
CHANGELOG.rst
@@ -4,6 +4,287 @@ Kubernetes Collection Release Notes
|
||||
|
||||
.. contents:: Topics
|
||||
|
||||
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
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This release includes bugfixes for k8s service field handling, k8s_cp init containers support, and removes deprecated ansible.module_utils.six imports.
|
||||
|
||||
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).
|
||||
- module_utils/k8s/service - hide fields first before creating diffs (https://github.com/ansible-collections/kubernetes.core/pull/915).
|
||||
|
||||
v5.4.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This release updates the ``helm_registry_auth`` module to match the behavior of ``helm >= 3.18.0`` which reports a successful logout regardless of the current state (i.e., no idempotency).
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- 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
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This release includes minor changes, bug fixes and also bumps ``ansible-lint`` version to ``25.1.2``.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- 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 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 support for ``insecure_skip_tls_verify`` option to helm and helm_repository(https://github.com/ansible-collections/kubernetes.core/issues/694).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- 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).
|
||||
|
||||
v5.2.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This release adds more functionality to the hidden_fields option and support for waiting on ClusterOperators to reach a ready state.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- k8s - Extend hidden_fields to allow the expression of more complex field types to be hidden (https://github.com/ansible-collections/kubernetes.core/pull/872)
|
||||
- k8s_info - Extend hidden_fields to allow the expression of more complex field types to be hidden (https://github.com/ansible-collections/kubernetes.core/pull/872)
|
||||
- waiter.py - add ClusterOperator support. The module can now check OpenShift cluster health by verifying ClusterOperator status requiring 'Available: True', 'Degraded: False', and 'Progressing: False' for success. (https://github.com/ansible-collections/kubernetes.core/issues/869)
|
||||
|
||||
v5.1.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This release came with new module ``helm_registry_auth``, improvements to the error messages in the k8s_drain module, new parameter ``insecure_registry`` for ``helm_template`` module and several bug fixes.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Bump version of ``ansible-lint`` to minimum 24.7.0 (https://github.com/ansible-collections/kubernetes.core/pull/765).
|
||||
- Parameter insecure_registry added to helm_template as equivalent of insecure-skip-tls-verify (https://github.com/ansible-collections/kubernetes.core/pull/805).
|
||||
- k8s_drain - Improve error message for pod disruption budget when draining a node (https://github.com/ansible-collections/kubernetes.core/issues/797).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- helm - Helm version checks did not support RC versions. They now accept any version tags. (https://github.com/ansible-collections/kubernetes.core/pull/745).
|
||||
- helm_pull - Apply no_log=True to pass_credentials to silence false positive warning. (https://github.com/ansible-collections/kubernetes.core/pull/796).
|
||||
- k8s_drain - Fix k8s_drain does not wait for single pod (https://github.com/ansible-collections/kubernetes.core/issues/769).
|
||||
- k8s_drain - Fix k8s_drain runs into a timeout when evicting a pod which is part of a stateful set (https://github.com/ansible-collections/kubernetes.core/issues/792).
|
||||
- kubeconfig option should not appear in module invocation log (https://github.com/ansible-collections/kubernetes.core/issues/782).
|
||||
- kustomize - kustomize plugin fails with deprecation warnings (https://github.com/ansible-collections/kubernetes.core/issues/639).
|
||||
- waiter - Fix waiting for daemonset when desired number of pods is 0. (https://github.com/ansible-collections/kubernetes.core/pull/756).
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
- helm_registry_auth - Helm registry authentication module
|
||||
|
||||
v5.0.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This major release drops support for ``ansible-core<2.15``.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- connection/kubectl.py - Added an example of using the kubectl connection plugin to the documentation (https://github.com/ansible-collections/kubernetes.core/pull/741).
|
||||
- inventory/k8s.py - Defer removal of k8s inventory plugin to version 6.0.0 (https://github.com/ansible-collections/kubernetes.core/pull/734).
|
||||
|
||||
Breaking Changes / Porting Guide
|
||||
--------------------------------
|
||||
|
||||
- Remove support for ``ansible-core<2.15`` (https://github.com/ansible-collections/kubernetes.core/pull/737).
|
||||
|
||||
v4.0.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This major release brings several bug fixes. We have also removed support for ``ansible-core<2.15`` and deprecated functions and class from ``module_utils/common.py``.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- inventory/k8s.py - Defer removal of k8s inventory plugin to version 5.0 (https://github.com/ansible-collections/kubernetes.core/pull/723).
|
||||
- k8s - The module and K8sService were changed so warnings returned by the K8S API are now displayed to the user.
|
||||
|
||||
Removed Features (previously deprecated)
|
||||
----------------------------------------
|
||||
|
||||
- k8s - Support for ``merge_type=json`` has been removed in version 4.0.0. Please use ``kubernetes.core.k8s_json_patch`` instead (https://github.com/ansible-collections/kubernetes.core/pull/722).
|
||||
- k8s_exec - the previously deprecated ``result.return_code`` return value has been removed, consider using ``result.rc`` instead (https://github.com/ansible-collections/kubernetes.core/pull/726).
|
||||
- module_utils/common.py - the previously deprecated ``K8sAnsibleMixin`` class has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
|
||||
- module_utils/common.py - the previously deprecated ``configuration_digest()`` function has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
|
||||
- module_utils/common.py - the previously deprecated ``get_api_client()`` function has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
|
||||
- module_utils/common.py - the previously deprecated ``unique_string()`` function has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Resolve Collections util resource discovery fails when complex subresources present (https://github.com/ansible-collections/kubernetes.core/pull/676).
|
||||
- align `helmdiff_check()` function commandline rendering with the `deploy()` function (https://github.com/ansible-collections/kubernetes.core/pull/670).
|
||||
- avoid unsafe conditions in integration tests (https://github.com/ansible-collections/kubernetes.core/pull/665).
|
||||
- helm - use ``reuse-values`` when running ``helm diff`` command (https://github.com/ansible-collections/kubernetes.core/issues/680).
|
||||
- integrations test helm_kubeconfig - set helm version to v3.10.3 to avoid incompatability with new bitnami charts (https://github.com/ansible-collections/kubernetes.core/pull/670).
|
||||
|
||||
v3.3.1
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This release fixes the CI issues with the ``linters`` workflow.
|
||||
|
||||
v3.3.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This release comes with improvements to the error messages in the k8s_drain module and several bug fixes.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- k8s_drain - Improve error message for pod disruption budget when draining a node (https://github.com/ansible-collections/kubernetes.core/issues/797).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- helm - Helm version checks did not support RC versions. They now accept any version tags. (https://github.com/ansible-collections/kubernetes.core/pull/745).
|
||||
- helm_pull - Apply no_log=True to pass_credentials to silence false positive warning. (https://github.com/ansible-collections/kubernetes.core/pull/796).
|
||||
- k8s_drain - Fix k8s_drain does not wait for single pod (https://github.com/ansible-collections/kubernetes.core/issues/769).
|
||||
- k8s_drain - Fix k8s_drain runs into a timeout when evicting a pod which is part of a stateful set (https://github.com/ansible-collections/kubernetes.core/issues/792).
|
||||
- kubeconfig option should not appear in module invocation log (https://github.com/ansible-collections/kubernetes.core/issues/782).
|
||||
- kustomize - kustomize plugin fails with deprecation warnings (https://github.com/ansible-collections/kubernetes.core/issues/639).
|
||||
- waiter - Fix waiting for daemonset when desired number of pods is 0. (https://github.com/ansible-collections/kubernetes.core/pull/756).
|
||||
|
||||
v3.2.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This release comes with documentation updates.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- connection/kubectl.py - Added an example of using the kubectl connection plugin to the documentation (https://github.com/ansible-collections/kubernetes.core/pull/741).
|
||||
- inventory/k8s.py - Defer removal of k8s inventory plugin to version 5.0 (https://github.com/ansible-collections/kubernetes.core/pull/723).
|
||||
- inventory/k8s.py - Defer removal of k8s inventory plugin to version 6.0.0 (https://github.com/ansible-collections/kubernetes.core/pull/734).
|
||||
|
||||
v3.1.0
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This release comes with some bugfixes and documentation updates. It also adds new features to the kubectl connection plugin and the kustomize lookup plugin.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- kubectl - added support of local enviroment variable that will be used for kubectl and may be requried for establishing connections ifself (https://github.com/ansible-collections/kubernetes.core/pull/702)
|
||||
- kustomize - new parameter added to --enable-helm (https://github.com/ansible-collections/kubernetes.core/issues/568)
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- helm - expand kubeconfig path with user's home directory for consistency with k8s
|
||||
- k8s_json_patch - rename action symlink to ensure k8s action plugin is used (https://github.com/ansible-collections/kubernetes.core/pull/652).
|
||||
|
||||
v3.0.1
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This release fixes issue with resources discovery when complex subresources are present, and fixes issues with `reuse-values` parameter for helm module.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Resolve Collections util resource discovery fails when complex subresources present (https://github.com/ansible-collections/kubernetes.core/pull/676).
|
||||
- align `helmdiff_check()` function commandline rendering with the `deploy()` function (https://github.com/ansible-collections/kubernetes.core/pull/670).
|
||||
- helm - use ``reuse-values`` when running ``helm diff`` command (https://github.com/ansible-collections/kubernetes.core/issues/680).
|
||||
- integrations test helm_kubeconfig - set helm version to v3.10.3 to avoid incompatability with new bitnami charts (https://github.com/ansible-collections/kubernetes.core/pull/670).
|
||||
|
||||
v3.0.0
|
||||
======
|
||||
|
||||
@@ -48,7 +48,7 @@ Where modules have multiple parameters we recommend running through the 4-step m
|
||||
|
||||
For general information on running the integration tests see the
|
||||
[Integration Tests page of the Module Development Guide](https://docs.ansible.com/ansible/devel/dev_guide/testing_integration.html#testing-integration),
|
||||
especially the section on configuration for cloud tests. For questions about writing tests the Ansible Kubernetes community can be found on Libera.Chat IRC as detailed below.
|
||||
especially the section on configuration for cloud tests.
|
||||
|
||||
### Updating documentation
|
||||
|
||||
@@ -70,11 +70,3 @@ Review the changes and create a pull request using updated files.
|
||||
The `kubernetes.core` collection follows the Ansible project's
|
||||
[Code of Conduct](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html).
|
||||
Please read and familiarize yourself with this document.
|
||||
|
||||
### IRC
|
||||
Our IRC channels may require you to register your nickname. If you receive an error when you connect, see
|
||||
[Libera.Chat's Nickname Registration guide](https://libera.chat/guides/registration) for instructions.
|
||||
|
||||
The `#ansible-kubernetes` channel on [libera.chat](https://libera.chat/) IRC is the main and official place to discuss use and development of the `kubernetes.core` collection.
|
||||
|
||||
For more information about Ansible's Kubernetes integration, browse the resources in the [Kubernetes Working Group](https://github.com/ansible/community/wiki/Kubernetes) Community wiki page.
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,5 +1,5 @@
|
||||
# Also needs to be updated in galaxy.yml
|
||||
VERSION = 3.0.0
|
||||
VERSION = 6.2.0
|
||||
|
||||
TEST_ARGS ?= ""
|
||||
PYTHON_VERSION ?= `python -c 'import platform; print(".".join(platform.python_version_tuple()[0:2]))'`
|
||||
|
||||
78
README.md
78
README.md
@@ -1,34 +1,46 @@
|
||||
# Kubernetes Collection for Ansible
|
||||
|
||||
[](https://github.com/ansible-collections/kubernetes.core/actions) [](https://codecov.io/gh/ansible-collections/kubernetes.core)
|
||||
|
||||
This repository hosts the `kubernetes.core` (formerly known as `community.kubernetes`) Ansible Collection.
|
||||
|
||||
## Description
|
||||
|
||||
The collection includes a variety of Ansible content to help automate the management of applications in Kubernetes and OpenShift clusters, as well as the provisioning and maintenance of clusters themselves.
|
||||
|
||||
## Communication
|
||||
|
||||
* Join the Ansible forum:
|
||||
* [Get Help](https://forum.ansible.com/c/help/6): get help or help others.
|
||||
* [Posts tagged with 'kubernetes'](https://forum.ansible.com/tag/kubernetes): subscribe to participate in collection-related conversations.
|
||||
* [Social Spaces](https://forum.ansible.com/c/chat/4): gather and interact with fellow enthusiasts.
|
||||
* [News & Announcements](https://forum.ansible.com/c/news/5): track project-wide announcements including social events.
|
||||
|
||||
* The Ansible [Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn): used to announce releases and important changes.
|
||||
|
||||
For more information about communication, see the [Ansible communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
|
||||
|
||||
## Requirements
|
||||
|
||||
<!--start requires_ansible-->
|
||||
## Ansible version compatibility
|
||||
|
||||
This collection has been tested against following Ansible versions: **>=2.14.0**.
|
||||
This collection has been tested against the following Ansible versions: **>=2.16.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.
|
||||
A collection may contain metadata that identifies these versions.
|
||||
PEP440 is the schema used to describe the versions of Ansible.
|
||||
<!--end requires_ansible-->
|
||||
|
||||
## Python Support
|
||||
### Python Support
|
||||
|
||||
* Collection supports 3.9+
|
||||
|
||||
Note: Python2 is deprecated from [1st January 2020](https://www.python.org/doc/sunset-python-2/). Please switch to Python3.
|
||||
|
||||
## Kubernetes Version Support
|
||||
### Kubernetes Version Support
|
||||
|
||||
This collection supports Kubernetes versions >= 1.24.
|
||||
|
||||
## Included content
|
||||
### Included Content
|
||||
|
||||
Click on the name of a plugin or module to view that content's documentation:
|
||||
|
||||
@@ -43,11 +55,6 @@ Name | Description
|
||||
--- | ---
|
||||
kubernetes.core.k8s_config_resource_name|Generate resource name for the given resource of type ConfigMap, Secret
|
||||
|
||||
### 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
|
||||
--- | ---
|
||||
@@ -62,6 +69,7 @@ Name | Description
|
||||
[kubernetes.core.helm_plugin](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_plugin_module.rst)|Manage Helm plugins
|
||||
[kubernetes.core.helm_plugin_info](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_plugin_info_module.rst)|Gather information about Helm plugins
|
||||
[kubernetes.core.helm_pull](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_pull_module.rst)|download a chart from a repository and (optionally) unpack it in local directory.
|
||||
[kubernetes.core.helm_registry_auth](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_registry_auth_module.rst)|Helm registry authentication module
|
||||
[kubernetes.core.helm_repository](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_repository_module.rst)|Manage Helm repositories.
|
||||
[kubernetes.core.helm_template](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_template_module.rst)|Render chart templates
|
||||
[kubernetes.core.k8s](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_module.rst)|Manage Kubernetes (K8s) objects
|
||||
@@ -79,9 +87,7 @@ Name | Description
|
||||
|
||||
<!--end collection content-->
|
||||
|
||||
## Installation and Usage
|
||||
|
||||
### Installing the Collection from Ansible Galaxy
|
||||
## Installation
|
||||
|
||||
Before using the Kubernetes collection, you need to install it with the Ansible Galaxy CLI:
|
||||
|
||||
@@ -93,7 +99,7 @@ You can also include it in a `requirements.yml` file and install it via `ansible
|
||||
---
|
||||
collections:
|
||||
- name: kubernetes.core
|
||||
version: 3.0.0
|
||||
version: 6.2.0
|
||||
```
|
||||
|
||||
### Installing the Kubernetes Python Library
|
||||
@@ -102,7 +108,7 @@ Content in this collection requires the [Kubernetes Python client](https://pypi.
|
||||
|
||||
pip3 install kubernetes
|
||||
|
||||
### Using modules from the Kubernetes Collection in your playbooks
|
||||
## Use Cases
|
||||
|
||||
It's preferable to use content in this collection using their Fully Qualified Collection Namespace (FQCN), for example `kubernetes.core.k8s_info`:
|
||||
|
||||
@@ -170,7 +176,7 @@ If upgrading older playbooks which were built prior to Ansible 2.10 and this col
|
||||
|
||||
For documentation on how to use individual modules and other content included in this collection, please see the links in the 'Included content' section earlier in this README.
|
||||
|
||||
## Ansible Turbo mode Tech Preview
|
||||
## Ansible Turbo Mode Tech Preview
|
||||
|
||||
|
||||
The ``kubernetes.core`` collection supports Ansible Turbo mode as a tech preview via the ``cloud.common`` collection. By default, this feature is disabled. To enable Turbo mode for modules, set the environment variable `ENABLE_TURBO_MODE=1` on the managed node. For example:
|
||||
@@ -189,12 +195,16 @@ defined in the playbook using `environment` keyword as above, you must set it us
|
||||
|
||||
Please read more about Ansible Turbo mode - [here](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/ansible_turbo_mode.rst).
|
||||
|
||||
## Testing and Development
|
||||
## Contributing to this Collection
|
||||
|
||||
If you want to develop new content for this collection or improve what's already here, the easiest way to work on the collection is to clone it into one of the configured [`COLLECTIONS_PATHS`](https://docs.ansible.com/ansible/latest/reference_appendices/config.html#collections-paths), and work on it there.
|
||||
|
||||
See [Contributing to kubernetes.core](CONTRIBUTING.md).
|
||||
|
||||
## Testing
|
||||
|
||||
[](https://github.com/ansible-collections/kubernetes.core/actions/workflows/linters.yaml) [](https://github.com/ansible-collections/kubernetes.core/actions/workflows/integration-tests.yaml) [](https://github.com/ansible-collections/kubernetes.core/actions/workflows/sanity-tests.yaml) [](https://github.com/ansible-collections/kubernetes.core/actions/workflows/unit-tests.yaml) [](https://app.codecov.io/gh/ansible-collections/kubernetes.core)
|
||||
|
||||
### Testing with `ansible-test`
|
||||
|
||||
The `tests` directory contains configuration for running sanity and integration tests using [`ansible-test`](https://docs.ansible.com/ansible/latest/dev_guide/testing_integration.html).
|
||||
@@ -231,9 +241,33 @@ After the version is published, verify it exists on the [Kubernetes Collection G
|
||||
|
||||
The process for uploading a supported release to Automation Hub is documented separately.
|
||||
|
||||
## More Information
|
||||
## Support
|
||||
|
||||
<!--List available communication channels. In addition to channels specific to your collection, we also recommend to use the following ones.-->
|
||||
|
||||
> **Note:** The `stable-4` branch, which handles all `4.x.y` releases of this collection, is no longer supported. This means that no backports nor releases will be performed on the `stable-4` branch.
|
||||
|
||||
We announce releases and important changes through Ansible's [The Bullhorn newsletter](https://github.com/ansible/community/wiki/News#the-bullhorn). Be sure you are [subscribed](https://eepurl.com/gZmiEP).
|
||||
|
||||
We take part in the global quarterly [Ansible Contributor Summit](https://github.com/ansible/community/wiki/Contributor-Summit) virtually or in-person. Track [The Bullhorn newsletter](https://eepurl.com/gZmiEP) and join us.
|
||||
|
||||
For more information about communication, refer to the [Ansible Communication guide](https://docs.ansible.com/ansible/devel/community/communication.html).
|
||||
|
||||
For the latest supported versions, refer to the release notes below.
|
||||
|
||||
If you encounter issues or have questions, you can submit a support request through the following channels:
|
||||
- GitHub Issues: Report bugs, request features, or ask questions by opening an issue in the [GitHub repository]((https://github.com/ansible-collections/kubernetes.core/).
|
||||
|
||||
## Release Notes
|
||||
|
||||
See the [raw generated changelog](https://github.com/ansible-collections/kubernetes.core/blob/main/CHANGELOG.rst).
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
We follow the [Ansible Code of Conduct](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html) in all our interactions within this project.
|
||||
|
||||
If you encounter abusive behavior, please refer to the [policy violations](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html#policy-violations) section of the Code for information on how to raise a complaint.
|
||||
|
||||
For more information about Ansible's Kubernetes integration, join the `#ansible-kubernetes` channel on [libera.chat](https://libera.chat/) IRC, and browse the resources in the [Kubernetes Working Group](https://github.com/ansible/community/wiki/Kubernetes) Community wiki page.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -814,3 +814,316 @@ releases:
|
||||
- remove_ansible_2_13.yaml
|
||||
- update_supported_versions.yaml
|
||||
release_date: '2023-11-17'
|
||||
3.0.1:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Resolve Collections util resource discovery fails when complex subresources
|
||||
present (https://github.com/ansible-collections/kubernetes.core/pull/676).
|
||||
- align `helmdiff_check()` function commandline rendering with the `deploy()`
|
||||
function (https://github.com/ansible-collections/kubernetes.core/pull/670).
|
||||
- helm - use ``reuse-values`` when running ``helm diff`` command (https://github.com/ansible-collections/kubernetes.core/issues/680).
|
||||
- integrations test helm_kubeconfig - set helm version to v3.10.3 to avoid incompatability
|
||||
with new bitnami charts (https://github.com/ansible-collections/kubernetes.core/pull/670).
|
||||
release_summary: This release fixes issue with resources discovery when complex
|
||||
subresources are present, and fixes issues with `reuse-values` parameter for
|
||||
helm module.
|
||||
fragments:
|
||||
- 20240117-fix-helm-diff-cmd-line-rendering.yml
|
||||
- 20240222-Collections-util-resource-discovery-fails-when-complex-subresources-present.yml
|
||||
- 20240228-fix-helm-diff-with-reuse-values.yml
|
||||
- 3.0.1.yml
|
||||
release_date: '2024-03-01'
|
||||
3.1.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- helm - expand kubeconfig path with user's home directory for consistency with
|
||||
k8s
|
||||
- k8s_json_patch - rename action symlink to ensure k8s action plugin is used
|
||||
(https://github.com/ansible-collections/kubernetes.core/pull/652).
|
||||
minor_changes:
|
||||
- kubectl - added support of local enviroment variable that will be used for
|
||||
kubectl and may be requried for establishing connections ifself (https://github.com/ansible-collections/kubernetes.core/pull/702)
|
||||
- kustomize - new parameter added to --enable-helm (https://github.com/ansible-collections/kubernetes.core/issues/568)
|
||||
release_summary: This release comes with some bugfixes and documentation updates.
|
||||
It also adds new features to the kubectl connection plugin and the kustomize
|
||||
lookup plugin.
|
||||
fragments:
|
||||
- 20240426-add-support-of-kubectl-local-env-vars-for-connection-plugin.yml
|
||||
- 3.1.0.yml
|
||||
- 592-kustomize-helm-support.yml
|
||||
- 652-fix-json-patch-action.yml
|
||||
- 654-helm-expand-user.yml
|
||||
release_date: '2024-05-16'
|
||||
3.2.0:
|
||||
changes:
|
||||
minor_changes:
|
||||
- connection/kubectl.py - Added an example of using the kubectl connection plugin
|
||||
to the documentation (https://github.com/ansible-collections/kubernetes.core/pull/741).
|
||||
- inventory/k8s.py - Defer removal of k8s inventory plugin to version 5.0 (https://github.com/ansible-collections/kubernetes.core/pull/723).
|
||||
- inventory/k8s.py - Defer removal of k8s inventory plugin to version 6.0.0
|
||||
(https://github.com/ansible-collections/kubernetes.core/pull/734).
|
||||
release_summary: This release comes with documentation updates.
|
||||
fragments:
|
||||
- 20240530-defer-removal-and-ansible-core-support-update.yaml
|
||||
- 20240601-doc-example-of-using-kubectl.yaml
|
||||
- 3.2.0.yml
|
||||
- inventory-update_removal_date.yml
|
||||
release_date: '2024-06-14'
|
||||
3.3.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- helm - Helm version checks did not support RC versions. They now accept any
|
||||
version tags. (https://github.com/ansible-collections/kubernetes.core/pull/745).
|
||||
- helm_pull - Apply no_log=True to pass_credentials to silence false positive
|
||||
warning. (https://github.com/ansible-collections/kubernetes.core/pull/796).
|
||||
- k8s_drain - Fix k8s_drain does not wait for single pod (https://github.com/ansible-collections/kubernetes.core/issues/769).
|
||||
- k8s_drain - Fix k8s_drain runs into a timeout when evicting a pod which is
|
||||
part of a stateful set (https://github.com/ansible-collections/kubernetes.core/issues/792).
|
||||
- kubeconfig option should not appear in module invocation log (https://github.com/ansible-collections/kubernetes.core/issues/782).
|
||||
- kustomize - kustomize plugin fails with deprecation warnings (https://github.com/ansible-collections/kubernetes.core/issues/639).
|
||||
- waiter - Fix waiting for daemonset when desired number of pods is 0. (https://github.com/ansible-collections/kubernetes.core/pull/756).
|
||||
minor_changes:
|
||||
- k8s_drain - Improve error message for pod disruption budget when draining
|
||||
a node (https://github.com/ansible-collections/kubernetes.core/issues/797).
|
||||
release_summary: This release comes with improvements to the error messages
|
||||
in the k8s_drain module and several bug fixes.
|
||||
fragments:
|
||||
- 20240530-ansible-core-support-update.yaml
|
||||
- 20240611-helm-rc-version.yaml
|
||||
- 20240620-fix-kustomize-plugin-fails-with-deprecation-warnings.yml
|
||||
- 20241102-fix-ci-post-2.18-issue.yaml
|
||||
- 20241213-kubeconfig-set-no_log-true.yaml
|
||||
- 756-fix-daemonset-waiting.yaml
|
||||
- 770-fix-k8s-drain-doesnt-wait-for-single-pod.yaml
|
||||
- 793-fix-k8s-drain-runs-into-timeout.yaml
|
||||
- 796-false-positive-helmull.yaml
|
||||
- 798-drain-pdb-error-message.yaml
|
||||
- readme_template_update.yml
|
||||
release_date: '2025-01-20'
|
||||
3.3.1:
|
||||
changes:
|
||||
release_summary: This release fixes the CI issues with the ``linters`` workflow.
|
||||
fragments:
|
||||
- release_summary.yml
|
||||
release_date: '2025-03-26'
|
||||
4.0.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- Resolve Collections util resource discovery fails when complex subresources
|
||||
present (https://github.com/ansible-collections/kubernetes.core/pull/676).
|
||||
- align `helmdiff_check()` function commandline rendering with the `deploy()`
|
||||
function (https://github.com/ansible-collections/kubernetes.core/pull/670).
|
||||
- avoid unsafe conditions in integration tests (https://github.com/ansible-collections/kubernetes.core/pull/665).
|
||||
- helm - use ``reuse-values`` when running ``helm diff`` command (https://github.com/ansible-collections/kubernetes.core/issues/680).
|
||||
- integrations test helm_kubeconfig - set helm version to v3.10.3 to avoid incompatability
|
||||
with new bitnami charts (https://github.com/ansible-collections/kubernetes.core/pull/670).
|
||||
minor_changes:
|
||||
- inventory/k8s.py - Defer removal of k8s inventory plugin to version 5.0 (https://github.com/ansible-collections/kubernetes.core/pull/723).
|
||||
- k8s - The module and K8sService were changed so warnings returned by the K8S
|
||||
API are now displayed to the user.
|
||||
release_summary: This major release brings several bug fixes. We have also removed
|
||||
support for ``ansible-core<2.15`` and deprecated functions and class from
|
||||
``module_utils/common.py``.
|
||||
removed_features:
|
||||
- k8s - Support for ``merge_type=json`` has been removed in version 4.0.0. Please
|
||||
use ``kubernetes.core.k8s_json_patch`` instead (https://github.com/ansible-collections/kubernetes.core/pull/722).
|
||||
- k8s_exec - the previously deprecated ``result.return_code`` return value has
|
||||
been removed, consider using ``result.rc`` instead (https://github.com/ansible-collections/kubernetes.core/pull/726).
|
||||
- module_utils/common.py - the previously deprecated ``K8sAnsibleMixin`` class
|
||||
has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
|
||||
- module_utils/common.py - the previously deprecated ``configuration_digest()``
|
||||
function has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
|
||||
- module_utils/common.py - the previously deprecated ``get_api_client()`` function
|
||||
has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
|
||||
- module_utils/common.py - the previously deprecated ``unique_string()`` function
|
||||
has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
|
||||
fragments:
|
||||
- 20231206-fix-unsafe-condition-in-integration.yml
|
||||
- 20240117-fix-helm-diff-cmd-line-rendering.yml
|
||||
- 20240222-Collections-util-resource-discovery-fails-when-complex-subresources-present.yml
|
||||
- 20240228-fix-helm-diff-with-reuse-values.yml
|
||||
- 20240423-k8s-display-warnings-to-users.yml
|
||||
- 4.0.0.yaml
|
||||
- inventory-update_removal_date.yml
|
||||
- k8s-merge_type-removed.yml
|
||||
- module_utils-common-remove-deprecated-functions-and-class.yaml
|
||||
release_date: '2024-05-24'
|
||||
5.0.0:
|
||||
changes:
|
||||
breaking_changes:
|
||||
- Remove support for ``ansible-core<2.15`` (https://github.com/ansible-collections/kubernetes.core/pull/737).
|
||||
minor_changes:
|
||||
- connection/kubectl.py - Added an example of using the kubectl connection plugin
|
||||
to the documentation (https://github.com/ansible-collections/kubernetes.core/pull/741).
|
||||
- inventory/k8s.py - Defer removal of k8s inventory plugin to version 6.0.0
|
||||
(https://github.com/ansible-collections/kubernetes.core/pull/734).
|
||||
release_summary: This major release drops support for ``ansible-core<2.15``.
|
||||
fragments:
|
||||
- 20240530-ansible-core-support-update.yaml
|
||||
- 20240530-defer-removal-and-ansible-core-support-update.yaml
|
||||
- 5.0.0.yml
|
||||
release_date: '2024-05-31'
|
||||
5.1.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- helm - Helm version checks did not support RC versions. They now accept any
|
||||
version tags. (https://github.com/ansible-collections/kubernetes.core/pull/745).
|
||||
- helm_pull - Apply no_log=True to pass_credentials to silence false positive
|
||||
warning. (https://github.com/ansible-collections/kubernetes.core/pull/796).
|
||||
- k8s_drain - Fix k8s_drain does not wait for single pod (https://github.com/ansible-collections/kubernetes.core/issues/769).
|
||||
- k8s_drain - Fix k8s_drain runs into a timeout when evicting a pod which is
|
||||
part of a stateful set (https://github.com/ansible-collections/kubernetes.core/issues/792).
|
||||
- kubeconfig option should not appear in module invocation log (https://github.com/ansible-collections/kubernetes.core/issues/782).
|
||||
- kustomize - kustomize plugin fails with deprecation warnings (https://github.com/ansible-collections/kubernetes.core/issues/639).
|
||||
- waiter - Fix waiting for daemonset when desired number of pods is 0. (https://github.com/ansible-collections/kubernetes.core/pull/756).
|
||||
minor_changes:
|
||||
- Bump version of ``ansible-lint`` to minimum 24.7.0 (https://github.com/ansible-collections/kubernetes.core/pull/765).
|
||||
- Parameter insecure_registry added to helm_template as equivalent of insecure-skip-tls-verify
|
||||
(https://github.com/ansible-collections/kubernetes.core/pull/805).
|
||||
- k8s_drain - Improve error message for pod disruption budget when draining
|
||||
a node (https://github.com/ansible-collections/kubernetes.core/issues/797).
|
||||
release_summary: This release came with new module ``helm_registry_auth``, improvements
|
||||
to the error messages in the k8s_drain module, new parameter ``insecure_registry``
|
||||
for ``helm_template`` module and several bug fixes.
|
||||
fragments:
|
||||
- 0-readme.yml
|
||||
- 20240601-doc-example-of-using-kubectl.yaml
|
||||
- 20240611-helm-rc-version.yaml
|
||||
- 20240620-fix-kustomize-plugin-fails-with-deprecation-warnings.yml
|
||||
- 20241102-fix-ci-post-2.18-issue.yaml
|
||||
- 20241103-completly-remove-obsolate-communication-channel.yaml
|
||||
- 20241207-add-insecure-skip-tls-verify-to-helm-template.yaml
|
||||
- 20241213-kubeconfig-set-no_log-true.yaml
|
||||
- 756-fix-daemonset-waiting.yaml
|
||||
- 765-bump-ansible-lint-version.yml
|
||||
- 770-fix-k8s-drain-doesnt-wait-for-single-pod.yaml
|
||||
- 793-fix-k8s-drain-runs-into-timeout.yaml
|
||||
- 796-false-positive-helmull.yaml
|
||||
- 798-drain-pdb-error-message.yaml
|
||||
- readme_template_update.yml
|
||||
modules:
|
||||
- description: Helm registry authentication module
|
||||
name: helm_registry_auth
|
||||
namespace: ''
|
||||
release_date: '2025-01-20'
|
||||
5.2.0:
|
||||
changes:
|
||||
minor_changes:
|
||||
- k8s - Extend hidden_fields to allow the expression of more complex field types
|
||||
to be hidden (https://github.com/ansible-collections/kubernetes.core/pull/872)
|
||||
- k8s_info - Extend hidden_fields to allow the expression of more complex field
|
||||
types to be hidden (https://github.com/ansible-collections/kubernetes.core/pull/872)
|
||||
- 'waiter.py - add ClusterOperator support. The module can now check OpenShift
|
||||
cluster health by verifying ClusterOperator status requiring ''Available:
|
||||
True'', ''Degraded: False'', and ''Progressing: False'' for success. (https://github.com/ansible-collections/kubernetes.core/issues/869)'
|
||||
release_summary: This release adds more functionality to the hidden_fields option
|
||||
and support for waiting on ClusterOperators to reach a ready state.
|
||||
fragments:
|
||||
- 5.2.0.yml
|
||||
- 643-extend-hidden-fields.yaml
|
||||
- 879-clusteroperator-waiter.py.yaml
|
||||
release_date: '2025-03-27'
|
||||
5.3.0:
|
||||
changes:
|
||||
bugfixes:
|
||||
- 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).
|
||||
minor_changes:
|
||||
- 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
|
||||
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 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
|
||||
ansible-lint version to ``25.1.2``.
|
||||
fragments:
|
||||
- 20250324-k8s_info-templating.yaml
|
||||
- 5.3.0.yml
|
||||
- 694-add-insecure-skip-tls-verify.yml
|
||||
- 800-helm-add-reset_then_reuse_values-support.yml
|
||||
- 898-k8s-dont-delete-in-check-mode.yaml
|
||||
- 919-update-ansible-lint-version.yaml
|
||||
release_date: '2025-05-16'
|
||||
5.4.0:
|
||||
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).
|
||||
release_summary: This release updates the ``helm_registry_auth`` module to match the behavior of ``helm >= 3.18.0`` which reports a successful logout regardless of the current state (i.e., no idempotency).
|
||||
fragments:
|
||||
- 20250411-kubeconfig-no_log-revert.yaml
|
||||
- 20250503-fix-unit-tests.yml
|
||||
- 20250605-fix-helm_registry_auth-integration_test.yaml
|
||||
- 5.4.0.yml
|
||||
release_date: '2025-08-12'
|
||||
5.4.1:
|
||||
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).
|
||||
- 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,
|
||||
k8s_cp init containers support, and removes deprecated ansible.module_utils.six
|
||||
imports.
|
||||
fragments:
|
||||
- 20250428-k8s-service-hide-fields-first.yaml
|
||||
- 20250731-fix-k8s_cp-initcontainers.yaml
|
||||
- 20250922-remove-ansible-six-imports.yaml
|
||||
- 5.4.1.yml
|
||||
release_date: '2025-10-07'
|
||||
6.0.0:
|
||||
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 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).
|
||||
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'
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
.. _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:
|
||||
|
||||
- Ansible 2.9.17 or latest installed
|
||||
- Ansible 2.16.0 or latest installed
|
||||
- `Kubernetes Python client <https://pypi.org/project/kubernetes/>`_ installed on the host that will execute the modules.
|
||||
|
||||
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
.. _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,6 +13,5 @@ To get started, please select one of the following topics.
|
||||
:maxdepth: 1
|
||||
|
||||
kubernetes_scenarios/k8s_intro
|
||||
kubernetes_scenarios/k8s_inventory
|
||||
kubernetes_scenarios/k8s_scenarios
|
||||
|
||||
|
||||
@@ -289,6 +289,29 @@ Parameters
|
||||
<div>Provide a URL for accessing the API. Can also be specified via <code>K8S_AUTH_HOST</code> environment variable.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>insecure_skip_tls_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 5.3.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>Skip tls certificate checks for the chart download.</div>
|
||||
<div>Do not confuse with the <code>validate_certs</code> option.</div>
|
||||
<div>This option is only available for helm >= 3.16.0.</div>
|
||||
<div style="font-size: small; color: darkgreen"><br/>aliases: skip_tls_certs_check</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
@@ -307,6 +330,27 @@ Parameters
|
||||
<div style="font-size: small; color: darkgreen"><br/>aliases: kubeconfig_path</div>
|
||||
</td>
|
||||
</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>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
@@ -435,6 +479,28 @@ Parameters
|
||||
<div>mutually exclusive with with <code>history_max</code>.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>reset_then_reuse_values</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.0.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>When upgrading package, reset the values to the ones built into the chart, apply the last release's values and merge in any overrides from parameters O(release_values), O(values_files) or O(set_values).</div>
|
||||
<div>If O(reset_values) or O(reuse_values) is set to V(True), this is ignored.</div>
|
||||
<div>This feature requires helm diff >= 3.9.12.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
@@ -443,7 +509,7 @@ Parameters
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.5.0</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.0.0</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
@@ -463,7 +529,7 @@ Parameters
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.5.0</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.0.0</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
@@ -556,6 +622,48 @@ Parameters
|
||||
<div>Skip custom resource definitions when installing or upgrading.</div>
|
||||
</td>
|
||||
</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>When upgrading, 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>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
@@ -765,6 +873,12 @@ Examples
|
||||
chart_ref: "https://github.com/grafana/helm-charts/releases/download/grafana-5.6.0/grafana-5.6.0.tgz"
|
||||
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
|
||||
- name: Deploy new-relic client chart
|
||||
kubernetes.core.helm:
|
||||
|
||||
@@ -193,6 +193,27 @@ Parameters
|
||||
<div>Pass credentials to all domains.</div>
|
||||
</td>
|
||||
</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>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
@@ -279,7 +300,8 @@ Parameters
|
||||
</td>
|
||||
<td>
|
||||
<div>Whether or not to check tls certificate for the chart download.</div>
|
||||
<div>Requires helm >= 3.3.0.</div>
|
||||
<div>Requires helm >= 3.3.0. Alias <code>insecure_skip_tls_verify</code> added in 5.3.0.</div>
|
||||
<div style="font-size: small; color: darkgreen"><br/>aliases: insecure_skip_tls_verify</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
333
docs/kubernetes.core.helm_registry_auth_module.rst
Normal file
333
docs/kubernetes.core.helm_registry_auth_module.rst
Normal file
@@ -0,0 +1,333 @@
|
||||
.. _kubernetes.core.helm_registry_auth_module:
|
||||
|
||||
|
||||
**********************************
|
||||
kubernetes.core.helm_registry_auth
|
||||
**********************************
|
||||
|
||||
**Helm registry authentication module**
|
||||
|
||||
|
||||
Version added: 5.1.0
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:depth: 1
|
||||
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
- Helm registry authentication module allows you to login ``helm registry login`` and logout ``helm registry logout`` from a Helm registry.
|
||||
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
The below requirements are needed on the host that executes this module.
|
||||
|
||||
- helm (https://github.com/helm/helm/releases) => 3.8.0
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Parameter</th>
|
||||
<th>Choices/<font color="blue">Defaults</font></th>
|
||||
<th width="100%">Comments</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>binary_path</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">path</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>The path of a helm binary to use.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>ca_file</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">path</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Path to the CA certificate SSL file for verify registry server certificate.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>cert_file</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">path</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Path to the client certificate SSL file for identify registry client using this certificate file.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>host</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
/ <span style="color: red">required</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Provide a URL for accessing the registry.</div>
|
||||
<div style="font-size: small; color: darkgreen"><br/>aliases: registry_url</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>insecure</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||
<li>yes</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Allow connections to SSL sites without certs.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>key_file</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">path</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Path to the client key SSL file for identify registry client using this key file.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>password</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Password for the registry.</div>
|
||||
<div style="font-size: small; color: darkgreen"><br/>aliases: repo_password</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>state</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li><div style="color: blue"><b>present</b> ←</div></li>
|
||||
<li>absent</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Desired state of the registry.</div>
|
||||
<div>If set to V(present) attempt to log in to the remote registry server using the URL specified in O(host).</div>
|
||||
<div>If set to V(absent) attempt to log out from the remote registry server using the URL specified in O(host).</div>
|
||||
<div>As helm >= 3.18.0 reports successful logout even if the user is not logged in, this module will report a change regardless of the current state.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>username</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Username for the registry.</div>
|
||||
<div style="font-size: small; color: darkgreen"><br/>aliases: repo_username</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: Login to remote registry
|
||||
kubernetes.core.helm_registry_auth:
|
||||
username: admin
|
||||
password: "sample_password"
|
||||
host: localhost:5000
|
||||
|
||||
- name: Logout from remote registry
|
||||
kubernetes.core.helm_registry_auth:
|
||||
state: absent
|
||||
host: localhost:5000
|
||||
|
||||
|
||||
|
||||
Return Values
|
||||
-------------
|
||||
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<table border=0 cellpadding=0 class="documentation-table">
|
||||
<tr>
|
||||
<th colspan="1">Key</th>
|
||||
<th>Returned</th>
|
||||
<th width="100%">Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>command</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always</td>
|
||||
<td>
|
||||
<div>Full <code>helm</code> command executed</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">/usr/local/bin/helm registry login oci-registry.domain.example --username=admin --password-stdin --insecure</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>failed</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always</td>
|
||||
<td>
|
||||
<div>Indicate if the <code>helm</code> command failed</div>
|
||||
<br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>stderr</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always</td>
|
||||
<td>
|
||||
<div>Full <code>helm</code> command stderr, in case you want to display it or examine the event log. Please be note that helm binnary may print messages to stderr even if the command is successful.</div>
|
||||
<br/>
|
||||
<div style="font-size: smaller"><b>Sample:</b></div>
|
||||
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">Login Succeeded\n</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>stderr_lines</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always</td>
|
||||
<td>
|
||||
<div>Full <code>helm</code> command stderr, in case you want to display it or examine the event log</div>
|
||||
<br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>stdout</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">string</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always</td>
|
||||
<td>
|
||||
<div>Full <code>helm</code> command stdout, in case you want to display it or examine the event log</div>
|
||||
<br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||
<b>stout_lines</b>
|
||||
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">list</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>always</td>
|
||||
<td>
|
||||
<div>Full <code>helm</code> command stdout, in case you want to display it or examine the event log</div>
|
||||
<br/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/><br/>
|
||||
|
||||
|
||||
Status
|
||||
------
|
||||
|
||||
|
||||
Authors
|
||||
~~~~~~~
|
||||
|
||||
- Yuriy Novostavskiy (@yurnov)
|
||||
@@ -143,6 +143,27 @@ Parameters
|
||||
<div>Provide a URL for accessing the API. Can also be specified via <code>K8S_AUTH_HOST</code> environment variable.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>insecure_skip_tls_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 5.3.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>Skip tls certificate checks for the repository url.</div>
|
||||
<div style="font-size: small; color: darkgreen"><br/>aliases: skip_tls_certs_check</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
|
||||
@@ -158,6 +158,26 @@ Parameters
|
||||
<div>Include custom resource descriptions in rendered templates.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>insecure_registry</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 5.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>Skip TLS certificate checks for the chart download</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
@@ -174,6 +194,27 @@ Parameters
|
||||
<div>If the directory already exists, it will be overwritten.</div>
|
||||
</td>
|
||||
</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>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
|
||||
@@ -512,6 +512,7 @@ Notes
|
||||
|
||||
.. note::
|
||||
- the tar binary is required on the container when copying from local filesystem to pod.
|
||||
- the (init) container has to be started before you copy files or directories to it.
|
||||
- To avoid SSL certificate validation errors when ``validate_certs`` is *True*, the full certificate chain for the API server must be provided via ``ca_cert`` or in the kubeconfig file.
|
||||
|
||||
|
||||
|
||||
@@ -423,7 +423,7 @@ Parameters
|
||||
<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 2.5.0</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.0.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
@@ -595,7 +595,8 @@ Examples
|
||||
kubernetes.core.k8s_drain:
|
||||
state: drain
|
||||
name: foo
|
||||
force: yes
|
||||
delete_options:
|
||||
force: yes
|
||||
|
||||
- name: Drain node "foo", but abort if there are pods not managed by a ReplicationController, Job, or DaemonSet, and use a grace period of 15 minutes.
|
||||
kubernetes.core.k8s_drain:
|
||||
|
||||
@@ -168,14 +168,13 @@ Parameters
|
||||
<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 2.5.0</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.0.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Hide fields matching any of the field definitions in the result</div>
|
||||
<div>An example might be <code>hidden_fields=[metadata.managedFields]</code></div>
|
||||
<div>Only field definitions that don't reference list items are supported (so V(spec.containers[0]) would not work)</div>
|
||||
<div>An example might be <code>hidden_fields=[metadata.managedFields]</code> or V(hidden_fields=[spec.containers[0].env[3].value]) or V(hidden_fields=[metadata.annotations[kubectl.kubernetes.io/last-applied-configuration]])</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -1,372 +0,0 @@
|
||||
.. _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 4.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 4.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,6 +140,25 @@ Parameters
|
||||
<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 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>
|
||||
<td colspan="2">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
|
||||
@@ -121,7 +121,7 @@ Parameters
|
||||
<td>
|
||||
<div><code>apply</code> compares the desired resource definition with the previously supplied resource definition, ignoring properties that are automatically generated</div>
|
||||
<div><code>apply</code> works better with Services than 'force=yes'</div>
|
||||
<div>mutually exclusive with <code>merge_type</code></div>
|
||||
<div>Mutually exclusive with <code>merge_type</code>.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -216,7 +216,7 @@ Parameters
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.5.0</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.0.0</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
@@ -389,14 +389,13 @@ Parameters
|
||||
<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 2.5.0</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.0.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Hide fields matching this option in the result</div>
|
||||
<div>An example might be <code>hidden_fields=[metadata.managedFields]</code></div>
|
||||
<div>Only field definitions that don't reference list items are supported (so V(spec.containers[0]) would not work)</div>
|
||||
<div>An example might be <code>hidden_fields=[metadata.managedFields]</code> or V(hidden_fields=[spec.containers[0].env[3].value]) or V(hidden_fields=[metadata.annotations[kubectl.kubernetes.io/last-applied-configuration]])</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -513,18 +512,17 @@ Parameters
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>json</li>
|
||||
<li>merge</li>
|
||||
<li>strategic-merge</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Whether to override the default patch merge approach with a specific type. By default, the strategic merge will typically be used.</div>
|
||||
<div>For example, Custom Resource Definitions typically aren't updatable by the usual strategic merge. You may want to use <code>merge</code> if you see "strategic merge patch format is not supported"</div>
|
||||
<div>For example, Custom Resource Definitions typically aren't updatable by the usual strategic merge. You may want to use <code>merge</code> if you see "strategic merge patch format is not supported".</div>
|
||||
<div>See <a href='https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/#use-a-json-merge-patch-to-update-a-deployment'>https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/#use-a-json-merge-patch-to-update-a-deployment</a></div>
|
||||
<div>If more than one <code>merge_type</code> is given, the merge_types will be tried in order. This defaults to <code>['strategic-merge', 'merge']</code>, which is ideal for using the same parameters on resource kinds that combine Custom Resources and built-in resources.</div>
|
||||
<div>mutually exclusive with <code>apply</code></div>
|
||||
<div><em>merge_type=json</em> is deprecated and will be removed in version 3.0.0. Please use <span class='module'>kubernetes.core.k8s_json_patch</span> instead.</div>
|
||||
<div>Mutually exclusive with <code>apply</code>.</div>
|
||||
<div><em>merge_type=json</em> has been removed in version 4.0.0. Please use <span class='module'>kubernetes.core.k8s_json_patch</span> instead.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -211,6 +211,27 @@ Parameters
|
||||
<div>The configuration can be provided as dictionary. Added in version 2.4.0.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>kubectl_local_env_vars</b>
|
||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></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 3.1.0</div>
|
||||
</td>
|
||||
<td>
|
||||
<b>Default:</b><br/><div style="color: blue">{}</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>var: ansible_kubectl_local_env_vars</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>Local enviromantal variable to be passed locally to the kubectl command line.</div>
|
||||
<div>Please be aware that this passes information directly on the command line and it could expose sensitive data.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
@@ -344,6 +365,82 @@ Parameters
|
||||
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: Run a command in a pod using local kubectl with kubeconfig file ~/.kube/config
|
||||
hosts: localhost
|
||||
gather_facts: no
|
||||
vars:
|
||||
ansible_connection: kubernetes.core.kubectl
|
||||
ansible_kubectl_namespace: my-namespace
|
||||
ansible_kubectl_pod: my-pod
|
||||
ansible_kubectl_container: my-container
|
||||
tasks:
|
||||
# be aware that the command is executed as the user that started the container
|
||||
# and requires python to be installed in the image
|
||||
- name: Run a command in a pod
|
||||
ansible.builtin.command: echo "Hello, World!"
|
||||
|
||||
- name: Run a command in a pod using local kubectl with inventory variables
|
||||
# Example inventory:
|
||||
# k8s:
|
||||
# hosts:
|
||||
# foo.example.com:
|
||||
# ansible_connection: kubernetes.core.kubectl
|
||||
# ansible_kubectl_kubeconfig: /root/.kube/foo.example.com.config
|
||||
# ansible_kubectl_pod: my-foo-pod
|
||||
# ansible_kubectl_container: my-foo-container
|
||||
# ansible_kubectl_namespace: my-foo-namespace
|
||||
# bar.example.com:
|
||||
# ansible_connection: kubernetes.core.kubectl
|
||||
# ansible_kubectl_kubeconfig: /root/.kube/bar.example.com.config
|
||||
# ansible_kubectl_pod: my-bar-pod
|
||||
# ansible_kubectl_container: my-bar-container
|
||||
# ansible_kubectl_namespace: my-bar-namespace
|
||||
hosts: k8s
|
||||
gather_facts: no
|
||||
tasks:
|
||||
# be aware that the command is executed as the user that started the container
|
||||
# and requires python to be installed in the image
|
||||
- name: Run a command in a pod
|
||||
ansible.builtin.command: echo "Hello, World!"
|
||||
|
||||
- name: Run a command in a pod using dynamic inventory
|
||||
hosts: localhost
|
||||
gather_facts: no
|
||||
vars:
|
||||
kubeconfig: /root/.kube/config
|
||||
namespace: my-namespace
|
||||
my_app: my-app
|
||||
tasks:
|
||||
- name: Get My App pod info based on label
|
||||
kubernetes.core.k8s_info:
|
||||
kubeconfig: "{{ kubeconfig }}"
|
||||
namespace: "{{ namespace }}"
|
||||
kind: Pod
|
||||
label_selectors: app.kubernetes.io/name = "{{ my_app }}"
|
||||
register: my_app_pod
|
||||
|
||||
- name: Get My App pod name
|
||||
ansible.builtin.set_fact:
|
||||
my_app_pod_name: "{{ my_app_pod.resources[0].metadata.name }}"
|
||||
|
||||
- name: Add My App pod to inventory
|
||||
ansible.builtin.add_host:
|
||||
name: "{{ my_app_pod_name }}"
|
||||
ansible_connection: kubernetes.core.kubectl
|
||||
ansible_kubectl_kubeconfig: "{{ kubeconfig }}"
|
||||
ansible_kubectl_pod: "{{ my_app_pod_name }}"
|
||||
ansible_kubectl_namespace: "{{ namespace }}"
|
||||
|
||||
- name: Run a command in My App pod
|
||||
# be aware that the command is executed as the user that started the container
|
||||
# and requires python to be installed in the image
|
||||
ansible.builtin.command: echo "Hello, World!"
|
||||
delegate_to: "{{ my_app_pod_name }}"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -77,6 +77,44 @@ Parameters
|
||||
<div>If omitted, '.' is assumed.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
<b>enable_helm</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>
|
||||
<b>Default:</b><br/><div style="color: blue">"False"</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>
|
||||
<div>Enable the helm chart inflation generator</div>
|
||||
</td>
|
||||
</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>
|
||||
<td colspan="1">
|
||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||
@@ -112,17 +150,29 @@ Examples
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: Run lookup using kustomize
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
resources: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kustomize') }}"
|
||||
|
||||
- name: Run lookup using kubectl kustomize
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
resources: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kubectl') }}"
|
||||
|
||||
- name: Create kubernetes resources for lookup output
|
||||
k8s:
|
||||
kubernetes.core.k8s:
|
||||
definition: "{{ lookup('kubernetes.core.kustomize', dir='/path/to/kustomization') }}"
|
||||
|
||||
- name: Create kubernetes resources for lookup output with `--enable-helm` set
|
||||
kubernetes.core.k8s:
|
||||
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
|
||||
|
||||
@@ -25,7 +25,7 @@ tags:
|
||||
- openshift
|
||||
- okd
|
||||
- cluster
|
||||
version: 3.0.0
|
||||
version: 6.2.0
|
||||
build_ignore:
|
||||
- .DS_Store
|
||||
- "*.tar.gz"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
requires_ansible: '>=2.14.0'
|
||||
requires_ansible: '>=2.16.0'
|
||||
|
||||
action_groups:
|
||||
helm:
|
||||
@@ -21,11 +21,10 @@ plugin_routing:
|
||||
openshift:
|
||||
redirect: community.okd.openshift
|
||||
k8s:
|
||||
deprecation:
|
||||
removal_version: 4.0.0
|
||||
tombstone:
|
||||
removal_version: 6.0.0
|
||||
warning_text: >-
|
||||
The k8s inventory plugin has been deprecated and
|
||||
will be removed in release 4.0.0.
|
||||
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.
|
||||
modules:
|
||||
k8s_auth:
|
||||
redirect: community.okd.k8s_auth
|
||||
|
||||
@@ -22,33 +22,20 @@ from ansible.errors import (
|
||||
)
|
||||
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.six import iteritems, string_types
|
||||
from ansible.plugins.action import ActionBase
|
||||
|
||||
try:
|
||||
from ansible.template import trust_as_template
|
||||
except ImportError:
|
||||
trust_as_template = None
|
||||
|
||||
class RemoveOmit(object):
|
||||
def __init__(self, buffer, omit_value):
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
raise AnsibleError("Failed to import the required Python library (PyYAML).")
|
||||
self.data = yaml.safe_load_all(buffer)
|
||||
self.omit = omit_value
|
||||
|
||||
def remove_omit(self, data):
|
||||
if isinstance(data, dict):
|
||||
result = dict()
|
||||
for key, value in iteritems(data):
|
||||
if value == self.omit:
|
||||
continue
|
||||
result[key] = self.remove_omit(value)
|
||||
return result
|
||||
if isinstance(data, list):
|
||||
return [self.remove_omit(v) for v in data if v != self.omit]
|
||||
return data
|
||||
|
||||
def output(self):
|
||||
return [self.remove_omit(d) for d in self.data]
|
||||
def _from_yaml_to_definition(buffer):
|
||||
try:
|
||||
import yaml
|
||||
except ImportError:
|
||||
raise AnsibleError("Failed to import the required Python library (PyYAML).")
|
||||
return list(yaml.safe_load_all(buffer))
|
||||
|
||||
|
||||
ENV_KUBECONFIG_PATH_SEPARATOR = ";" if platform.system() == "Windows" else ":"
|
||||
@@ -112,7 +99,7 @@ class ActionModule(ActionBase):
|
||||
"trim_blocks": True,
|
||||
"lstrip_blocks": False,
|
||||
}
|
||||
if isinstance(template, string_types):
|
||||
if isinstance(template, str):
|
||||
# treat this as raw_params
|
||||
template_param["path"] = template
|
||||
elif isinstance(template, dict):
|
||||
@@ -132,7 +119,7 @@ class ActionModule(ActionBase):
|
||||
):
|
||||
if s_type in template_args:
|
||||
value = ensure_type(template_args[s_type], "string")
|
||||
if value is not None and not isinstance(value, string_types):
|
||||
if value is not None and not isinstance(value, str):
|
||||
raise AnsibleActionFail(
|
||||
"%s is expected to be a string, but got %s instead"
|
||||
% (s_type, type(value))
|
||||
@@ -207,9 +194,8 @@ class ActionModule(ActionBase):
|
||||
"'template' is only a supported parameter for the 'k8s' module."
|
||||
)
|
||||
|
||||
omit_value = task_vars.get("omit")
|
||||
template_params = []
|
||||
if isinstance(template, string_types) or isinstance(template, dict):
|
||||
if isinstance(template, str) or isinstance(template, dict):
|
||||
template_params.append(self.get_template_args(template))
|
||||
elif isinstance(template, list):
|
||||
for element in template:
|
||||
@@ -230,17 +216,18 @@ class ActionModule(ActionBase):
|
||||
old_vars = self._templar.available_variables
|
||||
|
||||
default_environment = {}
|
||||
for key in (
|
||||
"newline_sequence",
|
||||
"variable_start_string",
|
||||
"variable_end_string",
|
||||
"block_start_string",
|
||||
"block_end_string",
|
||||
"trim_blocks",
|
||||
"lstrip_blocks",
|
||||
):
|
||||
if hasattr(self._templar.environment, key):
|
||||
default_environment[key] = getattr(self._templar.environment, key)
|
||||
if trust_as_template is None:
|
||||
for key in (
|
||||
"newline_sequence",
|
||||
"variable_start_string",
|
||||
"variable_end_string",
|
||||
"block_start_string",
|
||||
"block_end_string",
|
||||
"trim_blocks",
|
||||
"lstrip_blocks",
|
||||
):
|
||||
if hasattr(self._templar.environment, key):
|
||||
default_environment[key] = getattr(self._templar.environment, key)
|
||||
for template_item in template_params:
|
||||
# We need to convert unescaped sequences to proper escaped sequences for Jinja2
|
||||
newline_sequence = template_item["newline_sequence"]
|
||||
@@ -257,26 +244,35 @@ class ActionModule(ActionBase):
|
||||
with self.get_template_data(template_item["path"]) as template_data:
|
||||
# add ansible 'template' vars
|
||||
temp_vars = copy.deepcopy(task_vars)
|
||||
for key, value in iteritems(template_item):
|
||||
overrides = {}
|
||||
for key, value in template_item.items():
|
||||
if hasattr(self._templar.environment, key):
|
||||
if value is not None:
|
||||
setattr(self._templar.environment, key, value)
|
||||
else:
|
||||
overrides[key] = value
|
||||
if trust_as_template is None:
|
||||
setattr(self._templar.environment, key, value)
|
||||
elif trust_as_template is None:
|
||||
setattr(
|
||||
self._templar.environment,
|
||||
key,
|
||||
default_environment.get(key),
|
||||
)
|
||||
self._templar.available_variables = temp_vars
|
||||
result = self._templar.do_template(
|
||||
template_data,
|
||||
preserve_trailing_newlines=True,
|
||||
escape_backslashes=False,
|
||||
)
|
||||
if omit_value is not None:
|
||||
result_template.extend(RemoveOmit(result, omit_value).output())
|
||||
if trust_as_template:
|
||||
template_data = trust_as_template(template_data)
|
||||
result = self._templar.template(
|
||||
template_data,
|
||||
preserve_trailing_newlines=True,
|
||||
escape_backslashes=False,
|
||||
overrides=overrides,
|
||||
)
|
||||
else:
|
||||
result_template.append(result)
|
||||
result = self._templar.do_template(
|
||||
template_data,
|
||||
preserve_trailing_newlines=True,
|
||||
escape_backslashes=False,
|
||||
)
|
||||
result_template.extend(_from_yaml_to_definition(result))
|
||||
self._templar.available_variables = old_vars
|
||||
resource_definition = self._task.args.get("definition", None)
|
||||
if not resource_definition:
|
||||
@@ -306,7 +302,7 @@ class ActionModule(ActionBase):
|
||||
)
|
||||
|
||||
def get_kubeconfig(self, kubeconfig, remote_transport, new_module_args):
|
||||
if isinstance(kubeconfig, string_types):
|
||||
if isinstance(kubeconfig, str):
|
||||
# find the kubeconfig in the expected search path
|
||||
if not remote_transport:
|
||||
# kubeconfig is local
|
||||
|
||||
@@ -72,6 +72,15 @@ DOCUMENTATION = r"""
|
||||
- name: ansible_kubectl_extra_args
|
||||
env:
|
||||
- name: K8S_AUTH_EXTRA_ARGS
|
||||
kubectl_local_env_vars:
|
||||
description:
|
||||
- Local enviromantal variable to be passed locally to the kubectl command line.
|
||||
- Please be aware that this passes information directly on the command line and it could expose sensitive data.
|
||||
default: {}
|
||||
type: dict
|
||||
version_added: 3.1.0
|
||||
vars:
|
||||
- name: ansible_kubectl_local_env_vars
|
||||
kubectl_kubeconfig:
|
||||
description:
|
||||
- Path to a kubectl config file. Defaults to I(~/.kube/config)
|
||||
@@ -172,6 +181,81 @@ DOCUMENTATION = r"""
|
||||
aliases: [ kubectl_verify_ssl ]
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
|
||||
- name: Run a command in a pod using local kubectl with kubeconfig file ~/.kube/config
|
||||
hosts: localhost
|
||||
gather_facts: no
|
||||
vars:
|
||||
ansible_connection: kubernetes.core.kubectl
|
||||
ansible_kubectl_namespace: my-namespace
|
||||
ansible_kubectl_pod: my-pod
|
||||
ansible_kubectl_container: my-container
|
||||
tasks:
|
||||
# be aware that the command is executed as the user that started the container
|
||||
# and requires python to be installed in the image
|
||||
- name: Run a command in a pod
|
||||
ansible.builtin.command: echo "Hello, World!"
|
||||
|
||||
- name: Run a command in a pod using local kubectl with inventory variables
|
||||
# Example inventory:
|
||||
# k8s:
|
||||
# hosts:
|
||||
# foo.example.com:
|
||||
# ansible_connection: kubernetes.core.kubectl
|
||||
# ansible_kubectl_kubeconfig: /root/.kube/foo.example.com.config
|
||||
# ansible_kubectl_pod: my-foo-pod
|
||||
# ansible_kubectl_container: my-foo-container
|
||||
# ansible_kubectl_namespace: my-foo-namespace
|
||||
# bar.example.com:
|
||||
# ansible_connection: kubernetes.core.kubectl
|
||||
# ansible_kubectl_kubeconfig: /root/.kube/bar.example.com.config
|
||||
# ansible_kubectl_pod: my-bar-pod
|
||||
# ansible_kubectl_container: my-bar-container
|
||||
# ansible_kubectl_namespace: my-bar-namespace
|
||||
hosts: k8s
|
||||
gather_facts: no
|
||||
tasks:
|
||||
# be aware that the command is executed as the user that started the container
|
||||
# and requires python to be installed in the image
|
||||
- name: Run a command in a pod
|
||||
ansible.builtin.command: echo "Hello, World!"
|
||||
|
||||
- name: Run a command in a pod using dynamic inventory
|
||||
hosts: localhost
|
||||
gather_facts: no
|
||||
vars:
|
||||
kubeconfig: /root/.kube/config
|
||||
namespace: my-namespace
|
||||
my_app: my-app
|
||||
tasks:
|
||||
- name: Get My App pod info based on label
|
||||
kubernetes.core.k8s_info:
|
||||
kubeconfig: "{{ kubeconfig }}"
|
||||
namespace: "{{ namespace }}"
|
||||
kind: Pod
|
||||
label_selectors: app.kubernetes.io/name = "{{ my_app }}"
|
||||
register: my_app_pod
|
||||
|
||||
- name: Get My App pod name
|
||||
ansible.builtin.set_fact:
|
||||
my_app_pod_name: "{{ my_app_pod.resources[0].metadata.name }}"
|
||||
|
||||
- name: Add My App pod to inventory
|
||||
ansible.builtin.add_host:
|
||||
name: "{{ my_app_pod_name }}"
|
||||
ansible_connection: kubernetes.core.kubectl
|
||||
ansible_kubectl_kubeconfig: "{{ kubeconfig }}"
|
||||
ansible_kubectl_pod: "{{ my_app_pod_name }}"
|
||||
ansible_kubectl_namespace: "{{ namespace }}"
|
||||
|
||||
- name: Run a command in My App pod
|
||||
# be aware that the command is executed as the user that started the container
|
||||
# and requires python to be installed in the image
|
||||
ansible.builtin.command: echo "Hello, World!"
|
||||
delegate_to: "{{ my_app_pod_name }}"
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import os.path
|
||||
@@ -301,6 +385,19 @@ class Connection(ConnectionBase):
|
||||
|
||||
return local_cmd, censored_local_cmd
|
||||
|
||||
def _local_env(self):
|
||||
"""Return a dict of local environment variables to pass to the kubectl command"""
|
||||
local_env = {}
|
||||
local_local_env_vars_name = "{0}_local_env_vars".format(self.transport)
|
||||
local_env_vars = self.get_option(local_local_env_vars_name)
|
||||
if local_env_vars:
|
||||
if isinstance(local_env_vars, dict):
|
||||
local_env_vars = json.dumps(local_env_vars)
|
||||
local_env = os.environ.copy()
|
||||
local_env.update(json.loads(local_env_vars))
|
||||
return local_env
|
||||
return None
|
||||
|
||||
def _connect(self, port=None):
|
||||
"""Connect to the container. Nothing to do"""
|
||||
super(Connection, self)._connect()
|
||||
@@ -329,6 +426,7 @@ class Connection(ConnectionBase):
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
env=self._local_env(),
|
||||
)
|
||||
|
||||
stdout, stderr = p.communicate(in_data)
|
||||
@@ -378,7 +476,11 @@ class Connection(ConnectionBase):
|
||||
args = [to_bytes(i, errors="surrogate_or_strict") for i in args]
|
||||
try:
|
||||
p = subprocess.Popen(
|
||||
args, stdin=in_file, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
args,
|
||||
stdin=in_file,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
env=self._local_env(),
|
||||
)
|
||||
except OSError:
|
||||
raise AnsibleError(
|
||||
@@ -415,7 +517,11 @@ class Connection(ConnectionBase):
|
||||
) as out_file:
|
||||
try:
|
||||
p = subprocess.Popen(
|
||||
args, stdin=subprocess.PIPE, stdout=out_file, stderr=subprocess.PIPE
|
||||
args,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=out_file,
|
||||
stderr=subprocess.PIPE,
|
||||
env=self._local_env(),
|
||||
)
|
||||
except OSError:
|
||||
raise AnsibleError(
|
||||
|
||||
@@ -36,12 +36,12 @@ options:
|
||||
description:
|
||||
- Provide a URL for accessing the API. Can also be specified via C(K8S_AUTH_HOST) environment variable.
|
||||
type: str
|
||||
version_added: "1.2.0"
|
||||
version_added: 1.2.0
|
||||
api_key:
|
||||
description:
|
||||
- Token used to authenticate with the API. Can also be specified via C(K8S_AUTH_API_KEY) environment variable.
|
||||
type: str
|
||||
version_added: "1.2.0"
|
||||
version_added: 1.2.0
|
||||
validate_certs:
|
||||
description:
|
||||
- Whether or not to verify the API server's SSL certificates. Can also be specified via C(K8S_AUTH_VERIFY_SSL)
|
||||
@@ -49,12 +49,12 @@ options:
|
||||
type: bool
|
||||
aliases: [ verify_ssl ]
|
||||
default: True
|
||||
version_added: "1.2.0"
|
||||
version_added: 1.2.0
|
||||
ca_cert:
|
||||
description:
|
||||
- Path to a CA certificate used to authenticate with the API. The full certificate chain must be provided to
|
||||
avoid certificate validation errors. Can also be specified via C(K8S_AUTH_SSL_CA_CERT) environment variable.
|
||||
type: path
|
||||
aliases: [ ssl_ca_cert ]
|
||||
version_added: "1.2.0"
|
||||
version_added: 1.2.0
|
||||
"""
|
||||
|
||||
@@ -15,7 +15,7 @@ class ModuleDocFragment(object):
|
||||
options:
|
||||
delete_options:
|
||||
type: dict
|
||||
version_added: '1.2.0'
|
||||
version_added: 1.2.0
|
||||
description:
|
||||
- Configure behavior when deleting an object.
|
||||
- Only used when I(state=absent).
|
||||
|
||||
@@ -1,476 +0,0 @@
|
||||
# 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: 4.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 4.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
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.common import (
|
||||
HAS_K8S_MODULE_HELPER,
|
||||
k8s_import_exception,
|
||||
)
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
|
||||
get_api_client,
|
||||
)
|
||||
|
||||
try:
|
||||
from kubernetes.dynamic.exceptions import DynamicApiError
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
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 4.0.0",
|
||||
version="4.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
|
||||
)
|
||||
@@ -8,7 +8,7 @@ DOCUMENTATION = """
|
||||
|
||||
short_description: Build a set of kubernetes resources using a 'kustomization.yaml' file.
|
||||
|
||||
version_added: "2.2.0"
|
||||
version_added: 2.2.0
|
||||
|
||||
author:
|
||||
- Aubin Bikouo (@abikouo)
|
||||
@@ -30,6 +30,17 @@ DOCUMENTATION = """
|
||||
opt_dirs:
|
||||
description:
|
||||
- An optional list of directories to search for the executable in addition to PATH.
|
||||
enable_helm:
|
||||
description:
|
||||
- Enable the helm chart inflation generator
|
||||
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:
|
||||
- "python >= 3.6"
|
||||
@@ -37,16 +48,28 @@ DOCUMENTATION = """
|
||||
|
||||
EXAMPLES = """
|
||||
- name: Run lookup using kustomize
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
resources: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kustomize') }}"
|
||||
|
||||
- name: Run lookup using kubectl kustomize
|
||||
set_fact:
|
||||
ansible.builtin.set_fact:
|
||||
resources: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kubectl') }}"
|
||||
|
||||
- name: Create kubernetes resources for lookup output
|
||||
k8s:
|
||||
kubernetes.core.k8s:
|
||||
definition: "{{ lookup('kubernetes.core.kustomize', dir='/path/to/kustomization') }}"
|
||||
|
||||
- name: Create kubernetes resources for lookup output with `--enable-helm` set
|
||||
kubernetes.core.k8s:
|
||||
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 = """
|
||||
@@ -64,6 +87,7 @@ RETURN = """
|
||||
key1: val1
|
||||
"""
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from ansible.errors import AnsibleLookupError
|
||||
@@ -84,14 +108,25 @@ def get_binary_from_path(name, opt_dirs=None):
|
||||
return None
|
||||
|
||||
|
||||
def run_command(command):
|
||||
cmd = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
return cmd.communicate()
|
||||
def run_command(command, environ=None):
|
||||
cmd = subprocess.Popen(
|
||||
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=environ
|
||||
)
|
||||
stdout, stderr = cmd.communicate()
|
||||
return cmd.returncode, stdout, stderr
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
def run(
|
||||
self, terms, variables=None, dir=".", binary_path=None, opt_dirs=None, **kwargs
|
||||
self,
|
||||
terms,
|
||||
variables=None,
|
||||
dir=".",
|
||||
binary_path=None,
|
||||
opt_dirs=None,
|
||||
enable_helm=False,
|
||||
environment=None,
|
||||
**kwargs
|
||||
):
|
||||
executable_path = binary_path
|
||||
if executable_path is None:
|
||||
@@ -122,9 +157,35 @@ class LookupModule(LookupBase):
|
||||
)
|
||||
)
|
||||
|
||||
(out, err) = run_command(command)
|
||||
if err:
|
||||
raise AnsibleLookupError(
|
||||
"kustomize command failed with: {0}".format(err.decode("utf-8"))
|
||||
)
|
||||
if enable_helm:
|
||||
command += ["--enable-helm"]
|
||||
|
||||
environ = None
|
||||
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 err:
|
||||
raise AnsibleLookupError(
|
||||
"kustomize command failed. exit code: {0}, error: {1}".format(
|
||||
ret, err.decode("utf-8")
|
||||
)
|
||||
)
|
||||
else:
|
||||
raise AnsibleLookupError(
|
||||
"kustomize command failed with unknown error. exit code: {0}".format(
|
||||
ret
|
||||
)
|
||||
)
|
||||
return [out.decode("utf-8")]
|
||||
|
||||
@@ -149,6 +149,7 @@ def k8s_apply(resource, definition, **kwargs):
|
||||
force_conflicts=kwargs.get("force_conflicts"),
|
||||
field_manager=kwargs.get("field_manager"),
|
||||
dry_run=kwargs.get("dry_run"),
|
||||
serialize=kwargs.get("serialize"),
|
||||
)
|
||||
if not existing:
|
||||
return resource.create(
|
||||
@@ -158,6 +159,7 @@ def k8s_apply(resource, definition, **kwargs):
|
||||
return resource.get(
|
||||
name=definition["metadata"]["name"],
|
||||
namespace=definition["metadata"].get("namespace"),
|
||||
**kwargs
|
||||
)
|
||||
return resource.patch(
|
||||
body=desired,
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from ansible.module_utils.six import string_types
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
def list_dict_str(value):
|
||||
if isinstance(value, (list, dict, string_types)):
|
||||
if isinstance(value, (list, dict, str)):
|
||||
return value
|
||||
raise TypeError
|
||||
|
||||
@@ -18,7 +16,7 @@ AUTH_PROXY_HEADERS_SPEC = dict(
|
||||
)
|
||||
|
||||
AUTH_ARG_SPEC = {
|
||||
"kubeconfig": {"type": "raw"},
|
||||
"kubeconfig": {"type": "raw", "no_log": True},
|
||||
"context": {},
|
||||
"host": {},
|
||||
"api_key": {"no_log": True},
|
||||
|
||||
@@ -113,7 +113,7 @@ class Discoverer(kubernetes.dynamic.discovery.Discoverer):
|
||||
filter(lambda resource: "/" in resource["name"], resources_response)
|
||||
)
|
||||
for subresource in subresources_raw:
|
||||
resource, name = subresource["name"].split("/")
|
||||
resource, name = subresource["name"].split("/", 1)
|
||||
subresources[resource][name] = subresource
|
||||
|
||||
for resource in resources_raw:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -96,7 +96,7 @@ class K8SCopy(metaclass=ABCMeta):
|
||||
return error, stdout, stderr
|
||||
except Exception as e:
|
||||
self.module.fail_json(
|
||||
msg="Error while running/parsing from pod {1}/{2} command='{0}' : {3}".format(
|
||||
msg="Error while running/parsing from pod {0}/{1} command='{2}' : {3}".format(
|
||||
self.namespace, self.name, cmd, to_native(e)
|
||||
)
|
||||
)
|
||||
@@ -435,11 +435,21 @@ def check_pod(svc):
|
||||
|
||||
try:
|
||||
result = svc.client.get(resource, name=name, namespace=namespace)
|
||||
containers = [
|
||||
c["name"] for c in result.to_dict()["status"]["containerStatuses"]
|
||||
]
|
||||
if container and container not in containers:
|
||||
containers = dict(
|
||||
{
|
||||
c["name"]: c
|
||||
for cl in ["initContainerStatuses", "containerStatuses"]
|
||||
for c in result.to_dict()["status"].get(cl, [])
|
||||
}
|
||||
)
|
||||
if container and container not in containers.keys():
|
||||
module.fail_json(msg="Pod has no container {0}".format(container))
|
||||
return containers
|
||||
if (
|
||||
container
|
||||
and container in containers
|
||||
and not bool(containers[container].get("started", False))
|
||||
):
|
||||
module.fail_json(msg="Pod container {0} is not started".format(container))
|
||||
return containers.keys()
|
||||
except Exception as exc:
|
||||
_fail(exc)
|
||||
|
||||
@@ -15,7 +15,6 @@ import tempfile
|
||||
import traceback
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils.six import string_types
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.version import (
|
||||
LooseVersion,
|
||||
)
|
||||
@@ -77,7 +76,6 @@ def write_temp_kubeconfig(server, validate_certs=True, ca_cert=None, kubeconfig=
|
||||
|
||||
|
||||
class AnsibleHelmModule(object):
|
||||
|
||||
"""
|
||||
An Ansible module class for Kubernetes.core helm modules
|
||||
"""
|
||||
@@ -114,8 +112,8 @@ class AnsibleHelmModule(object):
|
||||
kubeconfig_content = None
|
||||
kubeconfig = self.params.get("kubeconfig")
|
||||
if kubeconfig:
|
||||
if isinstance(kubeconfig, string_types):
|
||||
with open(kubeconfig) as fd:
|
||||
if isinstance(kubeconfig, str):
|
||||
with open(os.path.expanduser(kubeconfig)) as fd:
|
||||
kubeconfig_content = yaml.safe_load(fd)
|
||||
elif isinstance(kubeconfig, dict):
|
||||
kubeconfig_content = kubeconfig
|
||||
@@ -160,11 +158,13 @@ class AnsibleHelmModule(object):
|
||||
self.helm_env = self._prepare_helm_environment()
|
||||
return self.helm_env
|
||||
|
||||
def run_helm_command(self, command, fails_on_error=True):
|
||||
def run_helm_command(self, command, fails_on_error=True, data=None):
|
||||
if not HAS_YAML:
|
||||
self.fail_json(msg=missing_required_lib("PyYAML"), exception=YAML_IMP_ERR)
|
||||
|
||||
rc, out, err = self.run_command(command, environ_update=self.env_update)
|
||||
rc, out, err = self.run_command(
|
||||
command, environ_update=self.env_update, data=data
|
||||
)
|
||||
if fails_on_error and rc != 0:
|
||||
self.fail_json(
|
||||
msg="Failure when executing Helm command. Exited {0}.\nstdout: {1}\nstderr: {2}".format(
|
||||
@@ -184,10 +184,10 @@ class AnsibleHelmModule(object):
|
||||
def get_helm_version(self):
|
||||
command = self.get_helm_binary() + " version"
|
||||
rc, out, err = self.run_command(command)
|
||||
m = re.match(r'version.BuildInfo{Version:"v([0-9\.]*)",', out)
|
||||
m = re.match(r'version.BuildInfo{Version:"v(.*?)",', out)
|
||||
if m:
|
||||
return m.group(1)
|
||||
m = re.match(r'Client: &version.Version{SemVer:"v([0-9\.]*)", ', out)
|
||||
m = re.match(r'Client: &version.Version{SemVer:"v(.*?)", ', out)
|
||||
if m:
|
||||
return m.group(1)
|
||||
return None
|
||||
|
||||
@@ -16,6 +16,7 @@ HELM_AUTH_ARG_SPEC = dict(
|
||||
type="raw",
|
||||
aliases=["kubeconfig_path"],
|
||||
fallback=(env_fallback, ["K8S_AUTH_KUBECONFIG"]),
|
||||
no_log=True,
|
||||
),
|
||||
host=dict(type="str", fallback=(env_fallback, ["K8S_AUTH_HOST"])),
|
||||
ca_cert=dict(
|
||||
|
||||
@@ -5,7 +5,6 @@ import hashlib
|
||||
import os
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
from ansible.module_utils.six import iteritems, string_types
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
|
||||
AUTH_ARG_MAP,
|
||||
AUTH_ARG_SPEC,
|
||||
@@ -115,7 +114,7 @@ def _load_config(auth: Dict) -> None:
|
||||
"persist_config": auth.get("persist_config"),
|
||||
}
|
||||
if kubeconfig:
|
||||
if isinstance(kubeconfig, string_types):
|
||||
if isinstance(kubeconfig, str):
|
||||
kubernetes.config.load_kube_config(config_file=kubeconfig, **optional_arg)
|
||||
elif isinstance(kubeconfig, dict):
|
||||
kubernetes.config.load_kube_config_from_dict(
|
||||
@@ -163,7 +162,7 @@ def _create_configuration(auth: Dict):
|
||||
except AttributeError:
|
||||
configuration = kubernetes.client.Configuration()
|
||||
|
||||
for key, value in iteritems(auth):
|
||||
for key, value in auth.items():
|
||||
if key in AUTH_ARG_MAP.keys() and value is not None:
|
||||
if key == "api_key":
|
||||
setattr(
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
import os
|
||||
from typing import Dict, Iterable, List, Optional, Union, cast
|
||||
|
||||
from ansible.module_utils.six import string_types
|
||||
from ansible.module_utils.urls import Request
|
||||
|
||||
try:
|
||||
@@ -78,11 +77,11 @@ def create_definitions(params: Dict) -> List[ResourceDefinition]:
|
||||
def from_yaml(definition: Union[str, List, Dict]) -> Iterable[Dict]:
|
||||
"""Load resource definitions from a yaml definition."""
|
||||
definitions: List[Dict] = []
|
||||
if isinstance(definition, string_types):
|
||||
if isinstance(definition, str):
|
||||
definitions += yaml.safe_load_all(definition)
|
||||
elif isinstance(definition, list):
|
||||
for item in definition:
|
||||
if isinstance(item, string_types):
|
||||
if isinstance(item, str):
|
||||
definitions += yaml.safe_load_all(item)
|
||||
else:
|
||||
definitions.append(item)
|
||||
|
||||
@@ -139,6 +139,7 @@ def perform_action(svc, definition: Dict, params: Dict) -> Dict:
|
||||
|
||||
result = {"changed": False, "result": {}}
|
||||
instance = {}
|
||||
warnings = []
|
||||
|
||||
resource = svc.find_resource(kind, api_version, fail=True)
|
||||
definition["kind"] = resource.kind
|
||||
@@ -172,7 +173,7 @@ def perform_action(svc, definition: Dict, params: Dict) -> Dict:
|
||||
return result
|
||||
|
||||
if params.get("apply"):
|
||||
instance = svc.apply(resource, definition, existing)
|
||||
instance, warnings = svc.apply(resource, definition, existing)
|
||||
result["method"] = "apply"
|
||||
elif not existing:
|
||||
if state == "patched":
|
||||
@@ -183,16 +184,19 @@ def perform_action(svc, definition: Dict, params: Dict) -> Dict:
|
||||
)
|
||||
)
|
||||
return result
|
||||
instance = svc.create(resource, definition)
|
||||
instance, warnings = svc.create(resource, definition)
|
||||
result["method"] = "create"
|
||||
result["changed"] = True
|
||||
elif params.get("force", False):
|
||||
instance = svc.replace(resource, definition, existing)
|
||||
instance, warnings = svc.replace(resource, definition, existing)
|
||||
result["method"] = "replace"
|
||||
else:
|
||||
instance = svc.update(resource, definition, existing)
|
||||
instance, warnings = svc.update(resource, definition, existing)
|
||||
result["method"] = "update"
|
||||
|
||||
if warnings:
|
||||
result["warnings"] = warnings
|
||||
|
||||
# If needed, wait and/or create diff
|
||||
success = True
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
import copy
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
from json import loads
|
||||
from re import compile
|
||||
from typing import Any, Dict, List, Optional, Tuple, Union
|
||||
|
||||
from ansible.module_utils.common.dict_transformations import dict_merge
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.hashes import (
|
||||
@@ -142,18 +144,12 @@ class K8sService:
|
||||
name: str,
|
||||
namespace: str,
|
||||
merge_type: str = None,
|
||||
) -> Dict:
|
||||
if merge_type == "json":
|
||||
self.module.deprecate(
|
||||
msg="json as a merge_type value is deprecated. Please use the k8s_json_patch module instead.",
|
||||
version="4.0.0",
|
||||
collection_name="kubernetes.core",
|
||||
)
|
||||
) -> Tuple[Dict, List[str]]:
|
||||
try:
|
||||
params = dict(name=name, namespace=namespace)
|
||||
params = dict(name=name, namespace=namespace, serialize=False)
|
||||
if merge_type:
|
||||
params["content_type"] = "application/{0}-patch+json".format(merge_type)
|
||||
return self.client.patch(resource, definition, **params).to_dict()
|
||||
return decode_response(self.client.patch(resource, definition, **params))
|
||||
except Exception as e:
|
||||
reason = e.body if hasattr(e, "body") else e
|
||||
msg = "Failed to patch object: {0}".format(reason)
|
||||
@@ -330,123 +326,124 @@ class K8sService:
|
||||
result["resources"].append(hide_fields(res, hidden_fields))
|
||||
return result
|
||||
|
||||
def create(self, resource: Resource, definition: Dict) -> Dict:
|
||||
def create(self, resource: Resource, definition: Dict) -> Tuple[Dict, List[str]]:
|
||||
namespace = definition["metadata"].get("namespace")
|
||||
name = definition["metadata"].get("name")
|
||||
|
||||
if self._client_side_dry_run:
|
||||
k8s_obj = _encode_stringdata(definition)
|
||||
else:
|
||||
try:
|
||||
k8s_obj = self.client.create(
|
||||
resource, definition, namespace=namespace
|
||||
).to_dict()
|
||||
except ConflictError:
|
||||
# Some resources, like ProjectRequests, can't be created multiple times,
|
||||
# because the resources that they create don't match their kind
|
||||
# In this case we'll mark it as unchanged and warn the user
|
||||
self.module.warn(
|
||||
"{0} was not found, but creating it returned a 409 Conflict error. This can happen \
|
||||
if the resource you are creating does not directly create a resource of the same kind.".format(
|
||||
name
|
||||
)
|
||||
return _encode_stringdata(definition), []
|
||||
|
||||
try:
|
||||
return decode_response(
|
||||
self.client.create(
|
||||
resource, definition, namespace=namespace, serialize=False
|
||||
)
|
||||
return dict()
|
||||
except Exception as e:
|
||||
reason = e.body if hasattr(e, "body") else e
|
||||
msg = "Failed to create object: {0}".format(reason)
|
||||
raise CoreException(msg) from e
|
||||
return k8s_obj
|
||||
)
|
||||
except ConflictError:
|
||||
# Some resources, like ProjectRequests, can't be created multiple times,
|
||||
# because the resources that they create don't match their kind
|
||||
# In this case we'll mark it as unchanged and warn the user
|
||||
self.module.warn(
|
||||
"{0} was not found, but creating it returned a 409 Conflict error. This can happen \
|
||||
if the resource you are creating does not directly create a resource of the same kind.".format(
|
||||
name
|
||||
)
|
||||
)
|
||||
return dict(), []
|
||||
except Exception as e:
|
||||
reason = e.body if hasattr(e, "body") else e
|
||||
msg = "Failed to create object: {0}".format(reason)
|
||||
raise CoreException(msg) from e
|
||||
|
||||
def apply(
|
||||
self,
|
||||
resource: Resource,
|
||||
definition: Dict,
|
||||
existing: Optional[ResourceInstance] = None,
|
||||
) -> Dict:
|
||||
) -> Tuple[Dict, List[str]]:
|
||||
namespace = definition["metadata"].get("namespace")
|
||||
|
||||
server_side_apply = self.module.params.get("server_side_apply")
|
||||
if server_side_apply:
|
||||
requires("kubernetes", "19.15.0", reason="to use server side apply")
|
||||
|
||||
if self._client_side_dry_run:
|
||||
ignored, patch = apply_object(resource, _encode_stringdata(definition))
|
||||
if existing:
|
||||
k8s_obj = dict_merge(existing.to_dict(), patch)
|
||||
return dict_merge(existing.to_dict(), patch), []
|
||||
else:
|
||||
k8s_obj = patch
|
||||
else:
|
||||
try:
|
||||
params = {}
|
||||
if server_side_apply:
|
||||
params["server_side"] = True
|
||||
params.update(server_side_apply)
|
||||
k8s_obj = self.client.apply(
|
||||
resource, definition, namespace=namespace, **params
|
||||
).to_dict()
|
||||
except Exception as e:
|
||||
reason = e.body if hasattr(e, "body") else e
|
||||
msg = "Failed to apply object: {0}".format(reason)
|
||||
raise CoreException(msg) from e
|
||||
return k8s_obj
|
||||
return patch, []
|
||||
|
||||
try:
|
||||
params = {}
|
||||
if server_side_apply:
|
||||
params["server_side"] = True
|
||||
params.update(server_side_apply)
|
||||
return decode_response(
|
||||
self.client.apply(
|
||||
resource, definition, namespace=namespace, serialize=False, **params
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
reason = e.body if hasattr(e, "body") else e
|
||||
msg = "Failed to apply object: {0}".format(reason)
|
||||
raise CoreException(msg) from e
|
||||
|
||||
def replace(
|
||||
self,
|
||||
resource: Resource,
|
||||
definition: Dict,
|
||||
existing: ResourceInstance,
|
||||
) -> Dict:
|
||||
) -> Tuple[Dict, List[str]]:
|
||||
append_hash = self.module.params.get("append_hash", False)
|
||||
name = definition["metadata"].get("name")
|
||||
namespace = definition["metadata"].get("namespace")
|
||||
|
||||
if self._client_side_dry_run:
|
||||
k8s_obj = _encode_stringdata(definition)
|
||||
else:
|
||||
try:
|
||||
k8s_obj = self.client.replace(
|
||||
return _encode_stringdata(definition), []
|
||||
|
||||
try:
|
||||
return decode_response(
|
||||
self.client.replace(
|
||||
resource,
|
||||
definition,
|
||||
name=name,
|
||||
namespace=namespace,
|
||||
append_hash=append_hash,
|
||||
).to_dict()
|
||||
except Exception as e:
|
||||
reason = e.body if hasattr(e, "body") else e
|
||||
msg = "Failed to replace object: {0}".format(reason)
|
||||
raise CoreException(msg) from e
|
||||
return k8s_obj
|
||||
serialize=False,
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
reason = e.body if hasattr(e, "body") else e
|
||||
msg = "Failed to replace object: {0}".format(reason)
|
||||
raise CoreException(msg) from e
|
||||
|
||||
def update(
|
||||
self, resource: Resource, definition: Dict, existing: ResourceInstance
|
||||
) -> Dict:
|
||||
) -> Tuple[Dict, List[str]]:
|
||||
name = definition["metadata"].get("name")
|
||||
namespace = definition["metadata"].get("namespace")
|
||||
|
||||
if self._client_side_dry_run:
|
||||
k8s_obj = dict_merge(existing.to_dict(), _encode_stringdata(definition))
|
||||
else:
|
||||
exception = None
|
||||
for merge_type in self.module.params.get("merge_type") or [
|
||||
"strategic-merge",
|
||||
"merge",
|
||||
]:
|
||||
try:
|
||||
k8s_obj = self.patch_resource(
|
||||
resource,
|
||||
definition,
|
||||
name,
|
||||
namespace,
|
||||
merge_type=merge_type,
|
||||
)
|
||||
exception = None
|
||||
except CoreException as e:
|
||||
exception = e
|
||||
continue
|
||||
break
|
||||
if exception:
|
||||
raise exception
|
||||
return k8s_obj
|
||||
return dict_merge(existing.to_dict(), _encode_stringdata(definition)), []
|
||||
|
||||
exception = None
|
||||
for merge_type in self.module.params.get("merge_type") or [
|
||||
"strategic-merge",
|
||||
"merge",
|
||||
]:
|
||||
try:
|
||||
return self.patch_resource(
|
||||
resource,
|
||||
definition,
|
||||
name,
|
||||
namespace,
|
||||
merge_type=merge_type,
|
||||
)
|
||||
except CoreException as e:
|
||||
exception = e
|
||||
continue
|
||||
raise exception
|
||||
|
||||
def delete(
|
||||
self,
|
||||
@@ -476,7 +473,7 @@ class K8sService:
|
||||
if label_selectors:
|
||||
params["label_selector"] = ",".join(label_selectors)
|
||||
|
||||
if delete_options:
|
||||
if delete_options and not self.module.check_mode:
|
||||
body = {
|
||||
"apiVersion": "v1",
|
||||
"kind": "DeleteOptions",
|
||||
@@ -501,45 +498,214 @@ def diff_objects(
|
||||
if not diff:
|
||||
return True, result
|
||||
|
||||
result["before"] = diff[0]
|
||||
result["after"] = diff[1]
|
||||
result["before"] = hide_fields(diff[0], hidden_fields)
|
||||
result["after"] = hide_fields(diff[1], hidden_fields)
|
||||
|
||||
if list(result["after"].keys()) != ["metadata"] or list(
|
||||
if list(result["after"].keys()) == ["metadata"] and list(
|
||||
result["before"].keys()
|
||||
) != ["metadata"]:
|
||||
return False, result
|
||||
) == ["metadata"]:
|
||||
# If only metadata.generation and metadata.resourceVersion changed, ignore it
|
||||
ignored_keys = set(["generation", "resourceVersion"])
|
||||
|
||||
# If only metadata.generation and metadata.resourceVersion changed, ignore it
|
||||
ignored_keys = set(["generation", "resourceVersion"])
|
||||
if set(result["after"]["metadata"].keys()).issubset(ignored_keys) and set(
|
||||
result["before"]["metadata"].keys()
|
||||
).issubset(ignored_keys):
|
||||
return True, result
|
||||
|
||||
if not set(result["after"]["metadata"].keys()).issubset(ignored_keys):
|
||||
return False, result
|
||||
if not set(result["before"]["metadata"].keys()).issubset(ignored_keys):
|
||||
return False, result
|
||||
|
||||
result["before"] = hide_fields(result["before"], hidden_fields)
|
||||
result["after"] = hide_fields(result["after"], hidden_fields)
|
||||
|
||||
return True, result
|
||||
return False, result
|
||||
|
||||
|
||||
def hide_fields(definition: dict, hidden_fields: Optional[list]) -> dict:
|
||||
if not hidden_fields:
|
||||
return definition
|
||||
result = copy.deepcopy(definition)
|
||||
for hidden_field in hidden_fields:
|
||||
result = hide_field(result, hidden_field)
|
||||
def hide_field_tree(hidden_field: str) -> List[str]:
|
||||
result = []
|
||||
key, rest = hide_field_split2(hidden_field)
|
||||
result.append(key)
|
||||
while rest:
|
||||
key, rest = hide_field_split2(rest)
|
||||
result.append(key)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
# hide_field is not hugely sophisticated and designed to cope
|
||||
# with e.g. status or metadata.managedFields rather than e.g.
|
||||
# spec.template.spec.containers[0].env[3].value
|
||||
def hide_field(definition: dict, hidden_field: str) -> dict:
|
||||
split = hidden_field.split(".", 1)
|
||||
if split[0] in definition:
|
||||
if len(split) == 2:
|
||||
definition[split[0]] = hide_field(definition[split[0]], split[1])
|
||||
else:
|
||||
del definition[split[0]]
|
||||
def build_hidden_field_tree(hidden_fields: List[str]) -> Dict[str, Any]:
|
||||
"""Group hidden field targeting the same json key
|
||||
Example:
|
||||
Input: ['env[3]', 'env[0]']
|
||||
Output: {'env': [0, 3]}
|
||||
"""
|
||||
output = {}
|
||||
for hidden_field in hidden_fields:
|
||||
current = output
|
||||
tree = hide_field_tree(hidden_field)
|
||||
for idx, key in enumerate(tree):
|
||||
if current.get(key, "") is None:
|
||||
break
|
||||
if idx == (len(tree) - 1):
|
||||
current[key] = None
|
||||
elif key not in current:
|
||||
current[key] = {}
|
||||
current = current[key]
|
||||
return output
|
||||
|
||||
|
||||
# hide_field should be able to cope with simple or more complicated
|
||||
# field definitions
|
||||
# e.g. status or metadata.managedFields or
|
||||
# spec.template.spec.containers[0].env[3].value or
|
||||
# metadata.annotations[kubectl.kubernetes.io/last-applied-configuration]
|
||||
def hide_field(
|
||||
definition: Union[Dict[str, Any], List[Any]], hidden_field: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
def dict_contains_key(obj: Dict[str, Any], key: str) -> bool:
|
||||
return key in obj
|
||||
|
||||
def list_contains_key(obj: List[Any], key: str) -> bool:
|
||||
return int(key) < len(obj)
|
||||
|
||||
hidden_keys = list(hidden_field.keys())
|
||||
field_contains_key = dict_contains_key
|
||||
field_get_key = str
|
||||
if isinstance(definition, list):
|
||||
# Sort with reverse=true so that when we delete an item from the list, the order is not changed
|
||||
hidden_keys = sorted(
|
||||
[k for k in hidden_field.keys() if k.isdecimal()], reverse=True
|
||||
)
|
||||
field_contains_key = list_contains_key
|
||||
field_get_key = int
|
||||
|
||||
for key in hidden_keys:
|
||||
if field_contains_key(definition, key):
|
||||
value = hidden_field.get(key)
|
||||
convert_key = field_get_key(key)
|
||||
if value is None:
|
||||
del definition[convert_key]
|
||||
else:
|
||||
definition[convert_key] = hide_field(definition[convert_key], value)
|
||||
if (
|
||||
definition[convert_key] == dict()
|
||||
or definition[convert_key] == list()
|
||||
):
|
||||
del definition[convert_key]
|
||||
|
||||
return definition
|
||||
|
||||
|
||||
def hide_fields(
|
||||
definition: Dict[str, Any], hidden_fields: Optional[List[str]]
|
||||
) -> Dict[str, Any]:
|
||||
if not hidden_fields:
|
||||
return definition
|
||||
result = copy.deepcopy(definition)
|
||||
hidden_field_tree = build_hidden_field_tree(hidden_fields)
|
||||
return hide_field(result, hidden_field_tree)
|
||||
|
||||
|
||||
def decode_response(resp) -> Tuple[Dict, List[str]]:
|
||||
"""
|
||||
This function decodes unserialized responses from the Kubernetes python
|
||||
client and decodes the RFC2616 14.46 warnings found in the response
|
||||
headers.
|
||||
"""
|
||||
obj = ResourceInstance(None, loads(resp.data.decode("utf8"))).to_dict()
|
||||
warnings = []
|
||||
if (
|
||||
resp.headers is not None
|
||||
and "warning" in resp.headers
|
||||
and resp.headers["warning"] is not None
|
||||
):
|
||||
warnings = resp.headers["warning"].split(", ")
|
||||
return obj, decode_warnings(warnings)
|
||||
|
||||
|
||||
def decode_warnings(warnings: str) -> List[str]:
|
||||
"""
|
||||
This function decodes RFC2616 14.46 warnings in a simplified way, where
|
||||
only the warn-texts are returned in a list.
|
||||
"""
|
||||
p = compile('\\d{3} .+ (".+")')
|
||||
|
||||
decoded = []
|
||||
for warning in warnings:
|
||||
m = p.match(warning)
|
||||
if m:
|
||||
try:
|
||||
parsed, unused = parse_quoted_string(m.group(1))
|
||||
decoded.append(parsed)
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
return decoded
|
||||
|
||||
|
||||
def parse_quoted_string(quoted_string: str) -> Tuple[str, str]:
|
||||
"""
|
||||
This function was adapted from:
|
||||
https://github.com/kubernetes/apimachinery/blob/bb8822152cabfb4f34dbc26270f874ce53db50de/pkg/util/net/http.go#L609
|
||||
"""
|
||||
if len(quoted_string) == 0:
|
||||
raise ValueError("invalid quoted string: 0-length")
|
||||
|
||||
if quoted_string[0] != '"':
|
||||
raise ValueError("invalid quoted string: missing initial quote")
|
||||
|
||||
quoted_string = quoted_string[1:]
|
||||
remainder = ""
|
||||
escaping = False
|
||||
closed_quote = False
|
||||
result = []
|
||||
|
||||
for i, b in enumerate(quoted_string):
|
||||
if b == '"':
|
||||
if escaping:
|
||||
result.append(b)
|
||||
escaping = False
|
||||
else:
|
||||
closed_quote = True
|
||||
remainder_start = i + 1
|
||||
remainder = quoted_string[remainder_start:].strip()
|
||||
break
|
||||
elif b == "\\":
|
||||
if escaping:
|
||||
result.append(b)
|
||||
escaping = False
|
||||
else:
|
||||
escaping = True
|
||||
else:
|
||||
result.append(b)
|
||||
escaping = False
|
||||
|
||||
if not closed_quote:
|
||||
raise ValueError("invalid quoted string: missing closing quote")
|
||||
|
||||
return "".join(result), remainder
|
||||
|
||||
|
||||
# hide_field_split2 returns the first key in hidden_field and the rest of the hidden_field
|
||||
# We expect the first key to either be in brackets, to be terminated by the start of a left
|
||||
# bracket, or to be terminated by a dot.
|
||||
|
||||
# examples would be:
|
||||
# field.another.next -> (field, another.next)
|
||||
# field[key].value -> (field, [key].value)
|
||||
# [key].value -> (key, value)
|
||||
# [one][two] -> (one, [two])
|
||||
|
||||
|
||||
def hide_field_split2(hidden_field: str) -> Tuple[str, str]:
|
||||
lbracket = hidden_field.find("[")
|
||||
rbracket = hidden_field.find("]")
|
||||
dot = hidden_field.find(".")
|
||||
|
||||
if lbracket == 0:
|
||||
# skip past right bracket and any following dot
|
||||
rest = hidden_field[rbracket + 1 :] # noqa: E203
|
||||
if rest and rest[0] == ".":
|
||||
rest = rest[1:]
|
||||
return (hidden_field[lbracket + 1 : rbracket], rest) # noqa: E203
|
||||
|
||||
if lbracket != -1 and (dot == -1 or lbracket < dot):
|
||||
return (hidden_field[:lbracket], hidden_field[lbracket:])
|
||||
|
||||
split = hidden_field.split(".", 1)
|
||||
if len(split) == 1:
|
||||
return split[0], ""
|
||||
return split
|
||||
|
||||
@@ -51,7 +51,7 @@ def daemonset_ready(daemonset: ResourceInstance) -> bool:
|
||||
return bool(
|
||||
daemonset.status
|
||||
and daemonset.status.desiredNumberScheduled is not None
|
||||
and daemonset.status.updatedNumberScheduled
|
||||
and (daemonset.status.updatedNumberScheduled or 0)
|
||||
== daemonset.status.desiredNumberScheduled
|
||||
and daemonset.status.numberReady == daemonset.status.desiredNumberScheduled
|
||||
and daemonset.status.observedGeneration == daemonset.metadata.generation
|
||||
@@ -117,11 +117,34 @@ def exists(resource: Optional[ResourceInstance]) -> bool:
|
||||
return bool(resource) and not empty_list(resource)
|
||||
|
||||
|
||||
def cluster_operator_ready(resource: ResourceInstance) -> bool:
|
||||
"""
|
||||
Predicate to check if a single ClusterOperator is healthy.
|
||||
Returns True if:
|
||||
- "Available" is True
|
||||
- "Degraded" is False
|
||||
- "Progressing" is False
|
||||
"""
|
||||
if not resource:
|
||||
return False
|
||||
|
||||
# Extract conditions from the resource's status
|
||||
conditions = resource.get("status", {}).get("conditions", [])
|
||||
|
||||
status = {x.get("type", ""): x.get("status") for x in conditions}
|
||||
return (
|
||||
(status.get("Degraded") == "False")
|
||||
and (status.get("Progressing") == "False")
|
||||
and (status.get("Available") == "True")
|
||||
)
|
||||
|
||||
|
||||
RESOURCE_PREDICATES = {
|
||||
"DaemonSet": daemonset_ready,
|
||||
"Deployment": deployment_ready,
|
||||
"Pod": pod_ready,
|
||||
"StatefulSet": statefulset_ready,
|
||||
"ClusterOperator": cluster_operator_ready,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ module: helm
|
||||
|
||||
short_description: Manages Kubernetes packages with the Helm package manager
|
||||
|
||||
version_added: "0.11.0"
|
||||
version_added: 0.11.0
|
||||
|
||||
author:
|
||||
- Lucas Boisserie (@LucasBoisserie)
|
||||
@@ -61,7 +61,7 @@ options:
|
||||
default: false
|
||||
type: bool
|
||||
aliases: [ dep_up ]
|
||||
version_added: "2.4.0"
|
||||
version_added: 2.4.0
|
||||
release_name:
|
||||
description:
|
||||
- Release name to manage.
|
||||
@@ -99,7 +99,7 @@ options:
|
||||
default: []
|
||||
type: list
|
||||
elements: str
|
||||
version_added: '1.1.0'
|
||||
version_added: 1.1.0
|
||||
update_repo_cache:
|
||||
description:
|
||||
- Run C(helm repo update) before the operation. Can be run as part of the package installation or as a separate step (see Examples).
|
||||
@@ -129,7 +129,7 @@ options:
|
||||
- string
|
||||
- json
|
||||
- file
|
||||
version_added: '2.4.0'
|
||||
version_added: 2.4.0
|
||||
reuse_values:
|
||||
description:
|
||||
- When upgrading package, specifies wether to reuse the last release's values and merge in any overrides from parameters I(release_values),
|
||||
@@ -137,14 +137,24 @@ options:
|
||||
- If I(reset_values) is set to C(True), this is ignored.
|
||||
type: bool
|
||||
required: false
|
||||
version_added: '2.5.0'
|
||||
version_added: 3.0.0
|
||||
reset_values:
|
||||
description:
|
||||
- When upgrading package, reset the values to the ones built into the chart.
|
||||
type: bool
|
||||
required: false
|
||||
default: True
|
||||
version_added: '2.5.0'
|
||||
version_added: 3.0.0
|
||||
reset_then_reuse_values:
|
||||
description:
|
||||
- When upgrading package, reset the values to the ones built into the chart, apply the last release's values and merge in any overrides from
|
||||
parameters O(release_values), O(values_files) or O(set_values).
|
||||
- If O(reset_values) or O(reuse_values) is set to V(True), this is ignored.
|
||||
- This feature requires helm diff >= 3.9.12.
|
||||
type: bool
|
||||
required: false
|
||||
default: False
|
||||
version_added: 6.0.0
|
||||
|
||||
#Helm options
|
||||
disable_hook:
|
||||
@@ -181,7 +191,7 @@ options:
|
||||
- similar to C(wait_timeout) but does not required C(wait) to be activated.
|
||||
- Mutually exclusive with C(wait_timeout).
|
||||
type: str
|
||||
version_added: "2.3.0"
|
||||
version_added: 2.3.0
|
||||
atomic:
|
||||
description:
|
||||
- If set, the installation process deletes the installation on failure.
|
||||
@@ -192,12 +202,12 @@ options:
|
||||
- Create the release namespace if not present.
|
||||
type: bool
|
||||
default: False
|
||||
version_added: "0.11.1"
|
||||
version_added: 0.11.1
|
||||
post_renderer:
|
||||
description:
|
||||
- Path to an executable to be used for post rendering.
|
||||
type: str
|
||||
version_added: "2.4.0"
|
||||
version_added: 2.4.0
|
||||
replace:
|
||||
description:
|
||||
- Reuse the given name, only if that name is a deleted release which remains in the history.
|
||||
@@ -205,19 +215,49 @@ options:
|
||||
- mutually exclusive with with C(history_max).
|
||||
type: bool
|
||||
default: False
|
||||
version_added: "1.11.0"
|
||||
version_added: 1.11.0
|
||||
skip_crds:
|
||||
description:
|
||||
- Skip custom resource definitions when installing or upgrading.
|
||||
type: bool
|
||||
default: False
|
||||
version_added: "1.2.0"
|
||||
version_added: 1.2.0
|
||||
history_max:
|
||||
description:
|
||||
- Limit the maximum number of revisions saved per release.
|
||||
- mutually exclusive with with C(replace).
|
||||
type: int
|
||||
version_added: "2.2.0"
|
||||
version_added: 2.2.0
|
||||
insecure_skip_tls_verify:
|
||||
description:
|
||||
- Skip tls certificate checks for the chart download.
|
||||
- Do not confuse with the C(validate_certs) option.
|
||||
- This option is only available for helm >= 3.16.0.
|
||||
type: bool
|
||||
default: False
|
||||
aliases: [ skip_tls_certs_check ]
|
||||
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:
|
||||
- When upgrading, 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:
|
||||
- kubernetes.core.helm_common_options
|
||||
"""
|
||||
@@ -300,6 +340,12 @@ EXAMPLES = r"""
|
||||
chart_ref: "https://github.com/grafana/helm-charts/releases/download/grafana-5.6.0/grafana-5.6.0.tgz"
|
||||
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
|
||||
- name: Deploy new-relic client chart
|
||||
kubernetes.core.helm:
|
||||
@@ -476,12 +522,28 @@ def run_dep_update(module, chart_ref):
|
||||
rc, out, err = module.run_helm_command(dep_update)
|
||||
|
||||
|
||||
def fetch_chart_info(module, command, chart_ref):
|
||||
def fetch_chart_info(
|
||||
module, command, chart_ref, insecure_skip_tls_verify=False, plain_http=False
|
||||
):
|
||||
"""
|
||||
Get chart info
|
||||
"""
|
||||
inspect_command = command + f" show chart '{chart_ref}'"
|
||||
|
||||
if 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)
|
||||
|
||||
return yaml.safe_load(out)
|
||||
@@ -509,6 +571,11 @@ def deploy(
|
||||
set_value_args=None,
|
||||
reuse_values=None,
|
||||
reset_values=True,
|
||||
reset_then_reuse_values=False,
|
||||
insecure_skip_tls_verify=False,
|
||||
plain_http=False,
|
||||
take_ownership=False,
|
||||
skip_schema_validation=False,
|
||||
):
|
||||
"""
|
||||
Install/upgrade/rollback release chart
|
||||
@@ -522,10 +589,23 @@ def deploy(
|
||||
deploy_command = command + " upgrade -i" # install/upgrade
|
||||
if reset_values:
|
||||
deploy_command += " --reset-values"
|
||||
if take_ownership:
|
||||
deploy_command += " --take-ownership"
|
||||
|
||||
if reuse_values is not None:
|
||||
deploy_command += " --reuse-values=" + str(reuse_values)
|
||||
|
||||
if reset_then_reuse_values:
|
||||
helm_version = module.get_helm_version()
|
||||
if LooseVersion(helm_version) < LooseVersion("3.14.0"):
|
||||
module.fail_json(
|
||||
msg="reset_then_reuse_values requires helm >= 3.14.0, current version is {0}".format(
|
||||
helm_version
|
||||
)
|
||||
)
|
||||
else:
|
||||
deploy_command += " --reset-then-reuse-values"
|
||||
|
||||
if wait:
|
||||
deploy_command += " --wait"
|
||||
if wait_timeout is not None:
|
||||
@@ -549,6 +629,20 @@ def deploy(
|
||||
if create_namespace:
|
||||
deploy_command += " --create-namespace"
|
||||
|
||||
if insecure_skip_tls_verify:
|
||||
helm_version = module.get_helm_version()
|
||||
if LooseVersion(helm_version) < LooseVersion("3.16.0"):
|
||||
module.fail_json(
|
||||
msg="insecure_skip_tls_verify requires helm >= 3.16.0, current version is {0}".format(
|
||||
helm_version
|
||||
)
|
||||
)
|
||||
else:
|
||||
deploy_command += " --insecure-skip-tls-verify"
|
||||
|
||||
if plain_http:
|
||||
deploy_command += " --plain-http"
|
||||
|
||||
if values_files:
|
||||
for value_file in values_files:
|
||||
deploy_command += " --values=" + value_file
|
||||
@@ -572,6 +666,17 @@ def deploy(
|
||||
if 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}'"
|
||||
return deploy_command
|
||||
|
||||
@@ -639,6 +744,13 @@ def helmdiff_check(
|
||||
replace=False,
|
||||
chart_repo_url=None,
|
||||
post_renderer=False,
|
||||
set_value_args=None,
|
||||
reuse_values=None,
|
||||
reset_values=True,
|
||||
reset_then_reuse_values=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.
|
||||
@@ -652,10 +764,14 @@ def helmdiff_check(
|
||||
if chart_version is not None:
|
||||
cmd += " " + "--version=" + chart_version
|
||||
if not replace:
|
||||
cmd += " " + "--reset-values"
|
||||
cmd += " " + "--reset-values=" + str(reset_values)
|
||||
if post_renderer:
|
||||
cmd += " --post-renderer=" + post_renderer
|
||||
|
||||
if values_files:
|
||||
for value_file in values_files:
|
||||
cmd += " --values=" + value_file
|
||||
|
||||
if release_values != {}:
|
||||
fd, path = tempfile.mkstemp(suffix=".yml")
|
||||
with open(path, "w") as yaml_file:
|
||||
@@ -663,9 +779,54 @@ def helmdiff_check(
|
||||
cmd += " -f=" + path
|
||||
module.add_cleanup_file(path)
|
||||
|
||||
if values_files:
|
||||
for values_file in values_files:
|
||||
cmd += " -f=" + values_file
|
||||
if set_value_args:
|
||||
cmd += " " + set_value_args
|
||||
|
||||
if reuse_values:
|
||||
cmd += " --reuse-values"
|
||||
|
||||
if reset_then_reuse_values:
|
||||
helm_diff_version = get_plugin_version("diff")
|
||||
helm_version = module.get_helm_version()
|
||||
fail_msg = ""
|
||||
if LooseVersion(helm_diff_version) < LooseVersion("3.9.12"):
|
||||
fail_msg = "reset_then_reuse_values requires helm diff >= 3.9.12, current version is {0}\n".format(
|
||||
helm_diff_version
|
||||
)
|
||||
if LooseVersion(helm_version) < LooseVersion("3.14.0"):
|
||||
fail_msg += "reset_then_reuse_values requires helm >= 3.14.0, current version is {0}\n".format(
|
||||
helm_version
|
||||
)
|
||||
|
||||
if fail_msg:
|
||||
module.fail_json(msg=fail_msg)
|
||||
else:
|
||||
cmd += " --reset-then-reuse-values"
|
||||
|
||||
if 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)
|
||||
return (len(out.strip()) > 0, out.strip())
|
||||
@@ -726,6 +887,13 @@ def argument_spec():
|
||||
set_values=dict(type="list", elements="dict"),
|
||||
reuse_values=dict(type="bool"),
|
||||
reset_values=dict(type="bool", default=True),
|
||||
reset_then_reuse_values=dict(type="bool", default=False),
|
||||
insecure_skip_tls_verify=dict(
|
||||
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
|
||||
@@ -778,6 +946,11 @@ def main():
|
||||
set_values = module.params.get("set_values")
|
||||
reuse_values = module.params.get("reuse_values")
|
||||
reset_values = module.params.get("reset_values")
|
||||
reset_then_reuse_values = module.params.get("reset_then_reuse_values")
|
||||
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:
|
||||
run_repo_update(module)
|
||||
@@ -787,6 +960,33 @@ def main():
|
||||
release_status = get_release_status(module, release_name, all_status=all_status)
|
||||
|
||||
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 = {}
|
||||
if release_state == "absent" and release_status is not None:
|
||||
# skip release statuses 'uninstalled' and 'uninstalling'
|
||||
@@ -815,7 +1015,9 @@ def main():
|
||||
helm_cmd += " --repo=" + chart_repo_url
|
||||
|
||||
# Fetch chart info to have real version and real name for chart_ref from archive, folder or url
|
||||
chart_info = fetch_chart_info(module, helm_cmd, chart_ref)
|
||||
chart_info = fetch_chart_info(
|
||||
module, helm_cmd, chart_ref, insecure_skip_tls_verify, plain_http
|
||||
)
|
||||
|
||||
if dependency_update:
|
||||
if chart_info.get("dependencies"):
|
||||
@@ -847,11 +1049,11 @@ def main():
|
||||
"Please consider add dependencies block or disable dependency_update to remove this warning."
|
||||
)
|
||||
|
||||
if release_status is None: # Not installed
|
||||
set_value_args = None
|
||||
if set_values:
|
||||
set_value_args = module.get_helm_set_values_args(set_values)
|
||||
set_value_args = None
|
||||
if set_values:
|
||||
set_value_args = module.get_helm_set_values_args(set_values)
|
||||
|
||||
if release_status is None: # Not installed
|
||||
helm_cmd = deploy(
|
||||
module,
|
||||
helm_cmd,
|
||||
@@ -874,6 +1076,10 @@ def main():
|
||||
set_value_args=set_value_args,
|
||||
reuse_values=reuse_values,
|
||||
reset_values=reset_values,
|
||||
reset_then_reuse_values=reset_then_reuse_values,
|
||||
insecure_skip_tls_verify=insecure_skip_tls_verify,
|
||||
plain_http=plain_http,
|
||||
skip_schema_validation=skip_schema_validation,
|
||||
)
|
||||
changed = True
|
||||
|
||||
@@ -896,6 +1102,13 @@ def main():
|
||||
replace,
|
||||
chart_repo_url,
|
||||
post_renderer,
|
||||
set_value_args,
|
||||
reuse_values=reuse_values,
|
||||
reset_values=reset_values,
|
||||
reset_then_reuse_values=reset_then_reuse_values,
|
||||
insecure_skip_tls_verify=insecure_skip_tls_verify,
|
||||
plain_http=plain_http,
|
||||
skip_schema_validation=skip_schema_validation,
|
||||
)
|
||||
if would_change and module._diff:
|
||||
opt_result["diff"] = {"prepared": prepared}
|
||||
@@ -909,10 +1122,6 @@ def main():
|
||||
)
|
||||
|
||||
if force or would_change:
|
||||
set_value_args = None
|
||||
if set_values:
|
||||
set_value_args = module.get_helm_set_values_args(set_values)
|
||||
|
||||
helm_cmd = deploy(
|
||||
module,
|
||||
helm_cmd,
|
||||
@@ -935,6 +1144,11 @@ def main():
|
||||
set_value_args=set_value_args,
|
||||
reuse_values=reuse_values,
|
||||
reset_values=reset_values,
|
||||
reset_then_reuse_values=reset_then_reuse_values,
|
||||
insecure_skip_tls_verify=insecure_skip_tls_verify,
|
||||
plain_http=plain_http,
|
||||
take_ownership=take_ownership,
|
||||
skip_schema_validation=skip_schema_validation,
|
||||
)
|
||||
changed = True
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ module: helm_info
|
||||
|
||||
short_description: Get information from Helm package deployed inside the cluster
|
||||
|
||||
version_added: "0.11.0"
|
||||
version_added: 0.11.0
|
||||
|
||||
author:
|
||||
- Lucas Boisserie (@LucasBoisserie)
|
||||
@@ -53,7 +53,7 @@ options:
|
||||
type: list
|
||||
elements: str
|
||||
default: []
|
||||
version_added: "2.3.0"
|
||||
version_added: 2.3.0
|
||||
get_all_values:
|
||||
description:
|
||||
- Set to C(True) if you want to get all (computed) values of the release.
|
||||
@@ -61,7 +61,7 @@ options:
|
||||
required: false
|
||||
default: false
|
||||
type: bool
|
||||
version_added: "2.4.0"
|
||||
version_added: 2.4.0
|
||||
extends_documentation_fragment:
|
||||
- kubernetes.core.helm_common_options
|
||||
"""
|
||||
@@ -123,18 +123,18 @@ status:
|
||||
elements: dict
|
||||
description: Hooks of the release
|
||||
returned: always
|
||||
version_added: "2.4.0"
|
||||
version_added: 2.4.0
|
||||
notes:
|
||||
type: str
|
||||
description: Notes of the release
|
||||
returned: always
|
||||
version_added: "2.4.0"
|
||||
version_added: 2.4.0
|
||||
manifest:
|
||||
type: list
|
||||
elements: dict
|
||||
description: Manifest of the release
|
||||
returned: always
|
||||
version_added: "2.4.0"
|
||||
version_added: 2.4.0
|
||||
"""
|
||||
|
||||
import copy
|
||||
|
||||
@@ -12,7 +12,7 @@ DOCUMENTATION = r"""
|
||||
---
|
||||
module: helm_plugin
|
||||
short_description: Manage Helm plugins
|
||||
version_added: "1.0.0"
|
||||
version_added: 1.0.0
|
||||
author:
|
||||
- Abhijeet Kasurde (@Akasurde)
|
||||
requirements:
|
||||
@@ -47,7 +47,7 @@ options:
|
||||
- Ignored when C(state=absent) or C(state=latest).
|
||||
required: false
|
||||
type: str
|
||||
version_added: "2.3.0"
|
||||
version_added: 2.3.0
|
||||
extends_documentation_fragment:
|
||||
- kubernetes.core.helm_common_options
|
||||
"""
|
||||
|
||||
@@ -12,7 +12,7 @@ DOCUMENTATION = r"""
|
||||
---
|
||||
module: helm_plugin_info
|
||||
short_description: Gather information about Helm plugins
|
||||
version_added: "1.0.0"
|
||||
version_added: 1.0.0
|
||||
author:
|
||||
- Abhijeet Kasurde (@Akasurde)
|
||||
requirements:
|
||||
|
||||
@@ -12,7 +12,7 @@ DOCUMENTATION = r"""
|
||||
---
|
||||
module: helm_pull
|
||||
short_description: download a chart from a repository and (optionally) unpack it in local directory.
|
||||
version_added: "2.4.0"
|
||||
version_added: 2.4.0
|
||||
author:
|
||||
- Aubin Bikouo (@abikouo)
|
||||
description:
|
||||
@@ -75,9 +75,10 @@ options:
|
||||
skip_tls_certs_check:
|
||||
description:
|
||||
- Whether or not to check tls certificate for the chart download.
|
||||
- Requires helm >= 3.3.0.
|
||||
- Requires helm >= 3.3.0. Alias C(insecure_skip_tls_verify) added in 5.3.0.
|
||||
type: bool
|
||||
default: False
|
||||
aliases: [ insecure_skip_tls_verify ]
|
||||
chart_devel:
|
||||
description:
|
||||
- Use development versions, too. Equivalent to version '>0.0.0-0'.
|
||||
@@ -113,6 +114,13 @@ options:
|
||||
- The path of a helm binary to use.
|
||||
required: false
|
||||
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"""
|
||||
@@ -189,8 +197,10 @@ def main():
|
||||
repo_password=dict(
|
||||
type="str", no_log=True, aliases=["password", "chart_repo_password"]
|
||||
),
|
||||
pass_credentials=dict(type="bool", default=False),
|
||||
skip_tls_certs_check=dict(type="bool", default=False),
|
||||
pass_credentials=dict(type="bool", default=False, no_log=False),
|
||||
skip_tls_certs_check=dict(
|
||||
type="bool", default=False, aliases=["insecure_skip_tls_verify"]
|
||||
),
|
||||
chart_devel=dict(type="bool"),
|
||||
untar_chart=dict(type="bool", default=False),
|
||||
destination=dict(type="path", required=True),
|
||||
@@ -198,6 +208,7 @@ def main():
|
||||
chart_ssl_cert_file=dict(type="path"),
|
||||
chart_ssl_key_file=dict(type="path"),
|
||||
binary_path=dict(type="path"),
|
||||
plain_http=dict(type="bool", default=False),
|
||||
)
|
||||
module = AnsibleHelmModule(
|
||||
argument_spec=argspec,
|
||||
@@ -222,6 +233,7 @@ def main():
|
||||
chart_ca_cert="3.1.0",
|
||||
chart_ssl_cert_file="3.1.0",
|
||||
chart_ssl_key_file="3.1.0",
|
||||
plain_http="3.13.0",
|
||||
)
|
||||
|
||||
def test_version_requirement(opt):
|
||||
@@ -261,6 +273,7 @@ def main():
|
||||
skip_tls_certs_check=dict(key="insecure-skip-tls-verify"),
|
||||
chart_devel=dict(key="devel"),
|
||||
untar_chart=dict(key="untar"),
|
||||
plain_http=dict(key="plain-http"),
|
||||
)
|
||||
|
||||
for k, v in helm_flag_args.items():
|
||||
|
||||
249
plugins/modules/helm_registry_auth.py
Normal file
249
plugins/modules/helm_registry_auth.py
Normal file
@@ -0,0 +1,249 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright: © Ericsson AB 2024
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
|
||||
DOCUMENTATION = r"""
|
||||
---
|
||||
module: helm_registry_auth
|
||||
|
||||
short_description: Helm registry authentication module
|
||||
|
||||
version_added: 5.1.0
|
||||
|
||||
author:
|
||||
- Yuriy Novostavskiy (@yurnov)
|
||||
|
||||
requirements:
|
||||
- "helm (https://github.com/helm/helm/releases) => 3.8.0"
|
||||
|
||||
description:
|
||||
- Helm registry authentication module allows you to login C(helm registry login) and logout C(helm registry logout) from a Helm registry.
|
||||
|
||||
options:
|
||||
state:
|
||||
description:
|
||||
- Desired state of the registry.
|
||||
- If set to V(present) attempt to log in to the remote registry server using the URL specified in O(host).
|
||||
- If set to V(absent) attempt to log out from the remote registry server using the URL specified in O(host).
|
||||
- As helm >= 3.18.0 reports successful logout even if the user is not logged in, this module will report a change regardless of the current state.
|
||||
required: false
|
||||
default: present
|
||||
choices: ['present', 'absent']
|
||||
type: str
|
||||
host:
|
||||
description:
|
||||
- Provide a URL for accessing the registry.
|
||||
required: true
|
||||
aliases: [ registry_url ]
|
||||
type: str
|
||||
insecure:
|
||||
description:
|
||||
- Allow connections to SSL sites without certs.
|
||||
required: false
|
||||
default: false
|
||||
type: bool
|
||||
username:
|
||||
description:
|
||||
- Username for the registry.
|
||||
required: false
|
||||
type: str
|
||||
aliases: [ repo_username ]
|
||||
password:
|
||||
description:
|
||||
- Password for the registry.
|
||||
required: false
|
||||
type: str
|
||||
aliases: [ repo_password ]
|
||||
key_file:
|
||||
description:
|
||||
- Path to the client key SSL file for identify registry client using this key file.
|
||||
required: false
|
||||
type: path
|
||||
cert_file:
|
||||
description:
|
||||
- Path to the client certificate SSL file for identify registry client using this certificate file.
|
||||
required: false
|
||||
type: path
|
||||
ca_file:
|
||||
description:
|
||||
- Path to the CA certificate SSL file for verify registry server certificate.
|
||||
required: false
|
||||
type: path
|
||||
binary_path:
|
||||
description:
|
||||
- The path of a helm binary to use.
|
||||
required: false
|
||||
type: path
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
- name: Login to remote registry
|
||||
kubernetes.core.helm_registry_auth:
|
||||
username: admin
|
||||
password: "sample_password"
|
||||
host: localhost:5000
|
||||
|
||||
- name: Logout from remote registry
|
||||
kubernetes.core.helm_registry_auth:
|
||||
state: absent
|
||||
host: localhost:5000
|
||||
"""
|
||||
|
||||
RETURN = r"""
|
||||
stdout:
|
||||
type: str
|
||||
description: Full C(helm) command stdout, in case you want to display it or examine the event log
|
||||
returned: always
|
||||
stout_lines:
|
||||
type: list
|
||||
description: Full C(helm) command stdout, in case you want to display it or examine the event log
|
||||
returned: always
|
||||
stderr:
|
||||
type: str
|
||||
description: >-
|
||||
Full C(helm) command stderr, in case you want to display it or examine the event log.
|
||||
Please be note that helm binnary may print messages to stderr even if the command is successful.
|
||||
returned: always
|
||||
sample: 'Login Succeeded\n'
|
||||
stderr_lines:
|
||||
type: list
|
||||
description: Full C(helm) command stderr, in case you want to display it or examine the event log
|
||||
returned: always
|
||||
command:
|
||||
type: str
|
||||
description: Full C(helm) command executed
|
||||
returned: always
|
||||
sample: '/usr/local/bin/helm registry login oci-registry.domain.example --username=admin --password-stdin --insecure'
|
||||
failed:
|
||||
type: bool
|
||||
description: Indicate if the C(helm) command failed
|
||||
returned: always
|
||||
sample: false
|
||||
"""
|
||||
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.helm import (
|
||||
AnsibleHelmModule,
|
||||
)
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.version import (
|
||||
LooseVersion,
|
||||
)
|
||||
|
||||
|
||||
def arg_spec():
|
||||
return dict(
|
||||
binary_path=dict(type="path", required=False),
|
||||
host=dict(type="str", aliases=["registry_url"], required=True),
|
||||
state=dict(default="present", choices=["present", "absent"], required=False),
|
||||
insecure=dict(type="bool", default=False, required=False),
|
||||
username=dict(type="str", aliases=["repo_username"], required=False),
|
||||
password=dict(
|
||||
type="str", aliases=["repo_password"], no_log=True, required=False
|
||||
),
|
||||
key_file=dict(type="path", required=False),
|
||||
cert_file=dict(type="path", required=False),
|
||||
ca_file=dict(type="path", required=False),
|
||||
)
|
||||
|
||||
|
||||
def login(
|
||||
command,
|
||||
host,
|
||||
insecure,
|
||||
username,
|
||||
password,
|
||||
key_file,
|
||||
cert_file,
|
||||
ca_file,
|
||||
):
|
||||
login_command = command + " registry login " + host
|
||||
|
||||
if username is not None and password is not None:
|
||||
login_command += " --username=" + username + " --password-stdin"
|
||||
|
||||
if insecure:
|
||||
login_command += " --insecure"
|
||||
|
||||
if key_file is not None:
|
||||
login_command += " --key-file=" + key_file
|
||||
|
||||
if cert_file is not None:
|
||||
login_command += " --cert-file=" + cert_file
|
||||
|
||||
if ca_file is not None:
|
||||
login_command += " --ca-file=" + ca_file
|
||||
|
||||
return login_command
|
||||
|
||||
|
||||
def logout(command, host):
|
||||
return command + " registry logout " + host
|
||||
|
||||
|
||||
def main():
|
||||
global module
|
||||
|
||||
module = AnsibleHelmModule(
|
||||
argument_spec=arg_spec(),
|
||||
required_together=[["username", "password"]],
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
changed = False
|
||||
|
||||
host = module.params.get("host")
|
||||
state = module.params.get("state")
|
||||
insecure = module.params.get("insecure")
|
||||
username = module.params.get("username")
|
||||
password = module.params.get("password")
|
||||
key_file = module.params.get("key_file")
|
||||
cert_file = module.params.get("cert_file")
|
||||
ca_file = module.params.get("ca_file")
|
||||
|
||||
helm_cmd = module.get_helm_binary()
|
||||
|
||||
if state == "absent":
|
||||
helm_cmd = logout(helm_cmd, host)
|
||||
changed = True
|
||||
elif state == "present":
|
||||
helm_cmd = login(
|
||||
helm_cmd, host, insecure, username, password, key_file, cert_file, ca_file
|
||||
)
|
||||
changed = True
|
||||
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=changed, command=helm_cmd)
|
||||
|
||||
rc, out, err = module.run_helm_command(
|
||||
helm_cmd, data=password, fails_on_error=False
|
||||
)
|
||||
|
||||
if rc != 0:
|
||||
if state == "absent" and "Error: not logged in" in err:
|
||||
changed = False
|
||||
else:
|
||||
module.fail_json(
|
||||
msg="Failure when executing Helm command. Exited {0}.\nstdout: {1}\nstderr: {2}".format(
|
||||
rc, out, err
|
||||
),
|
||||
stderr=err,
|
||||
command=helm_cmd,
|
||||
)
|
||||
|
||||
helm_version = module.get_helm_version()
|
||||
if LooseVersion(helm_version) >= LooseVersion("3.18.0") and state == "absent":
|
||||
# https://github.com/ansible-collections/kubernetes.core/issues/944
|
||||
module.warn(
|
||||
"The helm_registry_auth is not idempotent with helm >= 3.18.0, always report a change."
|
||||
)
|
||||
|
||||
module.exit_json(changed=changed, stdout=out, stderr=err, command=helm_cmd)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -14,7 +14,7 @@ module: helm_repository
|
||||
|
||||
short_description: Manage Helm repositories.
|
||||
|
||||
version_added: "0.11.0"
|
||||
version_added: 0.11.0
|
||||
|
||||
author:
|
||||
- Lucas Boisserie (@LucasBoisserie)
|
||||
@@ -76,12 +76,12 @@ options:
|
||||
description:
|
||||
- Provide a URL for accessing the API. Can also be specified via C(K8S_AUTH_HOST) environment variable.
|
||||
type: str
|
||||
version_added: "2.3.0"
|
||||
version_added: 2.3.0
|
||||
api_key:
|
||||
description:
|
||||
- Token used to authenticate with the API. Can also be specified via C(K8S_AUTH_API_KEY) environment variable.
|
||||
type: str
|
||||
version_added: "2.3.0"
|
||||
version_added: 2.3.0
|
||||
validate_certs:
|
||||
description:
|
||||
- Whether or not to verify the API server's SSL certificates. Can also be specified via C(K8S_AUTH_VERIFY_SSL)
|
||||
@@ -89,21 +89,21 @@ options:
|
||||
type: bool
|
||||
aliases: [ verify_ssl ]
|
||||
default: True
|
||||
version_added: "2.3.0"
|
||||
version_added: 2.3.0
|
||||
ca_cert:
|
||||
description:
|
||||
- Path to a CA certificate used to authenticate with the API. The full certificate chain must be provided to
|
||||
avoid certificate validation errors. Can also be specified via C(K8S_AUTH_SSL_CA_CERT) environment variable.
|
||||
type: path
|
||||
aliases: [ ssl_ca_cert ]
|
||||
version_added: "2.3.0"
|
||||
version_added: 2.3.0
|
||||
context:
|
||||
description:
|
||||
- Helm option to specify which kubeconfig context to use.
|
||||
- If the value is not specified in the task, the value of environment variable C(K8S_AUTH_CONTEXT) will be used instead.
|
||||
type: str
|
||||
aliases: [ kube_context ]
|
||||
version_added: "2.4.0"
|
||||
version_added: 2.4.0
|
||||
kubeconfig:
|
||||
description:
|
||||
- Helm option to specify kubeconfig path to use.
|
||||
@@ -111,14 +111,21 @@ options:
|
||||
- The configuration can be provided as dictionary.
|
||||
type: raw
|
||||
aliases: [ kubeconfig_path ]
|
||||
version_added: "2.4.0"
|
||||
version_added: 2.4.0
|
||||
force_update:
|
||||
description:
|
||||
- Whether or not to replace (overwrite) the repo if it already exists.
|
||||
type: bool
|
||||
aliases: [ force ]
|
||||
default: False
|
||||
version_added: "2.4.0"
|
||||
version_added: 2.4.0
|
||||
insecure_skip_tls_verify:
|
||||
description:
|
||||
- Skip tls certificate checks for the repository url.
|
||||
type: bool
|
||||
default: False
|
||||
aliases: [ skip_tls_certs_check ]
|
||||
version_added: "5.3.0"
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
@@ -226,6 +233,7 @@ def install_repository(
|
||||
repository_password,
|
||||
pass_credentials,
|
||||
force_update,
|
||||
insecure_skip_tls_verify,
|
||||
):
|
||||
install_command = command + " repo add " + repository_name + " " + repository_url
|
||||
|
||||
@@ -239,6 +247,9 @@ def install_repository(
|
||||
if force_update:
|
||||
install_command += " --force-update"
|
||||
|
||||
if insecure_skip_tls_verify:
|
||||
install_command += " --insecure-skip-tls-verify"
|
||||
|
||||
return install_command
|
||||
|
||||
|
||||
@@ -262,6 +273,9 @@ def argument_spec():
|
||||
),
|
||||
pass_credentials=dict(type="bool", default=False, no_log=True),
|
||||
force_update=dict(type="bool", default=False, aliases=["force"]),
|
||||
insecure_skip_tls_verify=dict(
|
||||
type="bool", default=False, aliases=["skip_tls_certs_check"]
|
||||
),
|
||||
)
|
||||
)
|
||||
return arg_spec
|
||||
@@ -290,6 +304,7 @@ def main():
|
||||
repo_state = module.params.get("repo_state")
|
||||
pass_credentials = module.params.get("pass_credentials")
|
||||
force_update = module.params.get("force_update")
|
||||
insecure_skip_tls_verify = module.params.get("insecure_skip_tls_verify")
|
||||
|
||||
helm_cmd = module.get_helm_binary()
|
||||
|
||||
@@ -308,6 +323,7 @@ def main():
|
||||
repo_password,
|
||||
pass_credentials,
|
||||
force_update,
|
||||
insecure_skip_tls_verify,
|
||||
)
|
||||
changed = True
|
||||
elif repository_status["url"] != repo_url:
|
||||
|
||||
@@ -53,7 +53,7 @@ options:
|
||||
default: false
|
||||
type: bool
|
||||
aliases: [ dep_up ]
|
||||
version_added: "2.4.0"
|
||||
version_added: 2.4.0
|
||||
disable_hook:
|
||||
description:
|
||||
- Prevent hooks from running during install.
|
||||
@@ -72,6 +72,13 @@ options:
|
||||
- If the directory already exists, it will be overwritten.
|
||||
required: false
|
||||
type: path
|
||||
insecure_registry:
|
||||
description:
|
||||
- Skip TLS certificate checks for the chart download
|
||||
required: false
|
||||
type: bool
|
||||
default: false
|
||||
version_added: 5.1.0
|
||||
release_name:
|
||||
description:
|
||||
- Release name to use in rendered templates.
|
||||
@@ -139,7 +146,14 @@ options:
|
||||
- string
|
||||
- json
|
||||
- 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"""
|
||||
@@ -211,6 +225,9 @@ from ansible.module_utils.basic import missing_required_lib
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.helm import (
|
||||
AnsibleHelmModule,
|
||||
)
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.version import (
|
||||
LooseVersion,
|
||||
)
|
||||
|
||||
|
||||
def template(
|
||||
@@ -221,6 +238,7 @@ def template(
|
||||
dependency_update=None,
|
||||
disable_hook=None,
|
||||
output_dir=None,
|
||||
insecure_registry=None,
|
||||
show_only=None,
|
||||
release_name=None,
|
||||
release_namespace=None,
|
||||
@@ -228,6 +246,7 @@ def template(
|
||||
values_files=None,
|
||||
include_crds=False,
|
||||
set_values=None,
|
||||
plain_http=False,
|
||||
):
|
||||
cmd += " template "
|
||||
|
||||
@@ -251,6 +270,12 @@ def template(
|
||||
if output_dir:
|
||||
cmd += " --output-dir=" + output_dir
|
||||
|
||||
if insecure_registry:
|
||||
cmd += " --insecure-skip-tls-verify"
|
||||
|
||||
if plain_http:
|
||||
cmd += " --plain-http"
|
||||
|
||||
if show_only:
|
||||
for template in show_only:
|
||||
cmd += " -s " + template
|
||||
@@ -289,12 +314,14 @@ def main():
|
||||
include_crds=dict(type="bool", default=False),
|
||||
release_name=dict(type="str", aliases=["name"]),
|
||||
output_dir=dict(type="path"),
|
||||
insecure_registry=dict(type="bool", default=False),
|
||||
release_namespace=dict(type="str"),
|
||||
release_values=dict(type="dict", default={}, aliases=["values"]),
|
||||
show_only=dict(type="list", default=[], elements="str"),
|
||||
values_files=dict(type="list", default=[], elements="str"),
|
||||
update_repo_cache=dict(type="bool", default=False),
|
||||
set_values=dict(type="list", elements="dict"),
|
||||
plain_http=dict(type="bool", default=False),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
@@ -308,18 +335,29 @@ def main():
|
||||
include_crds = module.params.get("include_crds")
|
||||
release_name = module.params.get("release_name")
|
||||
output_dir = module.params.get("output_dir")
|
||||
insecure_registry = module.params.get("insecure_registry")
|
||||
show_only = module.params.get("show_only")
|
||||
release_namespace = module.params.get("release_namespace")
|
||||
release_values = module.params.get("release_values")
|
||||
values_files = module.params.get("values_files")
|
||||
update_repo_cache = module.params.get("update_repo_cache")
|
||||
set_values = module.params.get("set_values")
|
||||
plain_http = module.params.get("plain_http")
|
||||
|
||||
if not IMP_YAML:
|
||||
module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR)
|
||||
|
||||
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:
|
||||
update_cmd = helm_cmd + " repo update"
|
||||
module.run_helm_command(update_cmd)
|
||||
@@ -337,12 +375,14 @@ def main():
|
||||
disable_hook=disable_hook,
|
||||
release_name=release_name,
|
||||
output_dir=output_dir,
|
||||
insecure_registry=insecure_registry,
|
||||
release_namespace=release_namespace,
|
||||
release_values=release_values,
|
||||
show_only=show_only,
|
||||
values_files=values_files,
|
||||
include_crds=include_crds,
|
||||
set_values=set_values_args,
|
||||
plain_http=plain_http,
|
||||
)
|
||||
|
||||
if not check_mode:
|
||||
|
||||
@@ -57,15 +57,14 @@ options:
|
||||
- Whether to override the default patch merge approach with a specific type. By default, the strategic
|
||||
merge will typically be used.
|
||||
- For example, Custom Resource Definitions typically aren't updatable by the usual strategic merge. You may
|
||||
want to use C(merge) if you see "strategic merge patch format is not supported"
|
||||
want to use C(merge) if you see "strategic merge patch format is not supported".
|
||||
- See U(https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/#use-a-json-merge-patch-to-update-a-deployment)
|
||||
- If more than one C(merge_type) is given, the merge_types will be tried in order. This defaults to
|
||||
C(['strategic-merge', 'merge']), which is ideal for using the same parameters on resource kinds that
|
||||
combine Custom Resources and built-in resources.
|
||||
- mutually exclusive with C(apply)
|
||||
- I(merge_type=json) is deprecated and will be removed in version 3.0.0. Please use M(kubernetes.core.k8s_json_patch) instead.
|
||||
- Mutually exclusive with C(apply).
|
||||
- I(merge_type=json) has been removed in version 4.0.0. Please use M(kubernetes.core.k8s_json_patch) instead.
|
||||
choices:
|
||||
- json
|
||||
- merge
|
||||
- strategic-merge
|
||||
type: list
|
||||
@@ -101,7 +100,7 @@ options:
|
||||
- C(apply) compares the desired resource definition with the previously supplied resource definition,
|
||||
ignoring properties that are automatically generated
|
||||
- C(apply) works better with Services than 'force=yes'
|
||||
- mutually exclusive with C(merge_type)
|
||||
- Mutually exclusive with C(merge_type).
|
||||
default: False
|
||||
type: bool
|
||||
template:
|
||||
@@ -182,17 +181,18 @@ options:
|
||||
- This parameter can be used with C(label_selectors) to restrict the resources to be deleted.
|
||||
type: bool
|
||||
default: false
|
||||
version_added: 2.5.0
|
||||
version_added: 3.0.0
|
||||
aliases:
|
||||
- all
|
||||
hidden_fields:
|
||||
description:
|
||||
- Hide fields matching this option in the result
|
||||
- An example might be C(hidden_fields=[metadata.managedFields])
|
||||
- Only field definitions that don't reference list items are supported (so V(spec.containers[0]) would not work)
|
||||
or V(hidden_fields=[spec.containers[0].env[3].value])
|
||||
or V(hidden_fields=[metadata.annotations[kubectl.kubernetes.io/last-applied-configuration]])
|
||||
type: list
|
||||
elements: str
|
||||
version_added: 2.5.0
|
||||
version_added: 3.0.0
|
||||
|
||||
requirements:
|
||||
- "python >= 3.9"
|
||||
@@ -460,7 +460,7 @@ def argspec():
|
||||
argument_spec.update(copy.deepcopy(AUTH_ARG_SPEC))
|
||||
argument_spec.update(copy.deepcopy(WAIT_ARG_SPEC))
|
||||
argument_spec["merge_type"] = dict(
|
||||
type="list", elements="str", choices=["json", "merge", "strategic-merge"]
|
||||
type="list", elements="str", choices=["merge", "strategic-merge"]
|
||||
)
|
||||
argument_spec["validate"] = dict(type="dict", default=None, options=validate_spec())
|
||||
argument_spec["append_hash"] = dict(type="bool", default=False)
|
||||
|
||||
@@ -11,7 +11,7 @@ __metaclass__ = type
|
||||
DOCUMENTATION = r"""
|
||||
module: k8s_cluster_info
|
||||
|
||||
version_added: "0.11.1"
|
||||
version_added: 0.11.1
|
||||
|
||||
short_description: Describe Kubernetes (K8s) cluster, APIs available and their respective versions
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ module: k8s_cp
|
||||
|
||||
short_description: Copy files and directories to and from pod.
|
||||
|
||||
version_added: "2.2.0"
|
||||
version_added: 2.2.0
|
||||
|
||||
author:
|
||||
- Aubin Bikouo (@abikouo)
|
||||
@@ -79,6 +79,7 @@ options:
|
||||
|
||||
notes:
|
||||
- the tar binary is required on the container when copying from local filesystem to pod.
|
||||
- the (init) container has to be started before you copy files or directories to it.
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
|
||||
@@ -15,7 +15,7 @@ module: k8s_drain
|
||||
|
||||
short_description: Drain, Cordon, or Uncordon node in k8s cluster
|
||||
|
||||
version_added: "2.2.0"
|
||||
version_added: 2.2.0
|
||||
|
||||
author: Aubin Bikouo (@abikouo)
|
||||
|
||||
@@ -47,7 +47,7 @@ options:
|
||||
- This option has effect only when C(state) is set to I(drain).
|
||||
type: list
|
||||
elements: str
|
||||
version_added: 2.5.0
|
||||
version_added: 3.0.0
|
||||
aliases:
|
||||
- label_selectors
|
||||
delete_options:
|
||||
@@ -106,7 +106,8 @@ EXAMPLES = r"""
|
||||
kubernetes.core.k8s_drain:
|
||||
state: drain
|
||||
name: foo
|
||||
force: yes
|
||||
delete_options:
|
||||
force: yes
|
||||
|
||||
- name: Drain node "foo", but abort if there are pods not managed by a ReplicationController, Job, or DaemonSet, and use a grace period of 15 minutes.
|
||||
kubernetes.core.k8s_drain:
|
||||
@@ -143,6 +144,7 @@ result:
|
||||
"""
|
||||
|
||||
import copy
|
||||
import json
|
||||
import time
|
||||
import traceback
|
||||
from datetime import datetime
|
||||
@@ -187,6 +189,17 @@ except ImportError:
|
||||
HAS_EVICTION_API = False
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
def filter_pods(pods, force, ignore_daemonset, delete_emptydir_data):
|
||||
k8s_kind_mirror = "kubernetes.io/config.mirror"
|
||||
daemonSet, unmanaged, mirror, localStorage, to_delete = [], [], [], [], []
|
||||
@@ -291,16 +304,19 @@ class K8sDrainAnsible(object):
|
||||
return (datetime.now() - start).seconds
|
||||
|
||||
response = None
|
||||
pod = pods.pop()
|
||||
pod = None
|
||||
while (_elapsed_time() < wait_timeout or wait_timeout == 0) and pods:
|
||||
if not pod:
|
||||
pod = pods.pop()
|
||||
pod = pods[-1]
|
||||
try:
|
||||
response = self._api_instance.read_namespaced_pod(
|
||||
namespace=pod[0], name=pod[1]
|
||||
)
|
||||
if not response:
|
||||
if not response or response.spec.node_name != self._module.params.get(
|
||||
"name"
|
||||
):
|
||||
pod = None
|
||||
del pods[-1]
|
||||
time.sleep(wait_sleep)
|
||||
except ApiException as exc:
|
||||
if exc.reason != "Not Found":
|
||||
@@ -308,6 +324,7 @@ class K8sDrainAnsible(object):
|
||||
msg="Exception raised: {0}".format(exc.reason)
|
||||
)
|
||||
pod = None
|
||||
del pods[-1]
|
||||
except Exception as e:
|
||||
self._module.fail_json(msg="Exception raised: {0}".format(to_native(e)))
|
||||
if not pods:
|
||||
@@ -334,7 +351,7 @@ class K8sDrainAnsible(object):
|
||||
if exc.reason != "Not Found":
|
||||
self._module.fail_json(
|
||||
msg="Failed to delete pod {0}/{1} due to: {2}".format(
|
||||
namespace, name, exc.reason
|
||||
namespace, name, to_native(format_dynamic_api_exc(exc))
|
||||
)
|
||||
)
|
||||
except Exception as exc:
|
||||
|
||||
@@ -15,7 +15,7 @@ module: k8s_exec
|
||||
|
||||
short_description: Execute command in Pod
|
||||
|
||||
version_added: "0.10.0"
|
||||
version_added: 0.10.0
|
||||
|
||||
author: "Tristan de Cacqueray (@tristanC)"
|
||||
|
||||
@@ -135,7 +135,7 @@ 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.common import (
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
|
||||
AUTH_ARG_SPEC,
|
||||
)
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
|
||||
@@ -219,12 +219,6 @@ def execute_module(module, client):
|
||||
else:
|
||||
rc = int(err["details"]["causes"][0]["message"])
|
||||
|
||||
module.deprecate(
|
||||
"The 'return_code' return key is being renamed to 'rc'. "
|
||||
"Both keys are being returned for now to allow users to migrate their automation.",
|
||||
version="4.0.0",
|
||||
collection_name="kubernetes.core",
|
||||
)
|
||||
module.exit_json(
|
||||
# Some command might change environment, but ultimately failing at end
|
||||
changed=True,
|
||||
|
||||
@@ -48,10 +48,11 @@ options:
|
||||
description:
|
||||
- Hide fields matching any of the field definitions in the result
|
||||
- An example might be C(hidden_fields=[metadata.managedFields])
|
||||
- Only field definitions that don't reference list items are supported (so V(spec.containers[0]) would not work)
|
||||
or V(hidden_fields=[spec.containers[0].env[3].value])
|
||||
or V(hidden_fields=[metadata.annotations[kubectl.kubernetes.io/last-applied-configuration]])
|
||||
type: list
|
||||
elements: str
|
||||
version_added: 2.5.0
|
||||
version_added: 3.0.0
|
||||
|
||||
extends_documentation_fragment:
|
||||
- kubernetes.core.k8s_auth_options
|
||||
|
||||
@@ -33,6 +33,14 @@ options:
|
||||
aliases:
|
||||
- api
|
||||
- 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:
|
||||
description:
|
||||
- Use to specify an object model.
|
||||
@@ -147,6 +155,7 @@ from ansible_collections.kubernetes.core.plugins.module_utils.k8s.exceptions imp
|
||||
)
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.service import (
|
||||
diff_objects,
|
||||
hide_fields,
|
||||
)
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.waiter import (
|
||||
get_waiter,
|
||||
@@ -174,6 +183,7 @@ JSON_PATCH_ARGS = {
|
||||
"namespace": {"type": "str"},
|
||||
"name": {"type": "str", "required": True},
|
||||
"patch": {"type": "list", "required": True, "elements": "dict"},
|
||||
"hidden_fields": {"type": "list", "elements": "str", "default": []},
|
||||
}
|
||||
|
||||
|
||||
@@ -203,6 +213,7 @@ def execute_module(module, client):
|
||||
namespace = module.params.get("namespace")
|
||||
patch = module.params.get("patch")
|
||||
|
||||
hidden_fields = module.params.get("hidden_fields")
|
||||
wait = module.params.get("wait")
|
||||
wait_sleep = module.params.get("wait_sleep")
|
||||
wait_timeout = module.params.get("wait_timeout")
|
||||
@@ -260,13 +271,13 @@ def execute_module(module, client):
|
||||
module.fail_json(msg=msg, error=to_native(exc), status="", reason="")
|
||||
|
||||
success = True
|
||||
result = {"result": obj}
|
||||
result = {"result": hide_fields(obj, hidden_fields)}
|
||||
if wait and not module.check_mode:
|
||||
waiter = get_waiter(client, resource, condition=wait_condition)
|
||||
success, result["result"], result["duration"] = waiter.wait(
|
||||
wait_timeout, wait_sleep, name, namespace
|
||||
)
|
||||
match, diffs = diff_objects(existing.to_dict(), obj)
|
||||
match, diffs = diff_objects(existing.to_dict(), obj, hidden_fields)
|
||||
result["changed"] = not match
|
||||
if module._diff:
|
||||
result["diff"] = diffs
|
||||
|
||||
@@ -14,7 +14,7 @@ module: k8s_log
|
||||
|
||||
short_description: Fetch logs from Kubernetes resources
|
||||
|
||||
version_added: "0.10.0"
|
||||
version_added: 0.10.0
|
||||
|
||||
author:
|
||||
- "Fabian von Feilitzsch (@fabianvf)"
|
||||
@@ -61,26 +61,26 @@ options:
|
||||
- A relative time in seconds before the current time from which to show logs.
|
||||
required: no
|
||||
type: str
|
||||
version_added: '2.2.0'
|
||||
version_added: 2.2.0
|
||||
previous:
|
||||
description:
|
||||
- If C(true), print the logs for the previous instance of the container in a pod if it exists.
|
||||
required: no
|
||||
type: bool
|
||||
default: False
|
||||
version_added: '2.4.0'
|
||||
version_added: 2.4.0
|
||||
tail_lines:
|
||||
description:
|
||||
- A number of lines from the end of the logs to retrieve.
|
||||
required: no
|
||||
type: int
|
||||
version_added: '2.4.0'
|
||||
version_added: 2.4.0
|
||||
all_containers:
|
||||
description:
|
||||
- If set to C(true), retrieve all containers' logs in the pod(s).
|
||||
- mutually exclusive with C(container).
|
||||
type: bool
|
||||
version_added: '2.4.0'
|
||||
version_added: 2.4.0
|
||||
|
||||
requirements:
|
||||
- "python >= 3.9"
|
||||
|
||||
@@ -12,7 +12,7 @@ __metaclass__ = type
|
||||
DOCUMENTATION = r"""
|
||||
module: k8s_rollback
|
||||
short_description: Rollback Kubernetes (K8S) Deployments and DaemonSets
|
||||
version_added: "1.0.0"
|
||||
version_added: 1.0.0
|
||||
author:
|
||||
- "Julien Huon (@julienhuon)"
|
||||
description:
|
||||
|
||||
@@ -13,7 +13,7 @@ __metaclass__ = type
|
||||
DOCUMENTATION = r"""
|
||||
module: k8s_taint
|
||||
short_description: Taint a node in a Kubernetes/OpenShift cluster
|
||||
version_added: "2.3.0"
|
||||
version_added: 2.3.0
|
||||
author: Alina Buzachis (@alinabuzachis)
|
||||
description:
|
||||
- Taint allows a node to refuse Pod to be scheduled unless that Pod has a matching toleration.
|
||||
|
||||
@@ -3,6 +3,7 @@ helm_default_archive_name: "helm-{{ helm_version }}-{{ ansible_system | lower }}
|
||||
helm_binary: "/tmp/helm/{{ ansible_system | lower }}-amd64/helm"
|
||||
|
||||
chart_test: "ingress-nginx"
|
||||
chart_test_oci: "oci://registry-1.docker.io/bitnamicharts/redis"
|
||||
chart_test_local_path: "nginx-ingress"
|
||||
chart_test_version: 4.2.4
|
||||
chart_test_version_local_path: 1.32.0
|
||||
@@ -26,3 +27,7 @@ test_namespace:
|
||||
- "helm-from-url"
|
||||
- "helm-reuse-values"
|
||||
- "helm-chart-with-space-into-name"
|
||||
- "helm-reset-then-reuse-values"
|
||||
- "helm-insecure"
|
||||
- "helm-test-take-ownership"
|
||||
- "helm-skip-schema-validation"
|
||||
|
||||
@@ -4,4 +4,6 @@
|
||||
loop_control:
|
||||
loop_var: helm_version
|
||||
with_items:
|
||||
- "v3.7.0"
|
||||
- "v3.15.4"
|
||||
- "v3.16.0"
|
||||
- "v3.17.0"
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
- name: test helm upgrade with reuse_values
|
||||
include_tasks: test_helm_reuse_values.yml
|
||||
|
||||
- name: test helm upgrade with reset_then_reuse_values
|
||||
include_tasks: test_helm_reset_then_reuse_values.yml
|
||||
|
||||
- name: test helm dependency update
|
||||
include_tasks: test_up_dep.yml
|
||||
|
||||
@@ -41,6 +44,15 @@
|
||||
- name: Test Skip CRDS feature in helm chart install
|
||||
include_tasks: test_crds.yml
|
||||
|
||||
- name: Test insecure registry flag feature
|
||||
include_tasks: test_helm_insecure.yml
|
||||
|
||||
- name: Test take ownership flag feature
|
||||
include_tasks: test_helm_take_ownership.yml
|
||||
|
||||
- name: Test helm skip_schema_validation
|
||||
include_tasks: test_skip_schema_validation.yml
|
||||
|
||||
- name: Clean helm install
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
|
||||
@@ -3,78 +3,89 @@
|
||||
vars:
|
||||
test_chart: "test-crds"
|
||||
helm_namespace: "{{ test_namespace[0] }}"
|
||||
helm_binary: helm
|
||||
block:
|
||||
- name: Create namespace
|
||||
k8s:
|
||||
kind: Namespace
|
||||
name: "{{ helm_namespace }}"
|
||||
|
||||
- name: Copy test chart
|
||||
copy:
|
||||
src: "{{ test_chart }}"
|
||||
dest: "/tmp/helm_test_crds/"
|
||||
|
||||
- name: Install chart while skipping CRDs
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "/tmp/helm_test_crds/{{ test_chart }}"
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: test-crds
|
||||
skip_crds: true
|
||||
register: install
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- install is changed
|
||||
- install.status.name == "test-crds"
|
||||
|
||||
- name: Fail to create custom resource
|
||||
k8s:
|
||||
definition:
|
||||
apiVersion: ansible.com/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: test-foo
|
||||
foobar: footest
|
||||
- name: Check if CRD resource is already present
|
||||
k8s_info:
|
||||
namespace: default
|
||||
kind: Foo
|
||||
api_version: ansible.com/v1
|
||||
ignore_errors: true
|
||||
register: result
|
||||
register: crd_check
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result is failed
|
||||
- "result.msg.startswith('Failed to find exact match for ansible.com/v1.Foo')"
|
||||
- when: crd_check is failed
|
||||
block:
|
||||
- name: Copy test chart
|
||||
copy:
|
||||
src: "{{ test_chart }}"
|
||||
dest: "/tmp/helm_test_crds/"
|
||||
|
||||
# Helm won't install CRDs into an existing release, so we need to delete this, first
|
||||
- name: Uninstall chart
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: test-crds
|
||||
state: absent
|
||||
|
||||
- name: Install chart with CRDs
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "/tmp/helm_test_crds/{{ test_chart }}"
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: test-crds
|
||||
|
||||
- name: Create custom resource
|
||||
k8s:
|
||||
definition:
|
||||
apiVersion: ansible.com/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
- name: Install chart while skipping CRDs
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "/tmp/helm_test_crds/{{ test_chart }}"
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: test-foo
|
||||
foobar: footest
|
||||
register: result
|
||||
name: test-crds
|
||||
skip_crds: true
|
||||
register: install
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result.result.foobar == "footest"
|
||||
- assert:
|
||||
that:
|
||||
- install is changed
|
||||
- install.status.name == "test-crds"
|
||||
|
||||
- name: Fail to create custom resource
|
||||
k8s:
|
||||
definition:
|
||||
apiVersion: ansible.com/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: test-foo
|
||||
foobar: footest
|
||||
ignore_errors: true
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result is failed
|
||||
- "result.msg.startswith('Failed to find exact match for ansible.com/v1.Foo')"
|
||||
|
||||
# Helm won't install CRDs into an existing release, so we need to delete this, first
|
||||
- name: Uninstall chart
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: test-crds
|
||||
state: absent
|
||||
|
||||
- name: Install chart with CRDs
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "/tmp/helm_test_crds/{{ test_chart }}"
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: test-crds
|
||||
|
||||
- name: Create custom resource
|
||||
k8s:
|
||||
definition:
|
||||
apiVersion: ansible.com/v1
|
||||
kind: Foo
|
||||
metadata:
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: test-foo
|
||||
foobar: footest
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result is changed
|
||||
- result.result.foobar == "footest"
|
||||
|
||||
always:
|
||||
- name: Remove chart
|
||||
|
||||
52
tests/integration/targets/helm/tasks/test_helm_insecure.yml
Normal file
52
tests/integration/targets/helm/tasks/test_helm_insecure.yml
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
- name: Test helm insecure
|
||||
vars:
|
||||
helm_namespace: "{{ test_namespace[12] }}"
|
||||
block:
|
||||
|
||||
- name: Initial chart installation (no flag set)
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "{{ chart_test_oci }}"
|
||||
release_name: test-secure
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
create_namespace: true
|
||||
register: install
|
||||
|
||||
- name: Validate that insecure flag is not set
|
||||
assert:
|
||||
that:
|
||||
- install is changed
|
||||
- '"--insecure-skip-tls-verify" not in install.command'
|
||||
|
||||
- name: Initial chart installation (insecure flag set)
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "{{ chart_test_oci }}"
|
||||
release_name: test-insecure
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
insecure_skip_tls_verify: true
|
||||
register: install
|
||||
ignore_errors: true
|
||||
|
||||
- name: Validate that insecure flag IS set if helm version is >= 3.16.0
|
||||
assert:
|
||||
that:
|
||||
- install is changed
|
||||
- '"--insecure-skip-tls-verify" in install.command'
|
||||
when: '"v3.16.0" <= helm_version'
|
||||
|
||||
- name: Validate that feature fails for helm < 3.16.0
|
||||
assert:
|
||||
that:
|
||||
- install is failed
|
||||
- '"insecure_skip_tls_verify requires helm >= 3.16.0" in install.msg'
|
||||
when: 'helm_version < "v3.16.0"'
|
||||
|
||||
always:
|
||||
- name: Remove helm namespace
|
||||
k8s:
|
||||
api_version: v1
|
||||
kind: Namespace
|
||||
name: "{{ helm_namespace }}"
|
||||
state: absent
|
||||
@@ -13,3 +13,11 @@
|
||||
that:
|
||||
- helm_missing_binary is failed
|
||||
- "'No such file or directory' in helm_missing_binary.msg"
|
||||
when: ansible_version.full is version('2.20', '<')
|
||||
|
||||
- name: Assert that helm is not installed (ansible 2.20+)
|
||||
assert:
|
||||
that:
|
||||
- helm_missing_binary is failed
|
||||
- "'Error executing command' in helm_missing_binary.msg"
|
||||
when: ansible_version.full is version('2.20', '>=')
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
- name: Test helm reset_then_reuse_values
|
||||
vars:
|
||||
helm_namespace: "{{ test_namespace[11] }}"
|
||||
chart_release_values:
|
||||
replica:
|
||||
replicaCount: 3
|
||||
master:
|
||||
count: 1
|
||||
kind: Deployment
|
||||
chart_reset_then_reuse_values:
|
||||
replica:
|
||||
replicaCount: 1
|
||||
master:
|
||||
count: 3
|
||||
block:
|
||||
- name: Initial chart installation
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: oci://registry-1.docker.io/bitnamicharts/redis
|
||||
release_name: test-redis
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
create_namespace: true
|
||||
release_values: "{{ chart_release_values }}"
|
||||
register: install
|
||||
|
||||
- name: Get value set as string
|
||||
helm_info:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
release_name: test-redis
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
register: release_value
|
||||
|
||||
- name: Validate that chart values are as expected
|
||||
assert:
|
||||
that:
|
||||
- install is changed
|
||||
- '"--reset-then-reuse-values" not in install.command'
|
||||
- release_value["status"]["values"] == chart_release_values
|
||||
|
||||
- name: Upgrade chart using reset_then_reuse_values=true
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: oci://registry-1.docker.io/bitnamicharts/redis
|
||||
release_name: test-redis
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
reuse_values: false
|
||||
reset_values: false
|
||||
reset_then_reuse_values: true
|
||||
release_values: "{{ chart_reset_then_reuse_values }}"
|
||||
register: upgrade
|
||||
|
||||
- name: Get value set as string
|
||||
helm_info:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
release_name: test-redis
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
register: release_value
|
||||
|
||||
- name: Validate that chart values are as expected
|
||||
assert:
|
||||
that:
|
||||
- upgrade is changed
|
||||
- '"--reset-then-reuse-values" in upgrade.command'
|
||||
- '"--reuse-values " not in upgrade.command'
|
||||
- '"--reset-values" not in upgrade.command'
|
||||
- release_value["status"]["values"] == chart_release_values | combine(chart_reset_then_reuse_values, recursive=true)
|
||||
|
||||
always:
|
||||
- name: Remove helm namespace
|
||||
k8s:
|
||||
api_version: v1
|
||||
kind: Namespace
|
||||
name: "{{ helm_namespace }}"
|
||||
state: absent
|
||||
@@ -17,8 +17,7 @@
|
||||
- name: Initial chart installation
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: redis
|
||||
chart_repo_url: https://charts.bitnami.com/bitnami
|
||||
chart_ref: oci://registry-1.docker.io/bitnamicharts/redis
|
||||
release_name: test-redis
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
create_namespace: true
|
||||
@@ -42,8 +41,7 @@
|
||||
- name: Upgrade chart using reuse_values=true
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: redis
|
||||
chart_repo_url: https://charts.bitnami.com/bitnami
|
||||
chart_ref: oci://registry-1.docker.io/bitnamicharts/redis
|
||||
release_name: test-redis
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
reuse_values: true
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
---
|
||||
- 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'
|
||||
|
||||
- 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"
|
||||
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"
|
||||
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
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
- name: Test helm skip_schema_validation
|
||||
vars:
|
||||
helm_namespace: "{{ test_namespace[14] }}"
|
||||
chart_release_values:
|
||||
replica:
|
||||
replicaCount: 3
|
||||
master:
|
||||
count: 1
|
||||
kind: Deployment
|
||||
block:
|
||||
- name: Chart installation
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: oci://registry-1.docker.io/bitnamicharts/redis
|
||||
release_name: test-redis
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
create_namespace: true
|
||||
release_values: "{{ chart_release_values }}"
|
||||
skip_schema_validation: true
|
||||
register: install
|
||||
ignore_errors: true
|
||||
|
||||
- name: Debug install result
|
||||
debug:
|
||||
var: install
|
||||
|
||||
- name: Validate skip_schema_validation with helm >= 3.16.0 works
|
||||
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:
|
||||
that:
|
||||
- install is failed
|
||||
- "'skip_schema_validation requires helm >= 3.16.0' in install.msg"
|
||||
when: "helm_version is ansible.builtin.version('v3.16.0', '<')"
|
||||
|
||||
always:
|
||||
- name: Remove helm namespace
|
||||
k8s:
|
||||
api_version: v1
|
||||
kind: Namespace
|
||||
name: "{{ helm_namespace }}"
|
||||
state: absent
|
||||
@@ -73,7 +73,7 @@
|
||||
assert:
|
||||
that:
|
||||
- install is changed
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- install.status.chart == chart_test+"-"+chart_test_version
|
||||
- install.status.status | lower == 'deployed'
|
||||
|
||||
- name: Check helm_info content
|
||||
@@ -95,7 +95,7 @@
|
||||
- name: "Assert that {{ chart_test }} is installed from {{ source }} with helm_info"
|
||||
assert:
|
||||
that:
|
||||
- content_info.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- content_info.status.chart == chart_test+"-"+chart_test_version
|
||||
- content_info.status.status | lower == 'deployed'
|
||||
- release_state_content_info.status.status | lower == 'deployed'
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
assert:
|
||||
that:
|
||||
- install is not changed
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- install.status.chart == chart_test+"-"+chart_test_version
|
||||
- install.status.status | lower == 'deployed'
|
||||
|
||||
- name: "Add vars to {{ chart_test }} from {{ source }}"
|
||||
@@ -130,7 +130,7 @@
|
||||
that:
|
||||
- install is changed
|
||||
- install.status.status | lower == 'deployed'
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- install.status.chart == chart_test+"-"+chart_test_version
|
||||
- "install.status['values'].revisionHistoryLimit == 0"
|
||||
|
||||
- name: Check idempotency after adding vars
|
||||
@@ -148,7 +148,7 @@
|
||||
that:
|
||||
- install is not changed
|
||||
- install.status.status | lower == 'deployed'
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- install.status.chart == chart_test+"-"+chart_test_version
|
||||
- "install.status['values'].revisionHistoryLimit == 0"
|
||||
|
||||
- name: "Remove Vars to {{ chart_test }} from {{ source }}"
|
||||
@@ -165,7 +165,7 @@
|
||||
that:
|
||||
- install is changed
|
||||
- install.status.status | lower == 'deployed'
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- install.status.chart == chart_test+"-"+chart_test_version
|
||||
- install.status['values'] == {}
|
||||
|
||||
- name: Check idempotency after removing vars
|
||||
@@ -182,7 +182,7 @@
|
||||
that:
|
||||
- install is not changed
|
||||
- install.status.status | lower == 'deployed'
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- install.status.chart == chart_test+"-"+chart_test_version
|
||||
- install.status['values'] == {}
|
||||
|
||||
- name: "Upgrade {{ chart_test }} from {{ source }}"
|
||||
@@ -199,7 +199,7 @@
|
||||
that:
|
||||
- install is changed
|
||||
- install.status.status | lower == 'deployed'
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version_upgrade }}"
|
||||
- install.status.chart == chart_test+"-"+chart_test_version_upgrade
|
||||
|
||||
- name: Check idempotency after upgrade
|
||||
helm:
|
||||
@@ -215,7 +215,7 @@
|
||||
that:
|
||||
- install is not changed
|
||||
- install.status.status | lower == 'deployed'
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version_upgrade }}"
|
||||
- install.status.chart == chart_test+"-"+chart_test_version_upgrade
|
||||
|
||||
- name: "Remove {{ chart_test }} from {{ source }}"
|
||||
helm:
|
||||
@@ -316,7 +316,7 @@
|
||||
that:
|
||||
- install is changed
|
||||
- install.status.status | lower == 'deployed'
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- install.status.chart == chart_test+"-"+chart_test_version
|
||||
- "install.status['values'].revisionHistoryLimit == 0"
|
||||
|
||||
- name: "Install {{ chart_test }} from {{ source }} with values_files (again)"
|
||||
@@ -357,7 +357,7 @@
|
||||
- result is changed
|
||||
- result is not failed
|
||||
- result.rc == 0
|
||||
- result.command is match("{{ helm_binary }} template {{ chart_source }}")
|
||||
- result.command is match(helm_binary+" template "+chart_source)
|
||||
|
||||
- name: Check templates created
|
||||
stat:
|
||||
@@ -374,8 +374,8 @@
|
||||
chart_ref: "{{ chart_source }}"
|
||||
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||
disable_hook: True
|
||||
release_name: "MyRelease"
|
||||
release_namespace: "MyReleaseNamespace"
|
||||
release_name: "myrelease"
|
||||
release_namespace: "myreleasenamespace"
|
||||
show_only:
|
||||
- "templates/configmap.yaml"
|
||||
release_values:
|
||||
@@ -388,7 +388,7 @@
|
||||
- result is changed
|
||||
- result is not failed
|
||||
- result.rc == 0
|
||||
- result.command is match("{{ helm_binary }} template MyRelease {{ chart_source }}")
|
||||
- result.command is match(helm_binary+" template myrelease "+chart_source)
|
||||
- result.stdout is search("ThisValue")
|
||||
when: chart_source is search("test-chart")
|
||||
# limit assertion of test result to controlled (local) chart_source
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: test-chart-deployment-time
|
||||
description: A chart with a config map containing the deployment time in data
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "default"
|
||||
@@ -0,0 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ default "ansible-configmap" .Values.myConfigmapName }}
|
||||
data:
|
||||
myValue: {{ default "test" .Values.myValue }}
|
||||
deploymentTime: {{ now }}
|
||||
@@ -0,0 +1,24 @@
|
||||
apiVersion: v2
|
||||
name: chart-reuse-values
|
||||
description: A Helm chart for Kubernetes
|
||||
|
||||
# A chart can be either an 'application' or a 'library' chart.
|
||||
#
|
||||
# Application charts are a collection of templates that can be packaged into versioned archives
|
||||
# to be deployed.
|
||||
#
|
||||
# Library charts provide useful utilities or functions for the chart developer. They're included as
|
||||
# a dependency of application charts to inject those utilities and functions into the rendering
|
||||
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
|
||||
type: application
|
||||
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: 0.1.0
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
# It is recommended to use it with quotes.
|
||||
appVersion: "1.16.0"
|
||||
@@ -0,0 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cmap
|
||||
data:
|
||||
ansible_version: {{ .Values.ansible_version }}
|
||||
phase: {{ .Values.phase }}
|
||||
@@ -0,0 +1,2 @@
|
||||
ansible_version: milestone
|
||||
phase: uat
|
||||
@@ -2,3 +2,4 @@
|
||||
dependencies:
|
||||
- remove_namespace
|
||||
- install_helm
|
||||
- setup_helm_registry
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
- name: Test helm diff functionality
|
||||
vars:
|
||||
test_chart_ref: "/tmp/test-chart"
|
||||
redis_chart_version: '17.0.5'
|
||||
|
||||
block:
|
||||
|
||||
@@ -11,7 +10,7 @@
|
||||
binary_path: "{{ helm_binary }}"
|
||||
state: present
|
||||
plugin_path: https://github.com/databus23/helm-diff
|
||||
plugin_version: 3.4.0
|
||||
plugin_version: 3.9.13
|
||||
|
||||
- name: Copy test chart
|
||||
copy:
|
||||
@@ -24,7 +23,7 @@
|
||||
name: test-chart
|
||||
namespace: "{{ helm_namespace }}"
|
||||
chart_ref: "{{ test_chart_ref }}"
|
||||
create_namespace: yes
|
||||
create_namespace: true
|
||||
register: install
|
||||
|
||||
- assert:
|
||||
@@ -49,8 +48,8 @@
|
||||
name: test-chart
|
||||
namespace: "{{ helm_namespace }}"
|
||||
chart_ref: "{{ test_chart_ref }}"
|
||||
check_mode: yes
|
||||
diff: yes
|
||||
check_mode: true
|
||||
diff: true
|
||||
register: diff_result
|
||||
|
||||
- name: Check if helm diff check is correct
|
||||
@@ -79,7 +78,7 @@
|
||||
namespace: "{{ helm_namespace }}"
|
||||
chart_ref: "{{ test_chart_ref }}"
|
||||
check_mode: yes
|
||||
diff: yes
|
||||
diff: true
|
||||
register: diff_result
|
||||
|
||||
- name: Check if no diff in check mode when no change
|
||||
@@ -101,7 +100,7 @@
|
||||
|
||||
- name: Modify values
|
||||
blockinfile:
|
||||
create: yes
|
||||
create: true
|
||||
path: "{{ test_chart_ref }}/values.yml"
|
||||
block: |
|
||||
---
|
||||
@@ -143,6 +142,8 @@
|
||||
chart_ref: "{{ test_chart_ref }}"
|
||||
values:
|
||||
foo: gaz
|
||||
values_files:
|
||||
- "{{ test_chart_ref }}/values.yml"
|
||||
register: install
|
||||
|
||||
- assert:
|
||||
@@ -157,6 +158,46 @@
|
||||
chart_ref: "{{ test_chart_ref }}"
|
||||
values:
|
||||
foo: gaz
|
||||
values_files:
|
||||
- "{{ test_chart_ref }}/values.yml"
|
||||
register: install
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- install is not changed
|
||||
|
||||
- name: Upgrade with set_values
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
name: test-chart
|
||||
namespace: "{{ helm_namespace }}"
|
||||
chart_ref: "{{ test_chart_ref }}"
|
||||
values:
|
||||
foo: gaz
|
||||
values_files:
|
||||
- "{{ test_chart_ref }}/values.yml"
|
||||
set_values:
|
||||
- value: foo=qux
|
||||
value_type: string
|
||||
register: install
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- install is changed
|
||||
|
||||
- name: Upgrade with set_values idempotency check
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
name: test-chart
|
||||
namespace: "{{ helm_namespace }}"
|
||||
chart_ref: "{{ test_chart_ref }}"
|
||||
values:
|
||||
foo: gaz
|
||||
values_files:
|
||||
- "{{ test_chart_ref }}/values.yml"
|
||||
set_values:
|
||||
- value: foo=qux
|
||||
value_type: string
|
||||
register: install
|
||||
|
||||
- assert:
|
||||
@@ -164,52 +205,76 @@
|
||||
- install is not changed
|
||||
|
||||
# Test helm diff with chart_repo_url
|
||||
- name: Define Redis chart values
|
||||
set_fact:
|
||||
redis_chart_values:
|
||||
commonLabels:
|
||||
phase: testing
|
||||
company: RedHat
|
||||
image:
|
||||
tag: 6.2.6-debian-10-r135
|
||||
architecture: standalone
|
||||
|
||||
- name: Install Redis chart
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_repo_url: https://charts.bitnami.com/bitnami
|
||||
chart_ref: redis
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: redis-chart
|
||||
chart_version: "{{ redis_chart_version }}"
|
||||
release_values: "{{ redis_chart_values }}"
|
||||
|
||||
- name: Upgrade Redis chart
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_repo_url: https://charts.bitnami.com/bitnami
|
||||
chart_ref: redis
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: redis-chart
|
||||
chart_version: "{{ redis_chart_version }}"
|
||||
release_values: "{{ redis_chart_values }}"
|
||||
check_mode: yes
|
||||
register: redis_upgrade
|
||||
|
||||
- name: Assert that module raised a warning
|
||||
assert:
|
||||
that:
|
||||
- not redis_upgrade.changed
|
||||
- redis_upgrade.warnings is defined
|
||||
- redis_upgrade.warnings | length == 1
|
||||
- redis_upgrade.warnings[0] == "The default idempotency check can fail to report changes in certain cases. Install helm diff >= 3.4.1 for better results."
|
||||
|
||||
- name: Uninstall helm diff
|
||||
helm_plugin:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
state: absent
|
||||
plugin_name: diff
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
|
||||
- name: Define chart variables
|
||||
set_fact:
|
||||
test_chart_values:
|
||||
myValue: 'Some ConfigMap data value'
|
||||
myConfigmapName: 'ansible-config-from-url'
|
||||
test_chart_version: 0.1.0
|
||||
test_chart_ref_url: "oci://localhost:6035/testing/test-chart-deployment-time"
|
||||
|
||||
- name: Deploy chart to remote registry
|
||||
block:
|
||||
- name: Create local directory to copy chart in
|
||||
ansible.builtin.tempfile:
|
||||
suffix: .chart
|
||||
state: directory
|
||||
register: _tmpd
|
||||
|
||||
- name: Copy local registry
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ _tmpd.path }}"
|
||||
src: '{{ role_path }}/files/test-chart-deployment-time'
|
||||
|
||||
- name: Push chart to helm registry
|
||||
ansible.builtin.include_role:
|
||||
name: push_to_helm_registry
|
||||
vars:
|
||||
chart_local_path: '{{ _tmpd.path }}/test-chart-deployment-time'
|
||||
chart_repo_path: 'testing'
|
||||
always:
|
||||
- name: Delete temporary directory
|
||||
ansible.builtin.file:
|
||||
state: absent
|
||||
path: '{{ _tmpd.path }}'
|
||||
|
||||
- name: Log into Helm registry
|
||||
ansible.builtin.command: "{{ helm_binary }} registry login -u testuser -p 'pass123!' localhost:6035"
|
||||
|
||||
- name: Install chart from remote URL
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "{{ test_chart_ref_url }}"
|
||||
chart_version: 0.1.0
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: another-chart
|
||||
release_values: "{{ test_chart_values }}"
|
||||
|
||||
- name: Upgrade chart
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "{{ test_chart_ref_url }}"
|
||||
chart_version: 0.1.0
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: another-chart
|
||||
release_values: "{{ test_chart_values }}"
|
||||
check_mode: true
|
||||
register: _upgrade
|
||||
|
||||
- name: Assert that module raised a warning
|
||||
assert:
|
||||
that:
|
||||
- not _upgrade.changed
|
||||
- _upgrade.warnings is defined
|
||||
- _upgrade.warnings | length == 1
|
||||
- _upgrade.warnings[0] == "The default idempotency check can fail to report changes in certain cases. Install helm diff >= 3.4.1 for better results."
|
||||
|
||||
- name: Install helm diff (version=3.4.1)
|
||||
helm_plugin:
|
||||
@@ -218,37 +283,36 @@
|
||||
plugin_path: https://github.com/databus23/helm-diff
|
||||
plugin_version: 3.4.1
|
||||
|
||||
- name: Upgrade Redis chart once again
|
||||
- name: Upgrade chart once again
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_repo_url: https://charts.bitnami.com/bitnami
|
||||
chart_ref: redis
|
||||
chart_ref: "{{ test_chart_ref_url }}"
|
||||
chart_version: 0.1.0
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: redis-chart
|
||||
chart_version: "{{ redis_chart_version }}"
|
||||
release_values: "{{ redis_chart_values }}"
|
||||
check_mode: yes
|
||||
register: redis_upgrade_2
|
||||
name: another-chart
|
||||
release_values: "{{ test_chart_values }}"
|
||||
check_mode: true
|
||||
register: _upgrade_2
|
||||
|
||||
- name: Assert that module raised a warning
|
||||
assert:
|
||||
that:
|
||||
- redis_upgrade_2.changed
|
||||
- redis_upgrade_2.warnings is not defined
|
||||
- _upgrade_2.changed
|
||||
- _upgrade_2.warnings is not defined
|
||||
|
||||
always:
|
||||
- name: Remove chart directory
|
||||
file:
|
||||
path: "{{ test_chart_ref }}"
|
||||
state: absent
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
|
||||
- name: Uninstall helm diff
|
||||
helm_plugin:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
state: absent
|
||||
plugin_name: diff
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
|
||||
- name: Remove helm namespace
|
||||
k8s:
|
||||
@@ -256,4 +320,9 @@
|
||||
kind: Namespace
|
||||
name: "{{ helm_namespace }}"
|
||||
state: absent
|
||||
ignore_errors: yes
|
||||
wait: true
|
||||
ignore_errors: true
|
||||
|
||||
- include_tasks: reuse_values.yml
|
||||
|
||||
- include_tasks: reset_then_reuse_values.yml
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
---
|
||||
- name: Create temporary directory for helm chart
|
||||
tempfile:
|
||||
suffix: .helm
|
||||
state: directory
|
||||
register: helm_dir
|
||||
|
||||
- name: Test helm diff functionality
|
||||
vars:
|
||||
test_chart_path: "{{ helm_dir.path }}/test-chart-reuse-values"
|
||||
test_release_name: "myrelease"
|
||||
|
||||
block:
|
||||
- name: Install helm diff
|
||||
kubernetes.core.helm_plugin:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
state: present
|
||||
plugin_path: https://github.com/databus23/helm-diff
|
||||
plugin_version: 3.9.14
|
||||
|
||||
- name: Copy test chart
|
||||
ansible.builtin.copy:
|
||||
src: "test-chart-reuse-values"
|
||||
dest: "{{ helm_dir.path }}"
|
||||
|
||||
- name: Delete existing namespace
|
||||
kubernetes.core.k8s:
|
||||
state: absent
|
||||
wait: true
|
||||
kind: Namespace
|
||||
name: "{{ helm_namespace }}"
|
||||
ignore_errors: true
|
||||
|
||||
- name: Create helm release
|
||||
kubernetes.core.helm:
|
||||
state: present
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "{{ test_chart_path }}"
|
||||
release_name: "{{ test_release_name }}"
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
create_namespace: true
|
||||
release_values:
|
||||
ansible_version: devel
|
||||
phase: ci
|
||||
wait: true
|
||||
|
||||
- name: Upgrade helm release (reset_values=false and reuse_values=false and reset_then_reuse_values=true)
|
||||
kubernetes.core.helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "{{ test_chart_path }}"
|
||||
reset_values: false
|
||||
reuse_values: false
|
||||
reset_then_reuse_values: true
|
||||
release_name: "{{ test_release_name }}"
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
values:
|
||||
ansible_version: devel
|
||||
register: helm_upgrade
|
||||
|
||||
- name: Ensure task did not reported change
|
||||
assert:
|
||||
that:
|
||||
- helm_upgrade is not changed
|
||||
|
||||
- name: Upgrade helm release (reset_then_reuse_values=true with default value for reset_values and reuse_values=false)
|
||||
kubernetes.core.helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "{{ test_chart_path }}"
|
||||
reuse_values: false
|
||||
reset_then_reuse_values: true
|
||||
release_name: "{{ test_release_name }}"
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
values:
|
||||
ansible_version: devel
|
||||
register: helm_upgrade
|
||||
|
||||
- name: Ensure task reported change
|
||||
assert:
|
||||
that:
|
||||
- helm_upgrade is changed
|
||||
|
||||
# Delete helm and helm diff to install older version
|
||||
- name: Uninstall helm diff
|
||||
helm_plugin:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
state: absent
|
||||
plugin_name: diff
|
||||
ignore_errors: true
|
||||
|
||||
- name: Delete Helm folders
|
||||
file:
|
||||
path: /tmp/helm/
|
||||
state: absent
|
||||
|
||||
- name: Init Helm folders
|
||||
file:
|
||||
path: /tmp/helm
|
||||
state: directory
|
||||
|
||||
- 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)
|
||||
kubernetes.core.helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "{{ test_chart_path }}"
|
||||
reuse_values: false
|
||||
reset_then_reuse_values: true
|
||||
release_name: "{{ test_release_name }}"
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
values:
|
||||
ansible_version: test
|
||||
register: helm_upgrade
|
||||
ignore_errors: true
|
||||
|
||||
- name: Debug
|
||||
debug:
|
||||
var: helm_upgrade
|
||||
|
||||
- name: Ensure warning for Helm version
|
||||
assert:
|
||||
that:
|
||||
- helm_upgrade is failed
|
||||
- '"reset_then_reuse_values requires helm >= 3.14.0, current version is" in helm_upgrade.msg'
|
||||
|
||||
- name: Install helm diff
|
||||
helm_plugin:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
state: present
|
||||
plugin_path: https://github.com/databus23/helm-diff
|
||||
plugin_version: "{{ helm_diff_old_version }}"
|
||||
|
||||
- name: Upgrade helm release (with reset_then_reuse_values=true)
|
||||
kubernetes.core.helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "{{ test_chart_path }}"
|
||||
reuse_values: false
|
||||
reset_then_reuse_values: true
|
||||
release_name: "{{ test_release_name }}"
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
values:
|
||||
ansible_version: devel
|
||||
register: helm_upgrade
|
||||
ignore_errors: true
|
||||
|
||||
- name: Debug
|
||||
debug:
|
||||
var: helm_upgrade
|
||||
|
||||
- name: Ensure warning for Helm Diff version
|
||||
assert:
|
||||
that:
|
||||
- helm_upgrade is failed
|
||||
- '"reset_then_reuse_values requires helm diff >= 3.9.12, current version is" in helm_upgrade.msg'
|
||||
|
||||
always:
|
||||
- name: Remove temporary directory
|
||||
file:
|
||||
path: "{{ helm_dir.path }}"
|
||||
state: absent
|
||||
ignore_errors: true
|
||||
|
||||
- name: Uninstall helm diff
|
||||
kubernetes.core.helm_plugin:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
state: absent
|
||||
plugin_name: diff
|
||||
ignore_errors: true
|
||||
|
||||
- name: Remove helm namespace
|
||||
kubernetes.core.k8s:
|
||||
api_version: v1
|
||||
kind: Namespace
|
||||
name: "{{ helm_namespace }}"
|
||||
state: absent
|
||||
wait: true
|
||||
ignore_errors: true
|
||||
94
tests/integration/targets/helm_diff/tasks/reuse_values.yml
Normal file
94
tests/integration/targets/helm_diff/tasks/reuse_values.yml
Normal file
@@ -0,0 +1,94 @@
|
||||
---
|
||||
- name: Create temporary directory for helm chart
|
||||
tempfile:
|
||||
suffix: .helm
|
||||
state: directory
|
||||
register: helm_dir
|
||||
|
||||
- name: Test helm diff functionality
|
||||
vars:
|
||||
test_chart_path: "{{ helm_dir.path }}/test-chart-reuse-values"
|
||||
test_release_name: "myrelease"
|
||||
|
||||
block:
|
||||
|
||||
- name: Install helm diff
|
||||
kubernetes.core.helm_plugin:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
state: present
|
||||
plugin_path: https://github.com/databus23/helm-diff
|
||||
plugin_version: 3.9.4
|
||||
|
||||
- name: Copy test chart
|
||||
ansible.builtin.copy:
|
||||
src: "test-chart-reuse-values"
|
||||
dest: "{{ helm_dir.path }}"
|
||||
|
||||
- name: Create helm release
|
||||
kubernetes.core.helm:
|
||||
state: present
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "{{ test_chart_path }}"
|
||||
release_name: "{{ test_release_name }}"
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
create_namespace: true
|
||||
release_values:
|
||||
ansible_version: devel
|
||||
phase: ci
|
||||
wait: true
|
||||
|
||||
- name: Upgrade helm release (reset_values=false and reuse_values=true)
|
||||
kubernetes.core.helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "{{ test_chart_path }}"
|
||||
reset_values: false
|
||||
reuse_values: true
|
||||
release_name: "{{ test_release_name }}"
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
values:
|
||||
ansible_version: devel
|
||||
register: helm_upgrade
|
||||
|
||||
- name: Ensure task did not reported change
|
||||
assert:
|
||||
that:
|
||||
- helm_upgrade is not changed
|
||||
|
||||
- name: Upgrade helm release (reuse_values=true with default value for reset_values)
|
||||
kubernetes.core.helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "{{ test_chart_path }}"
|
||||
reuse_values: true
|
||||
release_name: "{{ test_release_name }}"
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
values:
|
||||
ansible_version: devel
|
||||
register: helm_upgrade
|
||||
|
||||
- name: Ensure task reported change
|
||||
assert:
|
||||
that:
|
||||
- helm_upgrade is changed
|
||||
|
||||
always:
|
||||
- name: Remove temporary directory
|
||||
file:
|
||||
path: "{{ helm_dir.path }}"
|
||||
state: absent
|
||||
ignore_errors: true
|
||||
|
||||
- name: Uninstall helm diff
|
||||
kubernetes.core.helm_plugin:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
state: absent
|
||||
plugin_name: diff
|
||||
ignore_errors: true
|
||||
|
||||
- name: Remove helm namespace
|
||||
kubernetes.core.k8s:
|
||||
api_version: v1
|
||||
kind: Namespace
|
||||
name: "{{ helm_namespace }}"
|
||||
state: absent
|
||||
wait: true
|
||||
ignore_errors: true
|
||||
@@ -1,6 +1,10 @@
|
||||
---
|
||||
- name: Test helm with in-memory kubeconfig
|
||||
include_tasks: "from_in_memory_kubeconfig.yml"
|
||||
loop_control:
|
||||
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"
|
||||
@@ -8,12 +12,10 @@
|
||||
loop_var: test_helm_version
|
||||
with_items:
|
||||
- "v3.10.3"
|
||||
- "v3.8.2"
|
||||
|
||||
- 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.5.1"
|
||||
- "v3.4.2"
|
||||
- "v3.10.3"
|
||||
|
||||
@@ -18,7 +18,12 @@
|
||||
- set_fact:
|
||||
saved_kubeconfig_path: "{{ _dir.path }}/config"
|
||||
|
||||
- block:
|
||||
- vars:
|
||||
helm_repo_name: autoscaler
|
||||
helm_repo_url: "https://kubernetes.github.io/autoscaler"
|
||||
helm_release_name: "autoscaler"
|
||||
helm_chart_name: "cluster-autoscaler"
|
||||
block:
|
||||
- name: Copy default kubeconfig
|
||||
copy:
|
||||
remote_src: true
|
||||
@@ -59,14 +64,14 @@
|
||||
- plugin_info.plugin_list != []
|
||||
|
||||
# helm_repository, helm, helm_info
|
||||
- name: Add test_bitnami chart repository
|
||||
- name: 'Add "{{ helm_repo_name }}" chart repository'
|
||||
helm_repository:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
name: test_bitnami
|
||||
name: "{{ helm_repo_name }}"
|
||||
kubeconfig: "{{ test_kubeconfig | default(omit) }}"
|
||||
validate_certs: "{{ test_validate_certs | default(omit) }}"
|
||||
ca_cert: "{{ test_ca_cert | default(omit) }}"
|
||||
repo_url: https://charts.bitnami.com/bitnami
|
||||
repo_url: "{{ helm_repo_url }}"
|
||||
register: repository
|
||||
|
||||
- name: Assert that repository was added
|
||||
@@ -77,8 +82,8 @@
|
||||
- name: Install chart from repository added before
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
name: rabbitmq
|
||||
chart_ref: test_bitnami/rabbitmq
|
||||
name: "{{ helm_release_name }}"
|
||||
chart_ref: "{{ helm_repo_name }}/{{ helm_chart_name }}"
|
||||
namespace: "{{ helm_namespace }}"
|
||||
update_repo_cache: true
|
||||
kubeconfig: "{{ test_kubeconfig | default(omit) }}"
|
||||
@@ -98,7 +103,7 @@
|
||||
kubeconfig: "{{ test_kubeconfig | default(omit) }}"
|
||||
validate_certs: "{{ test_validate_certs | default(omit) }}"
|
||||
ca_cert: "{{ test_ca_cert | default(omit) }}"
|
||||
name: "rabbitmq"
|
||||
name: "{{ helm_release_name }}"
|
||||
namespace: "{{ helm_namespace }}"
|
||||
register: chart_info
|
||||
|
||||
@@ -112,7 +117,7 @@
|
||||
- name: Remove chart
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
name: rabbitmq
|
||||
name: "{{ helm_release_name }}"
|
||||
namespace: "{{ helm_namespace }}"
|
||||
kubeconfig: "{{ test_kubeconfig | default(omit) }}"
|
||||
validate_certs: "{{ test_validate_certs | default(omit) }}"
|
||||
@@ -131,7 +136,7 @@
|
||||
kubeconfig: "{{ test_kubeconfig | default(omit) }}"
|
||||
validate_certs: "{{ test_validate_certs | default(omit) }}"
|
||||
ca_cert: "{{ test_ca_cert | default(omit) }}"
|
||||
name: "rabbitmq"
|
||||
name: "{{ helm_release_name }}"
|
||||
namespace: "{{ helm_namespace }}"
|
||||
register: chart_info
|
||||
|
||||
@@ -143,7 +148,7 @@
|
||||
- name: Remove chart repository
|
||||
helm_repository:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
name: test_bitnami
|
||||
name: "{{ helm_repo_name }}"
|
||||
kubeconfig: "{{ test_kubeconfig | default(omit) }}"
|
||||
validate_certs: "{{ test_validate_certs | default(omit) }}"
|
||||
ca_cert: "{{ test_ca_cert | default(omit) }}"
|
||||
@@ -192,6 +197,6 @@
|
||||
- name: Delete helm repository
|
||||
helm_repository:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
name: test_bitnami
|
||||
name: "{{ helm_repo_name }}"
|
||||
state: absent
|
||||
ignore_errors: true
|
||||
|
||||
3
tests/integration/targets/helm_plain_http/aliases
Normal file
3
tests/integration/targets/helm_plain_http/aliases
Normal file
@@ -0,0 +1,3 @@
|
||||
helm_template
|
||||
helm_pull
|
||||
helm
|
||||
3
tests/integration/targets/helm_plain_http/inventory.ini
Normal file
3
tests/integration/targets/helm_plain_http/inventory.ini
Normal file
@@ -0,0 +1,3 @@
|
||||
[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
|
||||
@@ -0,0 +1,14 @@
|
||||
- name: Run test for helm plain http option
|
||||
hosts: all
|
||||
gather_facts: true
|
||||
|
||||
vars:
|
||||
ansible_connection: local
|
||||
ansible_python_interpreter: "{{ ansible_playbook_python }}"
|
||||
chart_test_oci: "oci://registry-1.docker.io/bitnamicharts/redis"
|
||||
|
||||
roles:
|
||||
- setup_namespace
|
||||
|
||||
tasks:
|
||||
- ansible.builtin.include_tasks: tasks/test.yaml
|
||||
@@ -0,0 +1,99 @@
|
||||
---
|
||||
- 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 }}"
|
||||
|
||||
- name: Set helm binary path
|
||||
ansible.builtin.set_fact:
|
||||
helm_binary: "{{ install_path.path }}/{{ ansible_system | lower }}-amd64/helm"
|
||||
|
||||
# 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
|
||||
4
tests/integration/targets/helm_plain_http/runme.sh
Executable file
4
tests/integration/targets/helm_plain_http/runme.sh
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eux
|
||||
export ANSIBLE_ROLES_PATH=../
|
||||
ansible-playbook playbooks/play.yaml -i inventory.ini "$@"
|
||||
@@ -180,6 +180,7 @@
|
||||
- '"--username ansible" in _result.command'
|
||||
- '"--password ***" in _result.command'
|
||||
- '"--keyring pubring.gpg" in _result.command'
|
||||
- '"Module did not set no_log for pass_credentials" not in _result.stderr'
|
||||
|
||||
- name: Download chart using chart_ref
|
||||
helm_pull:
|
||||
@@ -203,9 +204,8 @@
|
||||
- name: Download chart using untar_chart
|
||||
helm_pull:
|
||||
binary_path: "{{ helm_path }}"
|
||||
chart_ref: redis
|
||||
chart_ref: "oci://registry-1.docker.io/bitnamicharts/redis"
|
||||
destination: "{{ destination }}"
|
||||
repo_url: "https://charts.bitnami.com/bitnami"
|
||||
untar_chart: true
|
||||
register: _result
|
||||
|
||||
|
||||
2
tests/integration/targets/helm_registry_auth/aliases
Normal file
2
tests/integration/targets/helm_registry_auth/aliases
Normal file
@@ -0,0 +1,2 @@
|
||||
time=16
|
||||
helm_registry_auth
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
# Username and password for the registry
|
||||
# ../files/registry.password contains username and hashed password
|
||||
username: testuser
|
||||
password: testpassword
|
||||
wrong_password: 'WrongPassword'
|
||||
registry_name: oci_registry
|
||||
registry_port: 5000
|
||||
test_chart: https://github.com/grafana/helm-charts/releases/download/k8s-monitoring-1.6.8/k8s-monitoring-1.6.8.tgz
|
||||
@@ -0,0 +1 @@
|
||||
testuser:$2y$05$PmdUjSCJYdRUZlsYy8QGWuJDiwuHtWXa28YrELlN5haeHkZ1seZZG
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
dependencies:
|
||||
- install_helm
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user