Compare commits

...

117 Commits

Author SHA1 Message Date
patchback[bot]
2fb6546b03 docs: add until example to k8s_info (#885) (#1119)
I would liked to have an example like this when I was using the
documentation.

(cherry picked from commit 4d7dc2a7d1)

Co-authored-by: Birger Johan Nordølum <33870508+MindTooth@users.noreply.github.com>
2026-05-06 10:16:32 -04:00
patchback[bot]
ef9fb67688 Add kubeconfig module for managing Kubernetes config files (#1104) (#1122)
* Add kubeconfig module for managing Kubernetes config files

* Remove unnecessary requirement & Change version

* Move functions to module_utils

* Add unit tests

* Add kubeconfig module for managing Kubernetes config files

* Remove unnecessary requirement & Change version

* Move functions to module_utils

* Add unit tests

* Avoid linter errors

* Improve documentation clarity

* Redact sensitive kubeconfig information

* Imprvoe verbosity

* Move import statement for to_native to avoid linters check failure

* Fix linting error

---------


(cherry picked from commit e79ed52a4d)

Co-authored-by: Youssef Ali <154611350+YoussefKhalidAli@users.noreply.github.com>
Co-authored-by: Bianca Henderson <bianca@redhat.com>
2026-05-06 10:15:42 -04:00
Bianca Henderson
90bc4c4b3b Release prep for 6.4.0 (#1101)
SUMMARY

Prep kubernetes.core 6.4.0 release

COMPONENT NAME

Multiple

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
Reviewed-by: Yuriy Novostavskiy <yuriy@novostavskiy.kyiv.ua>
Reviewed-by: Bikouo Aubin
Reviewed-by: Hannah DeFazio <h2defazio@gmail.com>
2026-04-22 21:04:10 +00:00
patchback[bot]
1590c6a4cc Update URL reference in integration-test CI file (#1112) (#1114)
(cherry picked from commit 210467b26d)

Co-authored-by: Bianca Henderson <bianca@redhat.com>
2026-04-22 14:14:06 -04:00
patchback[bot]
76eccacab6 ci: conditionally test turbo mode and cloud.common (#1109) (#1111)
The cloud.common collection is incompatible with ansible-core >= 2.19.0.
With the current testing matrix using Python 3.12 and the ansible
milestone (currently 2.22), this incompatibility causes integration
tests to fail.

Instead of completely removing turbo mode from the testing matrix, this
commit adds ansible-core 2.18 to the matrix and excludes the combination
of the ansible milestone and turbo mode. The checkout and installation
of the cloud.common collection are now conditionally executed only when
turbo mode is enabled.

(cherry picked from commit 11f619b69e)

Co-authored-by: Yuriy Novostavskiy <yuriy@novostavskiy.kiev.ua>
2026-04-21 14:37:48 -04:00
patchback[bot]
620abbac26 trivial(doc): post #1090 cosmetic update (#1097) (#1107)
SUMMARY
Name of the Helm plays in the integration test framework test updated to reflect the actual version of Helm (addressed comments #1090 (review))
Updated documentation for the modules updated in the PR with the https://github.com/ansible-network/collection_prep, as per CONTRIBUTING.md
ISSUE TYPE

Docs Pull Request

COMPONENT NAME

tests/integration/targets/helm_v3_*/play.yaml
docs/kubernetes.core.helm*.rst

ADDITIONAL INFORMATION
Only cosmetic changes in this PR, so the label skip-changelog is suggested

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
(cherry picked from commit 16e92a20e8)

Co-authored-by: Yuriy Novostavskiy <yuriy@novostavskiy.kyiv.ua>
2026-04-21 11:31:11 +02:00
patchback[bot]
66a820e03a Add sanity test ignores for ansible-core 2.22 (#1102) (#1106)
The `devel` and `milestone` branches for ansible-core have been bumped to
`2.22.0.dev0` as the `stable-2.21` branch was created. Testing against `devel`
and `milestone` now uses 2.22, which requires creation of the
`tests/sanity/ignore-2.22.txt` file in all maintained collection branches.

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch ignore-2.22
# Changes to be committed:
#	new file:   tests/sanity/ignore-2.22.txt
#

(cherry picked from commit 58f8f2e6e9)

Co-authored-by: Yuriy Novostavskiy <yuriy@novostavskiy.kiev.ua>
2026-04-20 18:34:35 -04:00
patchback[bot]
a3f2438e9d Ensure compatibility with Helm v4 for the collection (#1090) (#1096)
This is a backport of PR #1090 as merged into main (e6076e5).
SUMMARY

Ensure compatibility with Helm v4 for modules helm_plugin and helm_plugin_info
Partially addresses #1038

ISSUE TYPE


Feature Pull Request

COMPONENT NAME

helm_plugin
helm_plugin_info
helm_info
helm_pull
helm_registry_auth
helm
helm_template

Reviewed-by: Bikouo Aubin
Reviewed-by: Matthew Johnson
2026-03-17 15:03:02 +00:00
patchback[bot]
0709ea31c9 Support take_ownership parameter in helm installation (#1034) (#1092)
This is a backport of PR #1034 as merged into main (42acb4f).
SUMMARY
Adds support for the take_ownership for initial release installation operations.
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
plugins/modules/helm.py
ADDITIONAL INFORMATION
I recently had to migrate a namespace k8s from flat manifest installation into helm a release.
I was so glad to see the take_ownership feature but realized that it work only after first installation of the release.
Seeing no reason to denied this use case i suggest this very simple changes.
To reproduce it:

Create a new namespace in any cluster.
Create a secret
Install any helm chart that deploy the same secret using take_ownership: true.
2026-02-19 16:40:12 +00:00
patchback[bot]
44ab1fc478 Add check_mode support for k8s_drain module (#1086) (#1091)
This is a backport of PR #1086 as merged into main (d239adb).
SUMMARY

Closes #1037

added support for check_mode
Converted warnings into informational display when user has explicitly requested to delete daemontset-managed pods, unmanaged pods or pods with local storage


ISSUE TYPE


Feature Pull Request

COMPONENT NAME

k8s_drain

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2026-02-16 20:35:22 +00:00
Bianca Henderson
80c33c5573 Prep 6.3.0 release (#1084)
SUMMARY

Prep kubernetes.core 6.3.0 release

COMPONENT NAME

Multiple

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
Reviewed-by: Bikouo Aubin
Reviewed-by: Mike Graves <mgraves@redhat.com>
Reviewed-by: Alina Buzachis
Reviewed-by: Yuriy Novostavskiy <yuriy@novostavskiy.kyiv.ua>
Reviewed-by: Rahmanim Benny <brahmani@redhat.com>
2026-02-03 17:03:41 +00:00
patchback[bot]
73dc94be68 Add idempotency to helm_pull module (#1055) (#1080)
This is a backport of PR #1055 as merged into main (34beacf).
SUMMARY
This PR implements idempotency for the helm_pull module, addressing issue #889.

New force parameter with defaults to False.
implemented chart_exists() function
checks chart existence before downloading, returns changed=False when chart exists

ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
helm_pull
ADDITIONAL INFORMATION
Force parameter added for backward compatibility and edge cases.
Implemented with the partial support of GitHub Copilot with Claude Sonnet 4.5 model

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2026-01-29 18:22:52 +00:00
patchback[bot]
1bc65230bb Fix incorrect assertion in helm_pull integration test (#1077) (#1079)
This is a backport of PR #1077 as merged into main (23b6cec).
SUMMARY

The error message emitted for incorrect helm version has changed since the merge of #1039. This PR updates the related assertion in the helm_pull integration test

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2026-01-29 17:44:05 +00:00
patchback[bot]
91427a5b6a chore(CI): prevent patchback bot from labeling new PRs (#1062) (#1064)
This is a backport of PR #1062 as merged into main (987c029).
SUMMARY
Currently, the patchback bot creates PRs with cherry-picks of PRs that are labeled with stable-* label, and this PR (as any new PR) gets labeled as needs_triage. This is unnecessary as it intentional PR created by the CI job.
This pull request introduces a small update to ensure that the workflow only runs if the pull request is not created by the patchback[bot] user to avoid unnecessary labels.
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
.github/workflows/label-new-prs.yaml
ADDITIONAL INFORMATION
No changelog is required 

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2026-01-29 16:00:40 +00:00
patchback[bot]
1d1a23b1ab Replace passing `warnings to exit_json with AnsibleModule.warn` for the few modules (#1033) (#1073)
This is a backport of PR #1033 as merged into main (3e32c12).
SUMMARY
Using exit_json or fail_json for warnings is deprecated in ansible-core>=2.19.0 and will be removed in ansible-core>=2.23.0
Tested with ansible-core 2.19.3 as the latest released version at the time of the start of this PR and with 2.16.0 as the lowest version supported by kubernetes.core 6.x
Resolves: #1031
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
k8s_drain
k8s_rollback
k8s_scale
ADDITIONAL INFORMATION
The initial version of this PR covers only the module k8s_drain, with the following commits extended to k8s_rollback
k8s_scale

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
Reviewed-by: Mike Graves <mgraves@redhat.com>
2026-01-26 21:14:44 +00:00
patchback[bot]
6edc84678d Limit compatibility to Helm =>v3.0.0,<4.0.0 (#1039) (#1071)
This is a backport of PR #1039 as merged into main (13791ec).
SUMMARY
Helm v4 is a major version with backward-incompatible changes, including to the flags and output of the Helm CLI and to the SDK. This version is currently not supported in the kubernetes.core. This PR is related to #1038 and is a short-term solution to mark compatibility explicitly
ISSUE TYPE

Bugfix Pull Request
Docs Pull Request

COMPONENT NAME

helm
helm_template
helm_info
helm_repository
helm_pull
helm_registry_auth
helm_plugin
helm_plugin_info

ADDITIONAL INFORMATION
Added `validate_helm_version()`` method to AnsibleHelmModule that enforces version constraint >=3.0.0,<4.0.0.
Fails fast with clear error message: "Helm version must be >=3.0.0,<4.0.0, current version is {version}"
Some modules (i.e. helm_registry_auth) technically is compatible with Helm v4, but validation was added to all helm modules.
Partially coauthored by GitHub Copilot with Claude Sonnet 4 model.
Addresses issue #1038

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
Reviewed-by: Mike Graves <mgraves@redhat.com>
2026-01-26 19:47:46 +00:00
patchback[bot]
66bd8620e4 Replace deprecated ansible.module_utils._text imports (#1053) (#1070)
This is a backport of PR #1053 as merged into main (452fb3d).
SUMMARY
Importing from ansible.module_utils._text is deprecated in ansible-core 2.20 and removed in 2.24. All imports of to_bytes, to_native, and to_text now use ansible.module_utils.common.text.converters.
Before:
from ansible.module_utils._text import to_bytes, to_native, to_text

After:
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text

ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
plugins/module_utils/common.py
plugins/action/k8s_info.py
plugins/connection/kubectl.py
plugins/module_utils/{copy.py, k8s/runner.py}
plugins/modules/{k8s_cp.py, k8s_drain.py, k8s_exec.py, k8s_json_patch.py, k8s_scale.py, k8s_taint.py}
ADDITIONAL INFORMATION
It's not an actual Bugfix, more a lifecycle management to ensure compatibility with future Ansible versions.
Tested with ansible-core 2.20 to ensure no deprecation warnings are raised and with ansible-core 2.16 to ensure backward compatibility.
Patrially coauthored-by: GitHub Copilot with Claude Code 4.5 model.
Addresses issue #1052.

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2026-01-26 15:22:45 +00:00
patchback[bot]
94b43dc582 Fix K8S_AUTH_VERIFY_SSL environment value handling in kubectl connection plugin (#1049) (#1069)
This is a backport of PR #1049 as merged into main (12abc9b).
SUMMARY
Fixed a bug where setting K8S_AUTH_VERIFY_SSL=true (or any string value) caused the value to be treated as a separate kubectl command argument instead of being properly converted to a boolean.
The option key name is validate_certs, which does NOT end with "verify_ssl", so the original condition key.endswith("verify_ssl") at line 327 failed. This caused the code to fall through to the else block which added the value as separate
arguments: ["--insecure-skip-tls-verify", "true"], making "true" appear as a kubectl command.
Fixes #1021
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
kubernetes.core.kubectl
ADDITIONAL INFORMATION
Changes Made

Changed condition from key.endswith("verify_ssl") to key == "validate_certs"
Added import of boolean function from ansible.module_utils.parsing.convert_bool
Added proper boolean conversion using boolean(self.get_option(key), strict=False)

Partially used LLM (GitHub Copilot with Claude Sonnet 4).
Before Fix
K8S_AUTH_VERIFY_SSL=true
Command: ['/usr/bin/kubectl', '--insecure-skip-tls-verify', 'true', 'exec', ...]

                                                            ^^^^^ treated as kubectl command (BUG!)

After Fix
K8S_AUTH_VERIFY_SSL=true
Command: ['/usr/bin/kubectl', '--insecure-skip-tls-verify=false', 'exec', ...]
                                                           ^^^^^ properly converted (FIXED!)

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2026-01-23 20:24:44 +00:00
patchback[bot]
3c4f9cee60 chore(doc): update typos (#1059) (#1061)
This is a backport of PR #1059 as merged into main (6c00f7c).
SUMMARY
This trivial documentation-only pull request correcting a few errors in README.md.

Documentation corrections:

Fixed a broken Markdown link for the GitHub repository in the support request section.
Corrected the reference from LICENCE to LICENSE to match the actual file name.



ISSUE TYPE

Docs Pull Request

COMPONENT NAME
README.md
ADDITIONAL INFORMATION
Trivial documentation-only change, no changelog is required.

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2026-01-15 21:30:22 +00:00
patchback[bot]
a54b4a13b6 address sanity issues (#1056) (#1058)
This is a backport of PR #1056 as merged into main (bd1cacc).
SUMMARY


helm/helm_info - Deprecate some parameters and add new ones to resolve sanity issues.
k8s - the return block doc is not aligned with what the module returns


ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

helm, helm_info, k8s
Fixes: #1046

Reviewed-by: Bikouo Aubin
Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2026-01-14 17:08:35 +00:00
patchback[bot]
e16b3c46b0 Add new workflow to label prs with needs_triage (#1045) (#1048)
This is a backport of PR #1045 as merged into main (9cfa903).
SUMMARY
This pr adds a new workflow for labeling new and reopened prs that are not marked as draft. The needs_triage label will be removed if the pr is marked as draft during development and re-added once the pr is marked as ready for review.
After consulting with the team, we decided to label prs in a new workflow to allow for the prs and issues to have different labels in the future.
ACA-2362
ISSUE TYPE

Feature Pull Request

COMPONENT NAME
github workflow
Reported CI Issues
Sanity tests: #1046

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-12-18 14:29:05 +00:00
patchback[bot]
bc60523372 Add 2.21 ignore file for sanity tests (#1032) (#1036)
SUMMARY

Resolves #1027

Reviewed-by: Yuriy Novostavskiy <yuriy@novostavskiy.kyiv.ua>
Reviewed-by: GomathiselviS <gomathiselvi@gmail.com>
(cherry picked from commit 1c16a2d2b5)

Co-authored-by: Bianca Henderson <bianca@redhat.com>
2025-10-24 09:28:46 -04:00
patchback[bot]
64f3f07c5a Extend k8s action group (#992) (#1026)
This is a backport of PR #992 as merged into main (798f549).
SUMMARY


Add all k8s_* modules to the action group in order to esaily set kubeconfig parameter
ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

meta
ADDITIONAL INFORMATION

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-10-14 20:47:03 +00:00
patchback[bot]
d6492b66d9 Selectively redact sensitive kubeconfig data from logs (#1014) (#1024)
This is a backport of PR #1014 as merged into main (4fa3648).
SUMMARY

Resolves #782

ISSUE TYPE


Bugfix Pull Request

ADDITIONAL INFORMATION


The proper redaction of kubeconfig data can be seen by running this example playbook with verbosity of -vvv against the code in this PR.
Prior to these changes, all info was redacted (as shown in the example below):
ok: [local] => {
    "changed": false,
    "invocation": {
        "module_args": {
            "api_key": null,
            "binary_path": null,
            "ca_cert": null,
            "context": null,
            "get_all_values": false,
            "host": null,
            "kubeconfig": {
                "apiVersion": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                "clusters": [
                    {
                        "cluster": {
                            "insecure-skip-tls-verify": true,
                            "server": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
                        },
                        "name": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
                    },
                    {
                        "cluster": {
                            "certificate-authority-data": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                            "server": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
                        },
                        "name": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
                    },
                    {
                        "cluster": {
                            "certificate-authority": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                            "extensions": [
                                {
                                    "extension": {
                                        "last-update": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                                        "provider": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                                        "version": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
                                    },
                                    "name": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
                                }
                            ],
                            "server": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
                        },
                        "name": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
                    }
                ],
                "contexts": [
                    {
                        "context": {
                            "cluster": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                            "user": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
                        },
                        "name": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
                    },
                    {
                        "context": {
                            "cluster": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                            "user": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
                        },
                        "name": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER"
                    },
[output shortened]

With the changes in this PR, only sensitive data is redacted:
ok: [local] => {
    "changed": false,
    "invocation": {
        "module_args": {
            "api_key": null,
            "binary_path": null,
            "ca_cert": null,
            "context": null,
            "get_all_values": false,
            "host": null,
            "kubeconfig": {
                "apiVersion": "v1",
                "clusters": [
                    {
                        "cluster": {
                            "insecure-skip-tls-verify": true,
                            "server": "<server address>"
                        },
                        "name": "exercise"
                    },
                    {
                        "cluster": {
                            "certificate-authority-data": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
                            "server": "<server address>"
                        },
                        "name": "kind-drain-test"
                    },
                    {
                        "cluster": {
                            "certificate-authority": "<path to .crt>",
                            "extensions": [
                                {
                                    "extension": {
                                        "last-update": "Tue, 07 Oct 2025 11:25:54 EDT",
                                        "provider": "minikube.sigs.k8s.io",
                                        "version": "v1.35.0"
                                    },
                                    "name": "cluster_info"
                                }
                            ],
                            "server": "<server address>"
                        },
                        "name": "minikube"
                    }
                ],
                "contexts": [
                    {
                        "context": {
                            "cluster": "exercise-pod",
                            "user": "bianca"
                        },
                        "name": "exercise"
                    },
                    {
                        "context": {
                            "cluster": "kind-drain-test",
                            "user": "kind-drain-test"
                        },
                        "name": "kind-drain-test"
                    },
[output shortened]

Reviewed-by: GomathiselviS <gomathiselvi@gmail.com>
2025-10-14 19:16:05 +00:00
patchback[bot]
4d5388ddf8 775 document proxy configurations (#1018) (#1020)
This is a backport of PR #1018 as merged into main (ae624cf).
SUMMARY
Added documentation for no_proxy, proxy, and proxy_headers parameters that were missing from the k8s lookup plugin. These parameters are already implemented in the codebase but were not documented.
no_proxy: Comma separated list of hosts that shouldn't use proxy
proxy: HTTP proxy URL for connections
proxy_headers: Dictionary of proxy headers with suboptions for proxy_basic_auth, basic_auth, and user_agent
Fixes #775
ISSUE TYPE

Docs Pull Request

COMPONENT NAME
k8s lookup
Additional comment
This is a reissue of #993, which was lost during the latest release due to me PR incorrectly from my fork's main branch. Linter errors on the previous PR should already be resolved.
This had the backport-5, backport-6 and skip-changelog labels.

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-10-10 17:30:10 +00:00
Bianca Henderson
6dadd06252 Add missing changelog fragments from 5.4.0 and 5.4.1 releases (#1015)
Reviewed-by: Mandar Kulkarni <mandar242@gmail.com>
Reviewed-by: Yuriy Novostavskiy <yuriy@novostavskiy.kyiv.ua>
2025-10-07 20:38:26 +00:00
Bianca Henderson
69dc7d5c5d Prep 6.2.0 release (#1011)
SUMMARY

Prep kubernetes.core 6.2.0 release

COMPONENT NAME
Multiple

Reviewed-by: Bikouo Aubin
Reviewed-by: Yuriy Novostavskiy <yuriy@novostavskiy.kyiv.ua>
Reviewed-by: Alina Buzachis
Reviewed-by: Bianca Henderson <beeankha@gmail.com>
Reviewed-by: Mandar Kulkarni <mandar242@gmail.com>
2025-10-07 18:18:54 +00:00
patchback[bot]
2fa1c2c6e5 Add support of local environment variables in kustomize lookup plugin (#786) (#1010)
This is a backport of PR #786 as merged into main (87344b9).
SUMMARY
kustomize doesn't support an environment that makes it impossible to use HTTP_PROXY or provide some templatized parameters.
This PR is the result of the issue #783
ISSUE TYPE

Feature Pull Request

COMPONENT NAME
kubernetes.core.kustomize lookup plugin

Reviewed-by: Bikouo Aubin
Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-10-03 14:34:41 +00:00
patchback[bot]
f2623dd3cf update doc following #971 (#1006) (#1008)
This is a backport of PR #1006 as merged into main (200d64f).
SUMMARY
In the PR #971, support for copying files to initContainers, and this change includes a minor update for DOCUMENTATION for the k8s_cp module; however, docs/kubernetes.core.k8s_cp_module.rst wasn't updated, and it's a trivial change following the Updating documentation section of the CONTRIBUTING.md
ISSUE TYPE

Docs Pull Request

COMPONENT NAME
docs/kubernetes.core.k8s_cp_module.rst
ADDITIONAL INFORMATION
As it is a trivial change and related to #971, I didn't created a chnagelog fragment and suggest adding skip-changelog label.
To be backported to stable-5 and stable-6

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-10-02 20:11:20 +00:00
patchback[bot]
8772d8c997 Add the PR head as reference to the checkout action of the splitter job. (#981) (#1005)
This is a backport of PR #981 as merged into main (ec35c74).
SUMMARY
During the workflow checks of one of my previous pull requests, I ran into an error as result of a new integration test that was added in the main branch but which was not present in my pull request (https://github.com/ansible-collections/kubernetes.core/actions/runs/16787189478/job/47540604109). I'd find out that the reference for the repository checkout for the splitter job was not set and therefor it referenced to the main branch.
With this change, the head of the pull request is used as reference for the repository checkout action, in the splitter job. This way it will not fail when someone creates a PR that doesn't have newly added integration tests that were added to the main branch in the meantime. It also adds that newly added integration tests will be tested during the PR workflow checks already.
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
bugfix in the workflow
ADDITIONAL INFORMATION
n/a

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-10-02 19:12:05 +00:00
patchback[bot]
a32108f64f Added support for copying files to init Containers. (#971) (#1003)
This is a backport of PR #971 as merged into main (027700c).
SUMMARY
Was going trough the list with issues and found 958; which seemed a quick fix.
What I fixed with with this PR:

Added support for copying files to init containers.
Fixed the format message when an exec is failing for a pod (the order was wrong).
Added a check if the container that you try to run copy for is started.

ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
copy.py module
ADDITIONAL INFORMATION
Some testing.
Verify that the pod does not exist:
kubectl -n default get pod/yorick
Output:
Error from server (NotFound): pods "yorick" not found

Run the playbook to create the file, create the deployment, wait for the init container to be ready, copy the created file to the init container, cat the copied file (using kubernetes.core.k8s_exec) that is now in the init container and try to copy the created file to the (not started) container (which fails - to see the new error message for it):
cat << EOF | ansible-playbook /dev/stdin
- hosts: localhost
  gather_facts: False
  tasks:

  - ansible.builtin.copy:
      content: |
        Hi there
      dest: /tmp/yorick.txt

  - name: Deploy pod with initContainer with an unlimited while loop
    kubernetes.core.k8s:
      kubeconfig: "~/.kube/config"
      definition:
        apiVersion: v1
        kind: Pod
        metadata:
          name: "yorick"
          namespace: "default"
        spec:
          initContainers:
            - name: "yorick-init"
              image: busybox:latest
              command: ["/bin/sh"]
              args:
                - "-c"
                - |
                  echo "Init container started, waiting for file..."
                  # Wait for the file to be copied
                  while :;do
                    echo "Waiting for file"
                    sleep 5
                  done
                  echo "File received! Init container completing..."
          containers:
            - name: "yorick-container"
              image: busybox:latest
              command: ["/bin/sh"]
              args:
                - "-c"
                - |
                  # Keep container running for testing
                  sleep 300

  - kubernetes.core.k8s_info:
      kubeconfig: "~/.kube/config"
      api_version: v1
      kind: Pod
      name: "yorick"
      namespace: "default"
    register: pod_status
    until: >-
      pod_status.resources|length > 0
      and 'initContainerStatuses' in pod_status.resources.0.status
      and pod_status.resources.0.status.initContainerStatuses|length > 0
      and pod_status.resources.0.status.initContainerStatuses.0.started|bool

  - name: Copy /tmp/yorick.txt to the yorick-init init container
    kubernetes.core.k8s_cp:
      kubeconfig: "~/.kube/config"
      namespace: default
      pod: yorick
      remote_path: /tmp/yorick.txt
      local_path: /tmp/yorick.txt
      container: yorick-init

  - name: Execute a command
    kubernetes.core.k8s_exec:
      kubeconfig: "~/.kube/config"
      namespace: default
      pod: yorick
      container: yorick-init
      command: cat /tmp/yorick.txt
    register: exec_out

  - ansible.builtin.debug:
      var: exec_out.stdout

  - name: Try to copy /tmp/yorick.txt to the yorick-container container
    kubernetes.core.k8s_cp:
      kubeconfig: "~/.kube/config"
      namespace: default
      pod: yorick
      remote_path: /tmp/yorick.txt
      local_path: /tmp/yorick.txt
      container: yorick-container
EOF
Output:
PLAY [localhost] ********************************************************************************************************************************************************************

TASK [ansible.builtin.copy] *********************************************************************************************************************************************************
Thursday 31 July 2025  02:01:21 +0200 (0:00:00.016)       0:00:00.016 *********
ok: [localhost]

TASK [Deploy pod with initContainer with an unlimited while loop] *******************************************************************************************************************
Thursday 31 July 2025  02:01:21 +0200 (0:00:00.788)       0:00:00.804 *********
changed: [localhost]

TASK [kubernetes.core.k8s_info] *****************************************************************************************************************************************************
Thursday 31 July 2025  02:01:25 +0200 (0:00:03.963)       0:00:04.768 *********
FAILED - RETRYING: [localhost]: kubernetes.core.k8s_info (3 retries left).
ok: [localhost]

TASK [Copy /tmp/yorick.txt to the yorick-init init container] ***********************************************************************************************************************
Thursday 31 July 2025  02:01:32 +0200 (0:00:06.598)       0:00:11.366 *********
changed: [localhost]

TASK [Execute a command] ************************************************************************************************************************************************************
Thursday 31 July 2025  02:01:39 +0200 (0:00:07.017)       0:00:18.383 *********
changed: [localhost]

TASK [ansible.builtin.debug] ********************************************************************************************************************************************************
Thursday 31 July 2025  02:01:40 +0200 (0:00:00.644)       0:00:19.028 *********
ok: [localhost] => {
    "exec_out.stdout": "Hi there\n"
}

TASK [Try to copy /tmp/yorick.txt to the yorick-container container] ****************************************************************************************************************
Thursday 31 July 2025  02:01:40 +0200 (0:00:00.021)       0:00:19.050 *********
fatal: [localhost]: FAILED! => {
    "changed": false
}

MSG:

Pod container yorick-container is not started

PLAY RECAP **************************************************************************************************************************************************************************
localhost                  : ok=6    changed=3    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

Playbook run took 0 days, 0 hours, 0 minutes, 21 seconds

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-09-25 15:07:52 +00:00
patchback[bot]
365e5e9159 Add support for skip-schema-validation in helm module (#995) (#1001)
This is a backport of PR #995 as merged into main (da93cce).
SUMMARY
This pull request adds support for a new skip_schema_validation option to the helm module, allowing users to disable JSON schema validation for Helm charts and values (requires helm >= 3.16.0).
ISSUE TYPE

Feature Pull Request

COMPONENT NAME
helm
ADDITIONAL INFORMATION
Added the skip_schema_validation boolean parameter to the helm module, allowing users to disable JSON schema validation for charts and values. This option is only available with Helm versions >= 3.16.0, and an appropriate error is raised for older versions.
Added integration tests to verify the behavior of the skip_schema_validation option, including cases for both supported and unsupported Helm versions.
Closes #994

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-09-24 20:29:07 +00:00
patchback[bot]
448a68da3d Changelog fixes (#989) (#990)
This is a backport of PR #989 as merged into main (6158300).
SUMMARY

Changelog fixes

ISSUE TYPE


Docs Pull Request

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
Reviewed-by: Chyna Sanders
2025-09-22 20:14:29 +00:00
patchback[bot]
46acab9c4c [CI Fix] Remove ansible.module_utils.six imports (#998) (#1000)
This is a backport of PR #998 as merged into main (448d3fe).
SUMMARY
This PR is essentially attempting Option B from issue #996 (Option A is implemented here); this code update accounts for the recent merge of sanity: warn on ansible.module_utils.six imports #85651.

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
Reviewed-by: Mandar Kulkarni <mandar242@gmail.com>
2025-09-22 16:49:02 +00:00
Bianca Henderson
fdb77182c8 Update/correct stable-6 changelog (#987)
SUMMARY
A part of the changelog referring to reverted changes was left in; this PR updates the changelog files to accurately reflect the state of stable-6/6.1.0 release.

Reviewed-by: Yuriy Novostavskiy
Reviewed-by: Alina Buzachis
2025-08-13 08:34:52 +00:00
Alina Buzachis
fa3d94f793 Prep kubernetes.core 6.1.0 (#977)
SUMMARY


ISSUE TYPE


Bugfix Pull Request
Docs Pull Request
Feature Pull Request
New Module Pull Request

COMPONENT NAME

ADDITIONAL INFORMATION

Reviewed-by: Yuriy Novostavskiy
Reviewed-by: Bianca Henderson <beeankha@gmail.com>
Reviewed-by: GomathiselviS <gomathiselvi@gmail.com>
2025-08-12 18:25:31 +00:00
patchback[bot]
9ec27cf37c CI fix for 976 (#982) (#985)
This is a backport of PR #982 as merged into main (a861079).
SUMMARY
Exclude plugins/connection/kubectl.py from ansible-lint, as this file contains only examples that is simplificated and may not be accordingally to linter rules.
resolves #976
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
CI
ADDITIONAL INFORMATION

Reviewed-by: Alina Buzachis
Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-08-12 15:59:34 +00:00
Bianca Henderson
10cb241256 Reapply "Remove kubeconfig value from module invocation log (#826)" (#899) (#966) (#979)
This reverts commit 1d962fb from stable-6 (i.e., reapplies the changes from #966); this is a temporary fix for #782 as it will re-introduce #870.

Reviewed-by: Alina Buzachis
Reviewed-by: GomathiselviS <gomathiselvi@gmail.com>
2025-08-11 16:48:04 +00:00
patchback[bot]
92e1f581fe fix(k8s,service): Hide fields first before creating diffs (#915) (#963)
This is a backport of PR #915 as merged into main (6a0635a).
SUMMARY

By hiding fields first before creating a diff hidden fields will not be shown in the resulting diffs and therefore will also not trigger the changed condition.
The issue can only be reproduced when a mutating webhook changes the object while the kubernetes.core.k8s module is working with it.

kubevirt/kubevirt.core#145
ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

kubernetes.core.module_utils.k8s.service
ADDITIONAL INFORMATION


Run kubernetes.core.k8s and create object with hidden fields. After run kubernetes.core.k8s again and let a webhook mutate the object that the module is working with. The module should return with changed: no.

Reviewed-by: Alina Buzachis
2025-08-04 18:03:21 +00:00
patchback[bot]
7f69aff0d6 k8s_json_patch: support the hidden_fields param (#964) (#972)
This is a backport of PR #964 as merged into main (c48778d).
SUMMARY
Add support for hidden_fields on k8s_json_patch

ISSUE TYPE

Feature Pull Request

COMPONENT NAME
k8s_json_patch
ADDITIONAL INFORMATION
Works exactly the same as k8s
Haven't pushed the doc yet, because of many changes. Will do it on a separate commit if the tests pass.
1st commit here, sorry if I forget some things.
Thanks!

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-08-01 18:24:39 +00:00
patchback[bot]
8c65ac066d Add support for take-ownership Helm flag (#957) (#969)
This is a backport of PR #957 as merged into main (cf3c3a9).
SUMMARY
Add support for take-ownership Helm flag added in Helm 3.17.0
ISSUE TYPE

Feature Pull Request

COMPONENT NAME

kubernetes.core.helm

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-07-28 15:48:39 +00:00
patchback[bot]
1d962fb932 Revert "Remove kubeconfig value from module invocation log (#826)" (#899) (#966)
This is a backport of PR #899 as merged into main (1705ced).
This reverts commit 6efabd3.
SUMMARY

Fixes #870
A better solution is necessary to address #782. The current code makes getting manifests practically unusable. We need to revert this commit until a better solution is found.

ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

kubeconfig

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-07-22 21:29:21 +00:00
patchback[bot]
27ce23aa72 Fix integration test with ansibe-core 2.20 (#951) (#960)
This is a backport of PR #951 as merged into main (f568c9d).
SUMMARY
Now that ansible-core 2.19.0rc1 has been released, ansible-core’s devel branch has been bumped from 2.19.0.dev0 to 2.20.0.dev0. This potentially requires collection CIs to be updated which rely on devel using tests/sanity/ignore-2.19.txt, for example. Also it’s now time to add stable-2.19 to CI if you relied on devel to cover 2.19 so far. Note that milestone has also been updated to 2.20.0dev0.
During testing, I noticed that the failed test tasks/test_helm_not_installed.yml due to the new error message with ansible 2.20, please find here and following comments.
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
test/CI (tasks/test_helm_not_installed.yml)
ADDITIONAL INFORMATION
to be cherry-picked to the stable-6 and stable-5

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-07-15 15:34:33 +00:00
patchback[bot]
993652b581 Add more functionality coverage to k8s_rollback integration test (#950) (#956)
This is a backport of PR #950 as merged into main (94e4235).
SUMMARY

Resolves #344

This revision adds the following test coverage:

Label Selectors: Tests rollback using label selectors to target specific deployments.
No Rollout History: Tests the warning scenario when attempting to rollback a deployment with only one revision.
Unsupported Resource Types: Tests error handling when trying to rollback unsupported resources like Services.
Non-existent Resources: Tests behavior when attempting to rollback resources that don't exist.
Multiple Resource Rollback: Tests bulk rollback operations using label selectors on multiple deployments.
Return Value Validation: Comprehensive validation of the rollback_info structure and content.
Field Selectors: Tests rollback using field selectors to target specific resources.
Check Mode Validation: Additional validation of check mode behavior and return values.

COMPONENT NAME

tests/integration/targets/k8s_rollback/tasks/main.yml

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-07-14 14:36:29 +00:00
patchback[bot]
9bd9d22db3 Fix the integration test for helm_registry_auth with helm >= 3.18.0 and clarify idempotency. (#946) (#953)
This is a backport of PR #946 as merged into main (642eb93).
SUMMARY
Fix the integration test for helm_registry_auth with helm >= 3.18.0 and clarify idempotency.
Fixes #944
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
helm_registry_auth
ADDITIONAL INFORMATION
Caused by the changes in helm starting from 3.18.0

Reviewed-by: Bikouo Aubin
Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-07-08 15:56:48 +00:00
patchback[bot]
0593426918 Add plain_http parameter to helm, helm_pull and helm_template (#934) (#949)
This is a backport of PR #934 as merged into main (775959c).
SUMMARY

This change introduces the plain_http parameter to modules that can interact with OCI registries. This in needed in cases where the OCI registry does not use SSL encryption, forcing Helm to send HTTP requests instead of HTTPS

ISSUE TYPE


Feature Pull Request

COMPONENT NAME

helm, helm_pull and helm_template
ADDITIONAL INFORMATION


This is the output when trying to use an OCI registry that is not configured to use SSL certs.

fatal: [localhost]: FAILED! => {"changed": false, "command": "/usr/local/bin/helm show chart 'oci://<http-registry>/charts/foo'", "msg": "Failure when executing Helm command. Exited 1.\nstdout: \nstderr: Error: Get \"https://<http-registry>/v2/charts/foo/tags/list\": http: server gave HTTP response to HTTPS client\n", "stderr": "Error: Get \"https://<http-registry>/v2/charts/foo/tags/list\": http: server gave HTTP response to HTTPS client\n", "stderr_lines": ["Error: Get \"https://<http-registry>/v2/charts/foo/tags/list\": http: server gave HTTP response to HTTPS client"], "stdout": "", "stdout_lines": []}

Reviewed-by: Bikouo Aubin
2025-06-12 10:53:42 +00:00
Bianca Henderson
8fa5b201a4 Prep release 6.0.0 (#933)
SUMMARY

Prep kubernetes.core 6.0.0
Prerequisite: Release of community.okd/redhat.openshift 4.0.2 needs to happen first

ISSUE TYPE


Feature Pull Request

COMPONENT NAME
Multiple

Reviewed-by: Bikouo Aubin
2025-06-03 16:56:33 +00:00
Bikouo Aubin
94c1f57f36 Push 5.x.x changes into main branch (#932)
Release 5.3.0 is out, update the main branch to reflect these changes.

Reviewed-by: Yuriy Novostavskiy
Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-05-16 16:06:45 +00:00
Bianca Henderson
d0b97319a5 Update README to remove information about backports. (#930)
Per this comment, I am removing information about backports that were added in #926; per the Cloud Content Handbook page on backports, we will only be backporting to the two latest versions, and since mentioning specific branches and versions in this collection's README in this manner will add to future maintenance/upkeep burden, I opted to remove this line entirely.
I will be creating a separate PR to manually backport the new README information to stable-5.

Reviewed-by: Mike Graves <mgraves@redhat.com>
Reviewed-by: Alina Buzachis
2025-05-15 13:45:09 +00:00
Bianca Henderson
38d5c81051 Add information in README stating stable-4 is no longer supported (#926)
SUMMARY

Resolves ACA-2383.

ISSUE TYPE


Docs Pull Request

COMPONENT NAME

README.md
ADDITIONAL INFORMATION
Also added information about backporting only bugfixes to stable-3 and made some minor capitalization edits.

Reviewed-by: Bikouo Aubin
Reviewed-by: Yuriy Novostavskiy
Reviewed-by: Mike Graves <mgraves@redhat.com>
Reviewed-by: Alina Buzachis
2025-05-14 17:13:52 +00:00
Noah Lehmann
914a16ec5c Add helm insecure skip tls verify (#901)
SUMMARY
Added the option insecure_skip_tls_verify  to the following helm modules:

helm_repository
helm
Unified the option with alias in helm_pull

For helm, added the option to the helm diff call, as it got fixed upstream.
Upstream Issue: databus23/helm-diff#503
Fixed with: helm/helm#12856
Fixes #694
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME

kubernetes.core.helm
kubernetes.core.helm_repository
kubernetes.core.helm_pull

ADDITIONAL INFORMATION
Basically the option was added in the parameters set in the ansible job, in the docs and then injected in the helm and helm diff binary calls if set. Defaults to False.
Example
---
- name: Test helm modules
  tasks:
    - name: Test helm repository insecure
      kubernetes.core.helm_repository:
        name: insecure
        repo_url: "<helm-repo-with-self-signed-tls>"
        state: present
        insecure_skip_tls_verify: true
    - name: Test helm pull insecure
      kubernetes.core.helm_pull:
        chart_ref: "oci://<helm-repo-with-self-signed-tls>/ptroject"
        destination: /tmp
        insecure_skip_tls_verify: true
    - name: Test helm insecure
      kubernetes.core.helm:
        name: insecure
        chart_ref: "oci://<helm-repo-with-self-signed-tls>/project"
        namespace: helm-insecure-test
        state: present
        insecure_skip_tls_verify: true
Note
Might need an alias for telm_template, as the option is called insecure_registry, in the manual and docs of helm it would be --insecure-skip-tls-verify as well though.
Not included, as it was recently merged with #805

Reviewed-by: Yuriy Novostavskiy
Reviewed-by: Noah Lehmann
Reviewed-by: Bikouo Aubin
Reviewed-by: Bianca Henderson <beeankha@gmail.com>
Reviewed-by: Mike Graves <mgraves@redhat.com>
2025-05-02 16:24:26 +00:00
Yuriy Novostavskiy
cb2070c93f Initial update to 6.0.0-dev0: remove support of ansible-core<2.16.0 and k8s inventory plugin (#867)
SUMMARY
This is initial to prepare the main branch to version 6.0.0 (6.0.0-dev0 in galaxy.yml) and includes following braking changes:

removed support of ansible-core<2.16.0 as 2.15 reach EOL in Nov 2024;
removed the k8s inventory plugin that was deprecated in release 3.0.0.

ISSUE TYPE

Feature Pull Request

COMPONENT NAME

Documentation
galaxy.yml
inventory/k8s.py

ADDITIONAL INFORMATION
The initial version of this PR doesn't remove tests/sanity/ignore-2.14.txt and tests/sanity/ignore-2.15.txt, and CI part will require removing version 2.15 from the matrix in https://github.com/ansible-network/github_actions, so, we have external dependency here.

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
Reviewed-by: Yuriy Novostavskiy
Reviewed-by: Mike Graves <mgraves@redhat.com>
2025-04-29 18:23:11 +00:00
Bianca Henderson
b594d35931 Update ansible-lint version to 25.1.2 (#919)
* Update ansible-lint version to 25.1.2

* Add changelog file
2025-04-29 11:54:09 -04:00
b0z02003
00699ac3e5 add reset_then_reuse_values support to helm module (#802)
SUMMARY
Starting with version 3.14.0, Helm supports --reset-then-reuse-values. As discussed on the original PR. This greatly improves on --reuse-values as it allows to avoid templates errors when new features are added to an upgraded chart.
Closes #803
ISSUE TYPE

Feature Pull Request

COMPONENT NAME
helm
ADDITIONAL INFORMATION
This PR is greatly 'inspired' by #575 and because I wasn't sure how I could provide additional tests for it, I actually copied those build previously for --reuse-values (as it is an improvement on this feature.

Reviewed-by: Bikouo Aubin
Reviewed-by: Yuriy Novostavskiy
Reviewed-by: b0z02003
Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-04-28 15:11:58 +00:00
Bikouo Aubin
d329e7ee42 Rebase PR #898 (#905)
This PR is a rebase of #898 for CI to pass
Thanks @efussi for your collaboration.
Closes #892

Reviewed-by: Yuriy Novostavskiy
Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-04-25 05:31:03 +00:00
Yuriy Novostavskiy
d4fc22c74e Bugfix: fix unit-source for pre-release of ansible-core 2.20 (devel and milestone branch) (#903)
SUMMARY
CI fix for #904
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
tests/unit
ADDITIONAL INFORMATION

Reviewed-by: Mike Graves <mgraves@redhat.com>
Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-04-24 14:56:24 +00:00
Mike Graves
b648f45e90 Prep 5.2.0 release (#891) (#896)
SUMMARY
Prep 5.2.0 release
ISSUE TYPE
COMPONENT NAME
ADDITIONAL INFORMATION
Reviewed-by: Yuriy Novostavskiy
Reviewed-by: Bikouo Aubin
Reviewed-by: Alina Buzachis
(cherry picked from commit 0eff03d)
SUMMARY


ISSUE TYPE


Bugfix Pull Request
Docs Pull Request
Feature Pull Request
New Module Pull Request

COMPONENT NAME

ADDITIONAL INFORMATION

Reviewed-by: Yuriy Novostavskiy
Reviewed-by: GomathiselviS <gomathiselvi@gmail.com>
2025-04-02 13:39:41 +00:00
Bikouo Aubin
2cb5d6c316 Run integration tests using ansible-core 2.19 (#888)
* fix integration test ``k8s_full`` running with ansible-core 2.19

* Fix templating issues

* fix test on current ansible version

* fix tests cases

* Fix additional tests

* fix the templating mechanism

* consider using variable_[start/end]_string while parsing template

* Remove support for omit into template option

* Remove unnecessary unit tests
2025-04-01 11:15:30 +02:00
Bikouo Aubin
0e7229cf8d Push changes from 3.3.1 into main branch (#893)
Release 3.3.1 is out; push changes to main branch

Reviewed-by: Bianca Henderson <beeankha@gmail.com>
2025-03-31 09:06:26 +00:00
Will Thames
9ec6912325 Extend hidden_fields to allow more complicated field definitions (#872)
SUMMARY
This allows us to ignore e.g. the last-applied-configuration annotation by specifying
metadata.annotations[kubectl.kubernetes.io/last-applied-configuration]
ISSUE TYPE

Feature Pull Request

COMPONENT NAME
hidden_fields
This replaces #643 as I no longer have permissions to push to branches in this repo

Reviewed-by: Bikouo Aubin
Reviewed-by: Helen Bailey <hebailey@redhat.com>
Reviewed-by: GomathiselviS <gomathiselvi@gmail.com>
Reviewed-by: Alina Buzachis
2025-03-20 10:35:51 +00:00
Steve Ovens
7cdf0d03f5 waiter.py Add ClusterOperator Test (#879)
SUMMARY
Fixes #869
During an OpenShift installation, one of the checks to see that the cluster is ready to proceed with configuration is to check to ensure that the Cluster Operators are in an Available: True Degraded: False Progressing: False state. While you can currently use the k8s_info module to get a json response, the resulting json needs to be iterated over several times to get the appropriate status.
This PR adds functionality into waiter.py which loops over all resource instances of the cluster operators. If any of them is not ready, waiter returns False and the task false. If the task returns, you can assume that all the cluster operators are healthy.


ISSUE TYPE


Feature Pull Request

COMPONENT NAME

waiter.py
ADDITIONAL INFORMATION



A simple playbook will trigger the waiter.py to watch the ClusterOperator object

---
- name: get operators
  hosts: localhost
  gather_facts: false
  tasks:
    - name: Get cluster operators
      kubernetes.core.k8s_info:
        api_version: v1
        kind: ClusterOperator
        kubeconfig: "/home/ocp/one/auth/kubeconfig"
        wait: true
        wait_timeout: 30
      register: cluster_operators


This will produce the simple response if everything is functioning properly:
PLAY [get operators] *************************************************************************************************

TASK [Get cluster operators] *****************************************************************************************
ok: [localhost]

PLAY RECAP ***********************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

If the timeout is reached:
PLAY [get operators] *************************************************************************************************

TASK [Get cluster operators] *****************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ansible_collections.kubernetes.core.plugins.module_utils.k8s.exceptions.CoreException: Failed to gather information about ClusterOperator(s) even after waiting for 30 seconds
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Failed to gather information about ClusterOperator(s) even after waiting for 30 seconds"}

PLAY RECAP ***********************************************************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

UNSOLVED: How to know which Operators are failing

Reviewed-by: Mandar Kulkarni <mandar242@gmail.com>
Reviewed-by: Bikouo Aubin
2025-02-26 17:53:12 +00:00
Yuriy Novostavskiy
91df2f10bc Fix linters in CI (#873)
SUMMARY
It seems that recent updates in linters break CI. Closes #874
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
CI
ADDITIONAL INFORMATION

Reviewed-by: Mike Graves <mgraves@redhat.com>
Reviewed-by: Yuriy Novostavskiy
2025-02-06 15:16:55 +00:00
Yuriy Novostavskiy
1943dfc3d9 Post release 5.1.0 update (#866)
SUMMARY
This is a post-5.1.0 documentation update of the main branch that includes a cherry-pic of the changelog and an update version to 5.2.0-dev0.
ISSUE TYPE

Docs Pull Request

COMPONENT NAME

changelog
galaxy.yml

ADDITIONAL INFORMATION
The reason for this version bump is to understand of version when the collection is installed as ansible-galaxy collection install git+https://github.com/ansible-collections/kubernetes.core.git and don't mess up the main (that may contain some PRs that is not included to any released version) with the released version 5.1.0.

Reviewed-by: Mike Graves <mgraves@redhat.com>
Reviewed-by: Yuriy Novostavskiy
2025-01-21 15:53:54 +00:00
Yuriy Novostavskiy
eb731cd3a5 Remove deprecated .github/stale.yml to address #837 (#838)
SUMMARY
I noticed that even config for probot/stale is present in the repo, but the old issues and PRs weren't marked as stale and not closed by the bot. Investigated and found that this bot was added to community.kubernetes as ansible-collections/community.kubernetes#53 but wasn't moved to kubernetes.core and never worked here.
Moreover, this bot is completely deprecated and down, ref: probot/stale#430
So, the config to be removed.
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
.github/stale.yml
ADDITIONAL INFORMATION
Closes #837
Trivial change that not require changelog

Reviewed-by: Mike Graves <mgraves@redhat.com>
2025-01-17 16:26:28 +00:00
Irum Malik
ecc64cace1 helm_pull: Silence false no_log warning (#796)
SUMMARY
Apply no_log=True to pass_credentials to silence false positive warning.
Fixes similar issue to: #423
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
changelog/fragements/796-false-positive-helmull.yaml
plugins/modules/helm_pull.py

Reviewed-by: Yuriy Novostavskiy
Reviewed-by: Mike Graves <mgraves@redhat.com>
Reviewed-by: Irum Malik
2025-01-17 15:52:58 +00:00
Yuriy Novostavskiy
bc0de24cba trivial doc: replace 2.5.0 with 3.0.0 (#831)
SUMMARY
Some parameters were added to the master in time where the latest version was 2.4.0 with version_added: 2.5.0, however the next version after 2.4.0 was a 3.0.0.
So, with this trivial doc PR (that most probably doesn't require a changelog fragment and including to changelog) I replacing  version_added: 2.5.0 to  version_added: 3.0.0 for:

reuse_values in kubernetes.core.helm module
reset_values in kubernetes.core.helm module
delete_all in  kubernetes.core.k8s module
hidden_fields  in  kubernetes.core.k8s module
hidden_fields   in  kubernetes.core.k8s_info module

All of them are introduced in kubernetes.core 3.0.0
ISSUE TYPE

Docs Pull Request

COMPONENT NAME

helm
k8s
8s_info


ADDITIONAL INFORMATION
PR to be backported to stable-3 and stable-5

Reviewed-by: Mike Graves <mgraves@redhat.com>
2025-01-17 15:43:51 +00:00
Mike Graves
9f60b151ba Clean up test namespace (#852)
SUMMARY

The helm_set_values test target did not clean up its namespace which is leading to unstable tests in the k8s_drain target.

ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

ADDITIONAL INFORMATION

Reviewed-by: Alina Buzachis
Reviewed-by: Yuriy Novostavskiy
2025-01-17 14:53:21 +00:00
Yuriy Novostavskiy
159a63af97 fix linters in github actions (#848)
Fix bug #846
within this commit ansible/ansible-lint updated to 24.12.2 and config moved to .config folder
2025-01-16 14:45:27 -05:00
Bikouo Aubin
6efabd3418 Remove kubeconfig value from module invocation log (#826) 2024-12-17 17:50:22 +01:00
Yuriy Novostavskiy
aee847431a helm_registry_auth module to authenticate in OCI registry (#800)
* new module helm_registry_auth

* Initial integration tests

* final update copyright and integration test before pr

* update link to pr in changelog fragment

* reformat plugins/module_utils/helm.py with black

to fix linters in actions

* attempt to fix unit test

unit test was missing initially

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

* next attemp to fix unit-test

* remove unused and unsupported helm_args_common

* remove unused imports and fix other linters errors

* another fix for unit test

* fix issue introducied by commit ff02893a12a31f9c44b5c48f9a8bf85057295961

* add binary_path to arg_spec

* return helm_cmd in the output of check mode

remove changlog fragment

* description suggestion from reviewer/maintainer

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

* description suggestion from reviewer/maintainer

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

* description suggestion from reviewer/maintainer

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

* description suggestion from reviewer/maintainer

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

* description suggestion from reviewer/maintainer

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

* description suggestion from reviewer/maintainer

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

* description suggestion from reviewer/maintainer

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

* description suggestion from reviewer/maintainer

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

* remove changed from module return

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

* remove redundant code

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

* Update plugins/modules/helm_registry_auth.py

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

* consider support of logout when user is not logged in

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

* consider support helm < 3.0.0

* Revert "consider support helm < 3.0.0"

This reverts commit f20004d196.

* reintroduce support of helm version less than 3.8.0

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

* revert reintroducing support of helm < 3.8.0

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

* update documentation with the recent module updates

* Update plugins/modules/helm_registry_auth.py

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

* add test of logout impendency

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

* fix linters

* fix intendations in the integration tests

* create tests/integration/targets/helm_registry_auth/aliases

* fix integration test (typo)

* fix integration tests (test wrong cred)

* add stderr when module fail

* another attempt to fix integration test

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

---------

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>
2024-12-17 15:39:42 +01:00
Yuriy Novostavskiy
6609abdd5a Parameter insecure_registry added to helm_template (#805)
* Parameter insecure_registry added to helm_template as equivalent of insecure-skip-tls-verify
2024-12-17 11:59:14 +01:00
Pierre Ozoux
219c747a24 fix: typo (#804)
* fix: typo

replaces https://github.com/ansible-collections/kubernetes.core/pull/799

* doc: add changelog fragment

* Delete changelogs/fragments/804-drain-typo.yaml

---------

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>
2024-12-17 11:58:33 +01:00
Bikouo Aubin
7559b65946 Fix helm integration tests (#830)
SUMMARY
Fix charts ref on integration tests targets
ISSUE TYPE


Bugfix Pull Request

Reviewed-by: Yuriy Novostavskiy
Reviewed-by: Alina Buzachis
2024-12-17 10:18:17 +00:00
Mike Graves
c8a33c7180 Fix helm tests (#827)
SUMMARY

Some of the charts we've used for testing are no longer available at the old helm repository urls, as they've been moved to oci registries. This updates those charts.
In the longer term, we should find a better way to handle these kinds of test fixtures, probably by switching to local charts as much as possible.

ISSUE TYPE


Bugfix Pull Request
Docs Pull Request
Feature Pull Request
New Module Pull Request

COMPONENT NAME

ADDITIONAL INFORMATION

Reviewed-by: Helen Bailey <hebailey@redhat.com>
Reviewed-by: Yuriy Novostavskiy
2024-12-13 21:50:37 +00:00
Ottavia Balducci
52f2cb5587 Improve error message for pod disruption budget when draining a node (#798)
SUMMARY
Closes #797 .
The error message "Too Many Requests" is confusing and is changed to a more meaningful message:
TASK [Drain node] *************************************************************************
Montag 25 November 2024  09:20:28 +0100 (0:00:00.014)       0:00:00.014 ******* 
fatal: [host -> localhost]: FAILED! => {"changed": false, "msg": "Failed to delete pod kube-public/draintest-6b84677b99-9jf7m due to: Cannot evict pod as it would violate the pod's disruption budget."}


The new task output would allow to deal with a pod disruption budget with the retries/until logic in a more controlled way:
---
- hosts: "{{ target }}"
  serial: 1
  gather_facts: false
  tasks:
    - name: Drain node
      kubernetes.core.k8s_drain:
        kubeconfig: "{{ kubeconfig_path }}"
        name: "{{ inventory_hostname }}"
        delete_options:
          ignore_daemonsets: true
          delete_emptydir_data: true
          wait_timeout: 100
          disable_eviction: false
          wait_sleep: 1
      delegate_to: localhost
      retries: 10
      delay: 5
      until: drain_result is success or 'disruption budget' not in drain_result.msg
      register: drain_result

ISSUE TYPE


Feature Pull Request

COMPONENT NAME
k8s_drain

Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-12-11 14:45:47 +00:00
Mike Graves
513ff66fcf Remove kubevirt integration test workflow (#806)
SUMMARY

This removes the kubevirt integration tests. We don't maintain that collection or have any permissions on that repo, so there's no reason for these tests to be here.

ISSUE TYPE


Bugfix Pull Request


COMPONENT NAME

ADDITIONAL INFORMATION

Reviewed-by: Bikouo Aubin
Reviewed-by: Helen Bailey <hebailey@redhat.com>
Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-12-10 16:18:14 +00:00
Ottavia Balducci
fca0dc0485 Fix k8s_drain runs into timeout with pods from stateful sets. (#793)
SUMMARY
Fixes #792 .
The function wait_for_pod_deletion in k8s_drain never checks on which node a pod is actually running:
            try:
                response = self._api_instance.read_namespaced_pod(
                    namespace=pod[0], name=pod[1]
                )
                if not response:
                    pod = None
                time.sleep(wait_sleep)
This means that if a pod is successfully evicted and restarted with the same name on a new node, k8s_drain does not notice and thinks that the original pod is still running. This is the case for pods which are part of a stateful set.

ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME
k8s_drain

Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-12-10 15:35:07 +00:00
Yuriy Novostavskiy
cd686316e9 [ci] fix github actions post 2.18 (#789)
This PR includes a trivial fix for the GitHub Actions issue #788 and related to switching milestone and devel branches of ansible/ansible to version 2.19 and prepare repo to be ready to include test with Python 3.13 when ansible-network/github_actions/pull/162 is merged.
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
GitHub actions/test

Reviewed-by: Andrew Klychkov <aklychko@redhat.com>
Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-11-04 17:12:45 +00:00
Yuriy Novostavskiy
b8e9873f64 Update README.md with removing outdated communication channels (#790)
Summary:
  As part of the consolidating Ansible discussion platforms and communication
  channels was decided to use the Ansible forum as the main place for questions
  and discussion.

  Reference: https://forum.ansible.com/t/proposal-consolidating-ansible-discussion-platforms/6812

  As part of this change, the IRC channel was removed by the PRs #778 and #774.

  However, the README.md file wasn't fully cleaned up from the outdated information.

  The `#ansible-kubernetes` channel on [libera.chat](https://libera.chat/) IRC isn't
  used by maintainers and contributors anymore.

  The Wiki page on the https://github.com/ansible/community/ was deprecated a long time ago
2024-11-04 14:31:08 +01:00
Ottavia Balducci
4c305e73f0 Make k8s_drain work when only one pod is present (#770)
SUMMARY
Fixes #769 .
k8s_drain was not checking if a pod has been deleted when there was only one pod on the node to be drained.
The list of pods, pods, was being "popped" before the first iteration of the while loop:
        pod = pods.pop()
        while (_elapsed_time() < wait_timeout or wait_timeout == 0) and pods:
When pods contains only one element, the while loop is skipped.


ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

k8s_drain

Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-11-01 14:22:27 +00:00
Andrew Klychkov
c8a9326306 CONTRIBUTING.md remove IRC (#778) 2024-09-05 09:07:17 +02:00
Andrew Klychkov
445d367059 README: Add Communication section with Forum information (#774) 2024-08-19 10:57:24 +02:00
GomathiselviS
fdb8af7ca9 Update Readme to match the template (#767)
SUMMARY


Refer: https://issues.redhat.com/browse/ACA-1749
This PR updates the README doc to match the template
ISSUE TYPE


Bugfix Pull Request
Docs Pull Request
Feature Pull Request
New Module Pull Request

COMPONENT NAME

ADDITIONAL INFORMATION

Reviewed-by: Alina Buzachis
2024-07-31 13:37:02 +00:00
Mandar Kulkarni
a89f19b4e5 Bump the ansible-lint version to 24.7.0 (#765)
* add minimum version for  ansible-lint to 24.7.0

* added changelog fragment

* add newline at eof
2024-07-26 13:48:56 -04:00
QCU
5bc53dba7c fix: kustomize plugin fails with deprecation warnings (#728)
SUMMARY

error judgments are based on the exit codes of command execution, where 0 represents success and non-zero represents failure.
Optimize the run_command function to return a tuple like the run_command method of AnsibleModule.

Fixes #639
ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

kustomize lookup plugin
ADDITIONAL INFORMATION

Reviewed-by: Mike Graves <mgraves@redhat.com>
Reviewed-by: QCU
2024-07-15 13:29:23 +00:00
Artur Załęski
b07fbd6271 Fix waiting for daemonset when desired number of pods is 0 (#756)
Fixes #755
SUMMARY
Because we don't have any node with non_exisiting_label (see code below) desired number of Pods will be 0. Kubernetes won't create .status.updatedNumberScheduled field (at least on version v1.27), because we still are not going to create any Pods. So that if .status.updatedNumberScheduled doesn't exist we should assume that number is 0
Code to reproduce:
- name: Create daemonset
  kubernetes.core.k8s:
    state: present
    wait: true
    definition:
      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        name: my-daemonset
        namespace: default
      spec:
        selector:
          matchLabels:
            app: my-app
        template:
          metadata:
            labels:
              app: my-app
          spec:
            containers:
              - name: my-container
                image: nginx
            nodeSelector:
              non_exisiting_label: 1
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
kubernetes.core.plugins.module_utils.k8s.waiter
ADDITIONAL INFORMATION



TASK [Create daemonset] **********************************************************************************************************************************
changed: [controlplane] => {"changed": true, "duration": 5, "method": "create", "result": {"apiVersion": "apps/v1", "kind": "DaemonSet", "metadata": {"annotations": {"deprecated.daemonset.template.generation": "1"}, "creationTimestamp": "2024-06-28T08:23:41Z", "generation": 1, "managedFields": [{"apiVersion": "apps/v1", "fieldsType": "FieldsV1", "fieldsV1": {"f:metadata": {"f:annotations": {".": {}, "f:deprecated.daemonset.template.generation": {}}}, "f:spec": {"f:revisionHistoryLimit": {}, "f:selector": {}, "f:template": {"f:metadata": {"f:labels": {".": {}, "f:app": {}}}, "f:spec": {"f:containers": {"k:{\"name\":\"my-container\"}": {".": {}, "f:image": {}, "f:imagePullPolicy": {}, "f:name": {}, "f:resources": {}, "f:terminationMessagePath": {}, "f:terminationMessagePolicy": {}}}, "f:dnsPolicy": {}, "f:nodeSelector": {}, "f:restartPolicy": {}, "f:schedulerName": {}, "f:securityContext": {}, "f:terminationGracePeriodSeconds": {}}}, "f:updateStrategy": {"f:rollingUpdate": {".": {}, "f:maxSurge": {}, "f:maxUnavailable": {}}, "f:type": {}}}}, "manager": "OpenAPI-Generator", "operation": "Update", "time": "2024-06-28T08:23:41Z"}, {"apiVersion": "apps/v1", "fieldsType": "FieldsV1", "fieldsV1": {"f:status": {"f:observedGeneration": {}}}, "manager": "kube-controller-manager", "operation": "Update", "subresource": "status", "time": "2024-06-28T08:23:41Z"}], "name": "my-daemonset", "namespace": "default", "resourceVersion": "1088421", "uid": "faafdbf7-4388-4cec-88d5-84657966312d"}, "spec": {"revisionHistoryLimit": 10, "selector": {"matchLabels": {"app": "my-app"}}, "template": {"metadata": {"creationTimestamp": null, "labels": {"app": "my-app"}}, "spec": {"containers": [{"image": "nginx", "imagePullPolicy": "Always", "name": "my-container", "resources": {}, "terminationMessagePath": "/dev/termination-log", "terminationMessagePolicy": "File"}], "dnsPolicy": "ClusterFirst", "nodeSelector": {"non_exisiting_label": "1"}, "restartPolicy": "Always", "schedulerName": "default-scheduler", "securityContext": {}, "terminationGracePeriodSeconds": 30}}, "updateStrategy": {"rollingUpdate": {"maxSurge": 0, "maxUnavailable": 1}, "type": "RollingUpdate"}}, "status": {"currentNumberScheduled": 0, "desiredNumberScheduled": 0, "numberMisscheduled": 0, "numberReady": 0, "observedGeneration": 1}}}

~$ kubectl get ds
NAME           DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR           AGE
my-daemonset   0         0         0       0            0           non_exisiting_label=1   30s

Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-07-10 13:58:37 +00:00
Mike Graves
44a2fc392a Merge pull request #757 from gravesm/gha-python-version
Remove ansible install step from kubevirt GHA
2024-07-09 11:52:07 -04:00
Mike Graves
6265a3e7ce Remove ansible install step from kubevirt GHA
Ansible 2.17 is already included in the ubuntu-latest runner image, so
there's no need for a separate install step. It was broken in any case
because the python version being used was too low for ansible 2.18.
2024-07-09 09:51:36 -04:00
Yuriy Novostavskiy
0afd257dd0 fix shields.io badges in README.md (#749)
SUMMARY
This PR fixes shields.io badges in README.md. It's just cosmetic bugfix
ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
README.md
ADDITIONAL INFORMATION
Current README.md:

This PR:

Reviewed-by: Mike Graves <mgraves@redhat.com>
Reviewed-by: Yuriy Novostavskiy
2024-06-18 13:55:25 +00:00
Yuriy Novostavskiy
d192157ed8 update changelog with release 3.2.0 (#750)
SUMMARY
Minor/cosmetic documentation change with adding release 3.2.0 to changelog for master as the release is from stable-3 branch
ISSUE TYPE

Docs Pull Request

COMPONENT NAME
CHANGELOG.md
ADDITIONAL INFORMATION
Most probably this PR should be backported to the stable-5 branch after the merge to the main and should be with a skip-changelog tag.

Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-06-17 18:58:44 +00:00
Eric G
6a04f42d0b helm: Accept release candidate versions for compatibility checks (#745)
SUMMARY

If the helm CLI version includes -rc.1 for example, the version checks fails due to an incomplete regex.
The error can be triggered if you use helm v3.15.0-rc.1 for example, and apply a helm chart with wait: true 
ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME
helm
helm_pull
ADDITIONAL INFORMATION

Reviewed-by: Yuriy Novostavskiy
Reviewed-by: Eric G.
Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-06-17 18:58:42 +00:00
Bikouo Aubin
5064d722c3 Update changelog after release 5.0.0 (#747)
Push change from stable-5 after release 5.0.0

Reviewed-by: Mike Graves <mgraves@redhat.com>
Reviewed-by: Yuriy Novostavskiy
2024-06-13 10:02:28 +00:00
Yuriy Novostavskiy
fb80d973c4 Doc: add example of using kubectl connection plugin (#741)
Doc: add example of using kubectl connection plugin

SUMMARY
Currently documentation for collection don't include any examples of using kubenrenes.core.kubectl connection plugin and it's hard to start using that plugin.
ISSUE TYPE

Docs Pull Request

COMPONENT NAME
kubenrenes.core.kubectl connection plugin
ADDITIONAL INFORMATION
This PR was inspired by #288 and based on feedback on that PR and my own experience. Thanks @tpo for his try and @geerlingguy for his Ansible for DevOps book

Reviewed-by: Bikouo Aubin
Reviewed-by: Sandra McCann <samccann@redhat.com>
Reviewed-by: Mike Graves <mgraves@redhat.com>
Reviewed-by: Yuriy Novostavskiy
Reviewed-by: purdzan
2024-06-06 13:48:15 +00:00
Bikouo Aubin
8363a4debf Remove support for ansible-core<2.15 (#737)
Drop support for ansible-core<2.15

SUMMARY

Remove support for ansible-core<2.15

ISSUE TYPE


Feature Pull Request

Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-05-31 07:41:07 +00:00
Bikouo Aubin
0c5233a650 Defer removal of inventory/k8s to 6.0.0 (#734)
Defer removal of inventory/k8s to 6.0.0

SUMMARY
Defer removal of inventory plugin k8s to release 6.0.0.

ISSUE TYPE


Feature Pull Request

Reviewed-by: Alina Buzachis
Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-05-31 07:41:04 +00:00
Bikouo Aubin
c0666a5137 kubevirt.core collection cross testing (#731)
* Initial

* update python version

* update python version

* checkout local version of collection

* add integration job

* indent

* Set workflow as non blocking
2024-05-30 15:34:29 +02:00
Bikouo Aubin
072a08091b Remove deprecated function from module_utils/common.py (#726)
Remove deprecated function from module_utils/common.py

SUMMARY

Remove deprecated functions and class from module_utils/common.py in order to prepare release 4.0.0

ISSUE TYPE


Feature Pull Request

COMPONENT NAME

module_utils/common.py

Reviewed-by: Alina Buzachis
2024-05-24 05:29:46 +00:00
Alina Buzachis
cbadbe32f9 Defer removal of k8s inventory plugin to version 5.0. (#723)
Defer removal of k8s inventory plugin to version 5.0.

SUMMARY

Defer removal of k8s inventory plugin to version 5.0.

ISSUE TYPE


Bugfix Pull Request
Docs Pull Request
Feature Pull Request
New Module Pull Request

COMPONENT NAME

inventory/k8s.py
ADDITIONAL INFORMATION

Reviewed-by: Bikouo Aubin
Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-05-22 10:13:50 +00:00
Alina Buzachis
966fa7e906 k8s - remove support for merge_type=json (#722)
k8s - remove support for merge_type=json

SUMMARY

Support for merge_type=json has been removed in version 4.0.0. Please use kubernetes.core.k8s_json_patch instead.

ISSUE TYPE


Bugfix Pull Request
Docs Pull Request
Feature Pull Request
New Module Pull Request

COMPONENT NAME

k8s.py
ADDITIONAL INFORMATION

Reviewed-by: Bikouo Aubin
Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-05-22 10:13:47 +00:00
Mike Graves
485eae3b10 Release 3.1.0 (#719) (#720)
Sync stable-3 to main branch (#719)

Release 3.1.0
SUMMARY
Release prep for 3.1.0
ISSUE TYPE
Bugfix Pull Request
Docs Pull Request
Feature Pull Request
New Module Pull Request
COMPONENT NAME
ADDITIONAL INFORMATION
Reviewed-by: Alina Buzachis
Reviewed-by: Helen Bailey hebailey@redhat.com
(cherry picked from commit ef829b8)

Reviewed-by: Alina Buzachis
2024-05-16 18:43:34 +00:00
Conner Crosby
a4c1bd8541 Update deprecation version for merge_type=json (#700)
Update deprecation version for merge_type=json

SUMMARY
When looking at the parts of plugins/module_utils/common.py and plugins/module_utils/k8s/service.py during the post 3.0.0 release (see https://github.com/ansible-collections/kubernetes.core/pull/663/files#diff-9ee2d0860a5643da4e1f35136e9e7c3a41c5f2fd2952c197e7e32b941e5a301c) that affect merge_type when set to json, I don't believe merge_type=json was deprecated for (and removed from) the k8s module, and instead the deprecation version has moved to 4.0.0. Hence, the documentation update.
ISSUE TYPE

Docs Pull Request

COMPONENT NAME
k8s module

Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-05-15 18:02:55 +00:00
Mike Graves
8858b19121 Fix unsafe text assertion in tests (#716)
Fix unsafe text assertion in tests

SUMMARY

This fixes a problem with unsafe text in an assertion.

ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

ADDITIONAL INFORMATION

Reviewed-by: GomathiselviS
Reviewed-by: Bikouo Aubin
2024-05-15 06:50:26 +00:00
Yuriy Novostavskiy
6360763098 minor: doc: use the same style of version_added across repo (#703)
minor(doc): use the same style of version_added across repo

SUMMARY
Currently is no single style of version_added, in some places it's unquoted, somewhere single quote is used, in another places it's double quoted. Moreover, some file had different styles in one single file.
The aim of this PR is to update whole repo to single style for version_added
ISSUE TYPE

Docs Pull Request

COMPONENT NAME
kustomize
helm
helm_info
helm_plugin
helm_plugin_info
helm_pull
helm_repository
helm_template
k8s_cluster_info
k8s_cp
k8s_drain
k8s_exec
k8s_log
k8s_rollback
k8s_taint
ADDITIONAL INFORMATION
The same style is proposed as used in amazon.aws collections

Reviewed-by: Kelv Gooding
Reviewed-by: Alina Buzachis
Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-05-14 15:50:12 +00:00
Dennis Ochocki
ac943e9890 fixed typo in filename of 'k8s_json_patch'-action (#652)
fixed typo in filename of 'k8s_json_patch'-action 

SUMMARY

The filename/symlink of the action for the 'k8s_json_patch'-module was wrong. Renamed file from 'ks8_json_patch.py' to ' k8s_json_patch.py'

ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME

k8s_json_patch
ADDITIONAL INFORMATION


Because of the wrong filename things like unvaulting kubeconfig files did not worked.

Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-05-14 15:48:01 +00:00
John Lathouwers
0408aa9328 Update kustomize.py add --enable-helm support (#592)
Update kustomize.py add --enable-helm support

Add --enable-helm support
SUMMARY
Fixes #568
ISSUE TYPE

Feature Pull Request

COMPONENT NAME
Lookup plugin: kubernetes.core.kustomize
ADDITIONAL INFORMATION
Current and maintained arg:
lookup('kubernetes.core.kustomize', dir=item)

Additional feature args:
lookup('kubernetes.core.kustomize', dir=item, enable_helm=false)
lookup('kubernetes.core.kustomize', dir=item, enable_helm=true)

Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-05-13 17:16:16 +00:00
Mike Graves
874fbfedd5 Merge pull request #707 from gravesm/linting-fix
Update ansible-lint GHA
2024-05-08 11:09:30 -04:00
Mike Graves
d8d9133912 Update ansible-lint GHA
There seems to be a bug in older versions of ansible-lint where pinning
to a version for the GHA still installs the main branch.
2024-05-07 12:35:35 -04:00
Alina Buzachis
86d9a3f45f Add tests/sanity/ignore-2.18.txt (#704)
Add tests/sanity/ignore-2.18.txt

SUMMARY

Add tests/sanity/ignore-2.18.txt

ISSUE TYPE


Bugfix Pull Request
Docs Pull Request
Feature Pull Request
New Module Pull Request

COMPONENT NAME

ADDITIONAL INFORMATION

Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-05-07 15:27:13 +00:00
Yuriy Novostavskiy
fb25ff44f1 add support of kubectl_local_env_vars (#698) (#702)
add support of kubectl_local_env_vars (#698)

SUMMARY
Support of local environmental variable that may be required to be set on Ansible Controller before the connection is set and may be used for kubectl command. This PR addressed for #698
The main idea is to have the support of  additional/extra local environmental variable that may be required for kubectl itself, i.e. for authorization in case of public clouds
ISSUE TYPE

Feature Pull Request

COMPONENT NAME
kubernetes.core.kubectl connection plugin
ADDITIONAL INFORMATION
This PR attempts to implement local env support for the kubectl connection plugin that may be useful in case of using kubectl against public cloud kubernetes environment that uses some authorization (i.e. aws cli) additionally to kubeconfig file. More detail in #698
The output that shows that the connection plugin can use local environment variable for kubectl command (with some debug that used during development but removed then):
root@ubuntu-shell:/# cat test.yaml
- hosts: localhost
  gather_facts: no
  any_errors_fatal: yes
  vars:
    ansible_connection: "kubectl"
    ansible_kubectl_namespace: "test"
    ansible_kubectl_config: "/.kube/config"
    ansible_kubectl_pod: "ubuntu"
    ansible_kubectl_container: "ubuntu"
    ansible_kubectl_local_env_vars:
      TESTVAR1: "test"
      TESTVAR2: "test"
      TESTVAR3: "test"
  environment:
    TEST_ENV1: value1
    TEST_ENV2: value2

  tasks:
  - name: test
    ansible.builtin.shell: env
    register: result
  - debug:
      var: result.stdout_lines
root@ubuntu-shell:/# ansible-playbook test.yaml
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] **************************************************************************************************************************************

TASK [test] *******************************************************************************************************************************************
changed: [localhost]

TASK [debug] ******************************************************************************************************************************************
ok: [localhost] => {
    "result.stdout_lines": [
        "KUBERNETES_PORT=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_PORT=443",
        "HOSTNAME=ubuntu",
        "HOME=/root",
        "LC_CTYPE=C.UTF-8",
        "TEST_ENV1=value1",
        "TEST_ENV2=value2",
        "TERM=xterm",
        "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "KUBERNETES_PORT_443_TCP_PORT=443",
        "KUBERNETES_PORT_443_TCP_PROTO=tcp",
        "KUBERNETES_SERVICE_PORT_HTTPS=443",
        "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_HOST=10.96.0.1",
        "PWD=/"
    ]
}

PLAY RECAP ********************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

root@ubuntu-shell:/# ansible-playbook test.yaml -vvv
ansible-playbook [core 2.14.5]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.10/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] (/usr/bin/python3)
  jinja version = 3.1.3
  libyaml = True
No config file found; using defaults
host_list declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
script declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
auto declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
yaml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
ini declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
Skipping due to inventory source not existing or not being readable by the current user
toml declined parsing /etc/ansible/hosts as it did not pass its verify_file() method
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: test.yaml ***********************************************************************************************************************************
1 plays in test.yaml

PLAY [localhost] **************************************************************************************************************************************

TASK [test] *******************************************************************************************************************************************
task path: /test.yaml:19
redirecting (type: connection) ansible.builtin.kubectl to kubernetes.core.kubectl
<127.0.0.1> ESTABLISH kubectl CONNECTION
<127.0.0.1> ENV: KUBERNETES_SERVICE_PORT_HTTPS=443
<127.0.0.1> ENV: KUBERNETES_SERVICE_PORT=443
<127.0.0.1> ENV: HOSTNAME=ubuntu-shell
<127.0.0.1> ENV: PWD=/
<127.0.0.1> ENV: HOME=/root
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
<127.0.0.1> ENV: LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
<127.0.0.1> ENV: TERM=xterm
<127.0.0.1> ENV: SHLVL=1
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP_PROTO=tcp
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
<127.0.0.1> ENV: KUBERNETES_SERVICE_HOST=10.96.0.1
<127.0.0.1> ENV: KUBERNETES_PORT=tcp://10.96.0.1:443
<127.0.0.1> ENV: KUBERNETES_PORT_443_TCP_PORT=443
<127.0.0.1> ENV: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
<127.0.0.1> ENV: _=/usr/local/bin/ansible-playbook
<127.0.0.1> ENV: LC_CTYPE=C.UTF-8
<127.0.0.1> ENV: TESTVAR1=test
<127.0.0.1> ENV: TESTVAR2=test
<127.0.0.1> ENV: TESTVAR3=test
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'echo ~ && sleep 0'"]
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', '/bin/sh -c \'( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133 `" && echo ansible-tmp-1713785852.548581-6866-69007595335133="` echo /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133 `" ) && sleep 0\'']
Using module file /usr/local/lib/python3.10/dist-packages/ansible/modules/command.py
<127.0.0.1> PUT /root/.ansible/tmp/ansible-local-6862s5_lr_wb/tmpxwmx0qeh TO /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/AnsiballZ_command.py
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'chmod u+x /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/ /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/AnsiballZ_command.py && sleep 0'"]
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'TEST_ENV1=value1 TEST_ENV2=value2 /usr/bin/python3 /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/AnsiballZ_command.py && sleep 0'"]
<127.0.0.1> EXEC ['/usr/local/bin/kubectl', '-n', 'test', '--kubeconfig', '/.kube/config', 'exec', '-i', 'ubuntu', '-c', 'ubuntu', '--', '/bin/sh', '-c', "/bin/sh -c 'rm -f -r /root/.ansible/tmp/ansible-tmp-1713785852.548581-6866-69007595335133/ > /dev/null 2>&1 && sleep 0'"]
changed: [localhost] => {
    "changed": true,
    "cmd": "env",
    "delta": "0:00:00.005088",
    "end": "2024-04-22 11:37:33.655340",
    "invocation": {
        "module_args": {
            "_raw_params": "env",
            "_uses_shell": true,
            "argv": null,
            "chdir": null,
            "creates": null,
            "executable": null,
            "removes": null,
            "stdin": null,
            "stdin_add_newline": true,
            "strip_empty_ends": true
        }
    },
    "msg": "",
    "rc": 0,
    "start": "2024-04-22 11:37:33.650252",
    "stderr": "",
    "stderr_lines": [],
    "stdout": "KUBERNETES_PORT=tcp://10.96.0.1:443\nKUBERNETES_SERVICE_PORT=443\nHOSTNAME=ubuntu\nHOME=/root\nLC_CTYPE=C.UTF-8\nTEST_ENV1=value1\nTEST_ENV2=value2\nTERM=xterm\nKUBERNETES_PORT_443_TCP_ADDR=10.96.0.1\nPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\nKUBERNETES_PORT_443_TCP_PORT=443\nKUBERNETES_PORT_443_TCP_PROTO=tcp\nKUBERNETES_SERVICE_PORT_HTTPS=443\nKUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443\nKUBERNETES_SERVICE_HOST=10.96.0.1\nPWD=/",
    "stdout_lines": [
        "KUBERNETES_PORT=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_PORT=443",
        "HOSTNAME=ubuntu",
        "HOME=/root",
        "LC_CTYPE=C.UTF-8",
        "TEST_ENV1=value1",
        "TEST_ENV2=value2",
        "TERM=xterm",
        "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "KUBERNETES_PORT_443_TCP_PORT=443",
        "KUBERNETES_PORT_443_TCP_PROTO=tcp",
        "KUBERNETES_SERVICE_PORT_HTTPS=443",
        "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_HOST=10.96.0.1",
        "PWD=/"
    ]
}

TASK [debug] ******************************************************************************************************************************************
task path: /test.yaml:22
redirecting (type: connection) ansible.builtin.kubectl to kubernetes.core.kubectl
ok: [localhost] => {
    "result.stdout_lines": [
        "KUBERNETES_PORT=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_PORT=443",
        "HOSTNAME=ubuntu",
        "HOME=/root",
        "LC_CTYPE=C.UTF-8",
        "TEST_ENV1=value1",
        "TEST_ENV2=value2",
        "TERM=xterm",
        "KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1",
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "KUBERNETES_PORT_443_TCP_PORT=443",
        "KUBERNETES_PORT_443_TCP_PROTO=tcp",
        "KUBERNETES_SERVICE_PORT_HTTPS=443",
        "KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443",
        "KUBERNETES_SERVICE_HOST=10.96.0.1",
        "PWD=/"
    ]
}

PLAY RECAP ********************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

root@ubuntu-shell:/#

Reviewed-by: Bikouo Aubin
Reviewed-by: Yuriy Novostavskiy
Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-05-07 15:27:09 +00:00
Felix Matouschek
600c10dffb k8s: Display warnings to users (#701)
k8s: Display warnings to users

SUMMARY
This changes K8sService and the k8s module so warnings returned by the K8S API are displayed to the user.
Fixes kubevirt/kubevirt.core#30
Fixes kubevirt/kubevirt.core#31
ISSUE TYPE


Feature Pull Request

COMPONENT NAME


k8s module
K8sService

ADDITIONAL INFORMATION



Before:
TASK [Create VM] **********************************************************************************************************************************************
ok: [localhost]

After:
TASK [Create VM] **********************************************************************************************************************************************
[WARNING]: unknown field "spec.template.spec.disk"
[WARNING]: unknown field "spec.template.spec.domain.bogus"
ok: [localhost]

Reviewed-by: Adam Miller <admiller@redhat.com>
Reviewed-by: Mike Graves <mgraves@redhat.com>
Reviewed-by: Felix Matouschek <felix@matouschek.org>
2024-05-06 13:35:52 +00:00
Wout Van De Wiel
9f7c865c9c helm - expand kubeconfig path with user's home dir (#654)
helm - expand kubeconfig path with user's home dir

SUMMARY

Currently the helm module fails when providing the default kubeconfig path explicitly, while the same path is fine for the k8s module.

ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

helm
ADDITIONAL INFORMATION



- name: Deploy kubelet-csr-approver
  delegate_to: client
  run_once: true
  kubernetes.core.helm:
    update_repo_cache: true
    kubeconfig: "~/.kube/config"
    state: present
    name: kubelet-csr-approver
    namespace: kubelet-csr-approver
    create_namespace: true
    chart_ref: kubelet-csr-approver/kubelet-csr-approver
    chart_version: 1.0.5
    values: "{{ lookup('template', 'values.yaml.j2') | from_yaml }}"
    atomic: true

Before change:
TASK [kubernetes/kubelet_csr_approver : Deploy kubelet-csr-approver] ***
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: FileNotFoundError: [Errno 2] No such file or directory: '~/.kube/config'
fatal: [node-1 -> client(192.168.121.56)]: FAILED! => {"changed": false, "module_stderr": "", "module_stdout": "Traceback (most recent call last):\r\n  File \"/home/vagrant/.ansible/tmp/ansible-tmp-1697293347.7135417-118207-9805169252135/AnsiballZ_helm.py\", line 107, in <module>\r\n    _ansiballz_main()\r\n  File \"/home/vagrant/.ansible/tmp/ansible-tmp-1697293347.7135417-118207-9805169252135/AnsiballZ_helm.py\", line 99, in _ansiballz_main\r\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n  File \"/home/vagrant/.ansible/tmp/ansible-tmp-1697293347.7135417-118207-9805169252135/AnsiballZ_helm.py\", line 47, in invoke_module\r\n    runpy.run_module(mod_name='ansible_collections.kubernetes.core.plugins.modules.helm', init_globals=dict(_module_fqn='ansible_collections.kubernetes.core.plugins.modules.helm', _modlib_path=modlib_path),\r\n  File \"/usr/lib/python3.10/runpy.py\", line 224, in run_module\r\n    return _run_module_code(code, init_globals, run_name, mod_spec)\r\n  File \"/usr/lib/python3.10/runpy.py\", line 96, in _run_module_code\r\n    _run_code(code, mod_globals, init_globals,\r\n  File \"/usr/lib/python3.10/runpy.py\", line 86, in _run_code\r\n    exec(code, run_globals)\r\n  File \"/tmp/ansible_kubernetes.core.helm_payload_o8s36dti/ansible_kubernetes.core.helm_payload.zip/ansible_collections/kubernetes/core/plugins/modules/helm.py\", line 924, in <module>\r\n  File \"/tmp/ansible_kubernetes.core.helm_payload_o8s36dti/ansible_kubernetes.core.helm_payload.zip/ansible_collections/kubernetes/core/plugins/modules/helm.py\", line 737, in main\r\n  File \"/tmp/ansible_kubernetes.core.helm_payload_o8s36dti/ansible_kubernetes.core.helm_payload.zip/ansible_collections/kubernetes/core/plugins/modules/helm.py\", line 435, in run_repo_update\r\n  File \"/tmp/ansible_kubernetes.core.helm_payload_o8s36dti/ansible_kubernetes.core.helm_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/helm.py\", line 169, in run_helm_command\r\n  File \"/tmp/ansible_kubernetes.core.helm_payload_o8s36dti/ansible_kubernetes.core.helm_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/helm.py\", line 162, in env_update\r\n  File \"/tmp/ansible_kubernetes.core.helm_payload_o8s36dti/ansible_kubernetes.core.helm_payload.zip/ansible_collections/kubernetes/core/plugins/module_utils/helm.py\", line 120, in _prepare_helm_environment\r\nFileNotFoundError: [Errno 2] No such file or directory: '~/.kube/config'\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}

After change:
TASK [kubernetes/kubelet_csr_approver : Deploy kubelet-csr-approver] ***
changed: [node-1 -> client(192.168.121.56)]

Reviewed-by: Mike Graves <mgraves@redhat.com>
Reviewed-by: Bikouo Aubin
2024-03-13 13:16:38 +00:00
Bikouo Aubin
23e94b60c1 helm - Add reuse-values when running helm diff (#683)
helm - Add reuse-values when running helm diff

SUMMARY

closes #680

ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

helm

Reviewed-by: GomathiselviS
Reviewed-by: Alina Buzachis
2024-03-01 16:15:11 +00:00
bastienbosser
1955989278 fix(Collection's util resource discovery fails when complex subresources present #659) (#676)
* fix(Collection's util resource discovery fails when complex subresources present #659)

* fix(add changelog fragment)

* update node image

* Create discovery.yml

* Update main.yml

---------

Co-authored-by: Bastien Bosser <bastien.bosser@eviden.com>
Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>
2024-02-29 14:38:45 +01:00
psmolkin
7c4ec3b982 Align helmdiff_check behavior with the deploy function (#670)
Align `helmdiff_check` behavior with the `deploy` function

SUMMARY
Align helmdiff_check behavior with the deploy function

Fixes #638
helmdiff_check respects set_values parameter
Fixes #669
helmdiff_check command line parameters sequence aligned to the deploy function

ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
kubernetes.core.helm

Reviewed-by: Mike Graves <mgraves@redhat.com>
2024-02-19 17:01:23 +00:00
Alina Buzachis
8d15489ec2 Remove ignore files and entries which are not useful anymore (#667)
Remove ignore files and entries which are not useful anymore

SUMMARY

Remove ignore files and entries which are not useful anymore

ISSUE TYPE


Bugfix Pull Request
Docs Pull Request
Feature Pull Request
New Module Pull Request

COMPONENT NAME

ADDITIONAL INFORMATION

Reviewed-by: Helen Bailey <hebailey@redhat.com>
Reviewed-by: Mike Graves <mgraves@redhat.com>
2023-12-12 16:09:14 +00:00
Bikouo Aubin
3dcdcbc85d avoid unsafe condition in integration (#665)
avoid unsafe condition in integration

SUMMARY


ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

integration tests

Reviewed-by: Helen Bailey <hebailey@redhat.com>
Reviewed-by: Alina Buzachis
2023-12-12 07:23:09 +00:00
GomathiselviS
fe9c12326d Update main branch post 3.0.0 release (#663)
Update main branch post 3.0.0 release

SUMMARY


ISSUE TYPE


Docs Pull Request

COMPONENT NAME

ADDITIONAL INFORMATION

Reviewed-by: Bikouo Aubin
2023-11-21 17:23:25 +00:00
270 changed files with 10941 additions and 7559 deletions

View File

@@ -2,5 +2,8 @@
profile: production
exclude_paths:
- .ansible/
- .github/
- tests/integration
- tests/unit
- tests/sanity

6
.ansible-lint-ignore Normal file
View 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
View File

@@ -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.

View File

@@ -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,18 +51,20 @@ jobs:
source: "./source"
cloud_common: "./cloudcommon"
ansible_posix: "./ansible_posix"
community_general: "./community_general"
strategy:
fail-fast: false
matrix:
ansible-version:
- milestone
# Ref must match a branch/tag on github.com/ansible/ansible (e.g. stable-2.18, not 2.18).
ansible-version: ["stable-2.18", "milestone"]
enable-turbo-mode: [true, false]
exclude:
- ansible-version: "milestone"
enable-turbo-mode: true
python-version:
- "3.12"
enable-turbo-mode:
- 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
@@ -105,6 +108,7 @@ jobs:
source_path: ${{ env.source }}
- name: checkout ansible-collections/cloud.common
if: ${{ matrix.enable-turbo-mode == true }}
uses: ansible-network/github_actions/.github/actions/checkout_dependency@main
with:
repository: ansible-collections/cloud.common
@@ -118,7 +122,15 @@ 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
if: ${{ matrix.enable-turbo-mode == true }}
uses: ansible-network/github_actions/.github/actions/build_install_collection@main
with:
install_python_dependencies: true
@@ -130,8 +142,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

28
.github/workflows/label-new-prs.yaml vendored Normal file
View File

@@ -0,0 +1,28 @@
---
name: label new prs
on:
pull_request_target:
types:
- opened
- reopened
- converted_to_draft
- ready_for_review
jobs:
add_label:
if: github.actor != 'patchback[bot]'
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Add 'needs_triage' label if the pr is not a draft
uses: actions-ecosystem/action-add-labels@v1
if: github.event.pull_request.draft == false
with:
labels: needs_triage
- name: Remove 'needs_triage' label if the pr is a draft
uses: actions-ecosystem/action-remove-labels@v1
if: github.event.pull_request.draft == true
with:
labels: needs_triage

View File

@@ -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"

5
.gitignore vendored
View File

@@ -13,10 +13,15 @@ changelogs/.plugin-cache.yaml
tests/output
tests/integration/cloud-config-*
.cache
.ansible
# Helm charts
tests/integration/*-chart-*.tgz
tests/integration/targets/*/*.tgz
# ansible-test generated file
tests/integration/inventory
tests/integration/*-*.yml
# VS Code settings
.vscode/

View File

@@ -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

View File

@@ -4,6 +4,387 @@ Kubernetes Collection Release Notes
.. contents:: Topics
v6.4.0
======
Release Summary
---------------
This release adds Helm v4 compatibility across the Helm modules and improves ``k8s_drain`` with check mode. When you explicitly allow evicting unmanaged pods, pods with local storage, or pods managed by a ``DaemonSet``, those cases are reported as informational output instead of module warnings.
Minor Changes
-------------
- helm_info - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
- helm_plugin - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
- helm_plugin_info - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
- helm_pull - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
- helm_registry_auth - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
- helm_registry_auth - add new option plain_http to allow insecure http connection when running ``helm registry login`` (https://github.com/ansible-collections/kubernetes.core/pull/1090).
- helm_repository - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
- k8s_drain - Add support for ``check_mode`` (https://github.com/ansible-collections/kubernetes.core/pull/1086).
- k8s_drain - Convert module warnings into informational displays when users explicitly request the deletion of unmanaged pods, pods with local storage, or those managed by a `DaemonSet` (https://github.com/ansible-collections/kubernetes.core/issues/1037).
Bugfixes
--------
- Helm - Allow taking ownership of existing Kubernetes resources on the first installation of a Helm release. Previously, the ``take_ownership`` parameter was always disabled during the initial install, preventing resource adoption (https://github.com/ansible-collections/kubernetes.core/pull/1034).
v6.3.0
======
Release Summary
---------------
This release includes bugfixes such as implementing idempotency for the ``helm_pull`` module as well as a security update for selectively redacting sensitive information from kubeconfig.
Minor Changes
-------------
- Remove deprecated import from ``ansible.module_utils._text`` (https://github.com/ansible-collections/kubernetes.core/pull/1053).
- helm - add ``release_values`` key to ``status`` return value that can be accessed using Jinja2 dot notation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
- helm_info - add ``release_values`` key to ``status`` return value that can be accessed using Jinja2 dot notation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
Deprecated Features
-------------------
- helm - the ``status.values`` return value has been deprecated and will be removed in a release after 2027-01-08. Use ``status.release_values`` instead (https://github.com/ansible-collections/kubernetes.core/pull/1056).
- helm_info - the ``status.values`` return value has been deprecated and will be removed in a release after 2027-01-08. Use ``status.release_values`` instead (https://github.com/ansible-collections/kubernetes.core/pull/1056).
Security Fixes
--------------
- Selectively redact sensitive info from kubeconfig instead of applying blanket ``no_log=True`` (https://github.com/ansible-collections/kubernetes.core/pull/1014).
Bugfixes
--------
- Add idempotency for ``helm_pull`` module (https://github.com/ansible-collections/kubernetes.core/pull/1055).
- Fixed a bug where setting ``K8S_AUTH_VERIFY_SSL=true`` (or any string value) caused the value to be treated as a separate ``kubectl`` command argument. (https://github.com/ansible-collections/kubernetes.core/pull/1049).
- Limit supported versions of Helm to <4.0.0 (https://github.com/ansible-collections/kubernetes.core/pull/1039).
- Replace passing ``warnings`` to ``exit_json`` with ``AnsibleModule.warn`` in the ``k8s_drain``, ``k8s_rollback.py`` and ``k8s_scale.py`` modules as it deprecated in ``ansible-core>=2.19.0`` and will be removed in ``ansible-core>=2.23.0`` (https://github.com/ansible-collections/kubernetes.core/pull/1033).
- k8s - Fix return block from the module documentation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
- meta - Add ``k8s_cluster_info``, ``k8s_json_patch`` and ``k8s_rollback`` to k8s action group (https://github.com/ansible-collections/kubernetes.core/pull/992).
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
======
Release Summary
---------------
This major release drops support for ansible-core versions lower than 2.14, Python versions lower than 3.9 and updates python kubernetes library to 24.2.0, helm/kind-action to 1.8.0, kubernetes >= 1.24, along with bug fixes and minor changes.
Minor Changes
-------------
- helm - add ``reuse_values`` and ``reset_values`` support to helm module (https://github.com/ansible-collections/kubernetes.core/issues/394).
- k8s - add new option ``delete_all`` to support deletion of all resources when state is set to ``absent``. (https://github.com/ansible-collections/kubernetes.core/issues/504)
- k8s, k8s_info - add a hidden_fields option to allow fields to be hidden in the results of k8s and k8s_info
- k8s_drain - add ability to filter the list of pods to be drained by a pod label selector (https://github.com/ansible-collections/kubernetes.core/issues/474).
Breaking Changes / Porting Guide
--------------------------------
- Remove support for ansible-core < 2.14
- Update python kubernetes library to 24.2.0, helm/kind-action to 1.8.0, kubernetes >= 1.24.
Deprecated Features
-------------------
- k8s - the ``k8s`` inventory plugin has been deprecated and will be removed in release 4.0.0 (https://github.com/ansible-collections/kubernetes.core/issues/31).
Bugfixes
--------
- helm - Put the chart_ref into quotes when running ``helm show chart``, ``helm upgrade`` and ``helm dependency update`` commands (https://github.com/ansible-collections/kubernetes.core/issues/653).
- helm - delete temporary file created when deploying chart with option ``release_values`` set (https://github.com/ansible-collections/kubernetes.core/issues/530).
- helm - fix issue occurring when uninstalling chart with statues others than ``deployed`` (https://github.com/ansible-collections/kubernetes.core/issues/319).
- helm - fix post_renderer argument breaking the helm deploy_command (https://github.com/ansible-collections/kubernetes.core/pull/586).
- helm - use post_renderer when checking ``changed`` status for a helm release (https://github.com/ansible-collections/kubernetes.core/pull/588).
- k8s_scale - clean handling of ResourceTimeout exception (https://github.com/ansible-collections/kubernetes.core/issues/583).
- k8s_scale - fix issue when scaling StatefulSets with ``updateStrategy=OnDelete`` (https://github.com/ansible-collections/kubernetes.core/issues/579).
v2.4.0
======
@@ -96,7 +477,7 @@ v2.3.1
Bugfixes
--------
- Catch exception raised when the process is waiting for resources (https://github.com/ansible-collections/kubernetes.core/issues/407).
- Catch expectation raised when the process is waiting for resources (https://github.com/ansible-collections/kubernetes.core/issues/407).
- Remove `omit` placeholder when defining resource using template parameter (https://github.com/ansible-collections/kubernetes.core/issues/431).
- k8s - fix the issue when trying to delete resources using label_selectors options (https://github.com/ansible-collections/kubernetes.core/issues/433).
- k8s_cp - fix issue when using parameter local_path with file on managed node. (https://github.com/ansible-collections/kubernetes.core/issues/421).

View File

@@ -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.

View File

@@ -1,5 +1,5 @@
# Also needs to be updated in galaxy.yml
VERSION = 2.4.0
VERSION = 6.4.0
TEST_ARGS ?= ""
PYTHON_VERSION ?= `python -c 'import platform; print(".".join(platform.python_version_tuple()[0:2]))'`

View File

@@ -1,34 +1,50 @@
# Kubernetes Collection for Ansible
[![CI](https://github.com/ansible-collections/kubernetes.core/workflows/CI/badge.svg?event=push)](https://github.com/ansible-collections/kubernetes.core/actions) [![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/kubernetes.core)](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
### Helm Version Compatibility
This collection supports Helm v3.x and newer. Please note that specific modules or certain parameters may have additional version requirements.
### 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 +59,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 +73,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 +91,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 +103,7 @@ You can also include it in a `requirements.yml` file and install it via `ansible
---
collections:
- name: kubernetes.core
version: 2.4.0
version: 6.4.0
```
### Installing the Kubernetes Python Library
@@ -102,7 +112,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,8 +180,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 +198,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
[![Linters](https://img.shields.io/github/actions/workflow/status/ansible-collections/kubernetes.core/linters.yaml?label=linters)](https://github.com/ansible-collections/kubernetes.core/actions/workflows/linters.yaml) [![Integration tests](https://img.shields.io/github/actions/workflow/status/ansible-collections/kubernetes.core/integration-tests.yaml?label=integration%20tests)](https://github.com/ansible-collections/kubernetes.core/actions/workflows/integration-tests.yaml) [![Sanity tests](https://img.shields.io/github/actions/workflow/status/ansible-collections/kubernetes.core/sanity-tests.yaml?label=sanity%20tests)](https://github.com/ansible-collections/kubernetes.core/actions/workflows/sanity-tests.yaml) [![Unit tests](https://img.shields.io/github/actions/workflow/status/ansible-collections/kubernetes.core/unit-tests.yaml?label=unit%20tests)](https://github.com/ansible-collections/kubernetes.core/actions/workflows/unit-tests.yaml) [![Codecov](https://img.shields.io/codecov/c/github/ansible-collections/kubernetes.core)](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).
@@ -207,7 +220,7 @@ You can run the collection's test suites with the commands:
### Testing with `molecule`
There are also integration tests in the `molecule` directory which are meant to be run against a local Kubernetes cluster, e.g. using [KinD](https://kind.sigs.k8s.io) or [Minikube](https://minikube.sigs.k8s.io). To setup a local cluster using KinD and run Molecule:
There are also integration tests in the `molecule` directory which are meant to be run against a local Kubernetes cluster, e.g. using [KinD](https://kind.sigs.k8s.io) or [Minikube](https://minikube.sigs.k8s.io). To set up a local cluster using KinD and run Molecule:
kind create cluster
make test-molecule
@@ -231,12 +244,35 @@ 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
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.
<!--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.
## License
GNU General Public License v3.0 or later
See LICENCE to see the full text.
See LICENSE to see the full text.

View File

@@ -762,3 +762,444 @@ releases:
name: helm_pull
namespace: ''
release_date: '2023-01-24'
3.0.0:
changes:
breaking_changes:
- Remove support for ansible-core < 2.14
- Update python kubernetes library to 24.2.0, helm/kind-action to 1.8.0, kubernetes
>= 1.24.
bugfixes:
- helm - Put the chart_ref into quotes when running ``helm show chart``, ``helm
upgrade`` and ``helm dependency update`` commands (https://github.com/ansible-collections/kubernetes.core/issues/653).
- helm - delete temporary file created when deploying chart with option ``release_values``
set (https://github.com/ansible-collections/kubernetes.core/issues/530).
- helm - fix issue occurring when uninstalling chart with statues others than
``deployed`` (https://github.com/ansible-collections/kubernetes.core/issues/319).
- helm - fix post_renderer argument breaking the helm deploy_command (https://github.com/ansible-collections/kubernetes.core/pull/586).
- helm - use post_renderer when checking ``changed`` status for a helm release
(https://github.com/ansible-collections/kubernetes.core/pull/588).
- k8s_scale - clean handling of ResourceTimeout exception (https://github.com/ansible-collections/kubernetes.core/issues/583).
- k8s_scale - fix issue when scaling StatefulSets with ``updateStrategy=OnDelete``
(https://github.com/ansible-collections/kubernetes.core/issues/579).
deprecated_features:
- k8s - the ``k8s`` inventory plugin has been deprecated and will be removed
in release 4.0.0 (https://github.com/ansible-collections/kubernetes.core/issues/31).
minor_changes:
- helm - add ``reuse_values`` and ``reset_values`` support to helm module (https://github.com/ansible-collections/kubernetes.core/issues/394).
- k8s - add new option ``delete_all`` to support deletion of all resources when
state is set to ``absent``. (https://github.com/ansible-collections/kubernetes.core/issues/504)
- k8s, k8s_info - add a hidden_fields option to allow fields to be hidden in
the results of k8s and k8s_info
- k8s_drain - add ability to filter the list of pods to be drained by a pod
label selector (https://github.com/ansible-collections/kubernetes.core/issues/474).
release_summary: This major release drops support for ansible-core versions
lower than 2.14, Python versions lower than 3.9 and updates python kubernetes
library to 24.2.0, helm/kind-action to 1.8.0, kubernetes >= 1.24, along with
bug fixes and minor changes.
fragments:
- 20230206-deprecate-k8s-inventory.yml
- 20231110-helm-quote-ref.yaml
- 517-k8s-make-name-optional.yaml
- 575-helm-add-support-for-reuse_values-and-reset_values.yml
- 579-k8s_scale-fix-issue-with-scaling-statefulsets.yml
- 583-k8s_scale-clean-handling-of-ResourceTimeout-exception.yaml
- 586-helm-fix-post-renderer-arg.yml
- 588-helm-use-post-renderer-for-helmdiff.yml
- 589-helm-uninstall-chart-releases-with-statuses-different-than-deployed.yaml
- 606-k8s_drain-add-pod_selectors-parameter.yaml
- 612-fix-helm-tests.yaml
- 629-add-hidden-fields-option.yaml
- gha-sanity-fixes.yaml
- helm-delete-temporary-file-created-when-using-option-release_values.yaml
- 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`` does not support idempotency with `helm >= 3.18.0`
(https://github.com/ansible-collections/kubernetes.core/pull/946).
- Module k8s_json_patch - Add support for ``hidden_fields`` (https://github.com/ansible-collections/kubernetes.core/pull/964).
- helm - Parameter plain_http added for working with insecure OCI registries
(https://github.com/ansible-collections/kubernetes.core/pull/934).
- helm - Parameter take_ownership added (https://github.com/ansible-collections/kubernetes.core/pull/957).
- helm_pull - Parameter plain_http added for working with insecure OCI registries
(https://github.com/ansible-collections/kubernetes.core/pull/934).
- helm_template - Parameter plain_http added for working with insecure OCI registries
(https://github.com/ansible-collections/kubernetes.core/pull/934).
release_summary: "This release adds ``plain_http`` and ``take_ownership`` parameters
for helm modules, support for ``hidden_fields`` in ``k8s_json_patch``, documented
lack of idempotency support in ``helm_registry_auth`` with ``helm \u2265 3.18.0``,
and improved ``k8s_rollback`` test coverage."
fragments:
- 20250411-kubeconfig-no_log-revert.yaml
- 20250428-k8s-service-hide-fields-first.yaml
- 20250522-add-plain-http-for-oci-registries.yaml
- 20250605-fix-helm_registry_auth-integration_test.yaml
- 20250704-k8s-rollback-integration-test-coverage.yaml
- 20250720-k8s-patch-add-hidden-fields.yaml
- 20250911-add-support-helm-take-ownership.yaml
- release_summary.yml
release_date: '2025-08-12'
6.2.0:
changes:
bugfixes:
- Remove ``ansible.module_utils.six`` imports to avoid warnings (https://github.com/ansible-collections/kubernetes.core/pull/998).
- Update the `k8s_cp` module to also work for init containers (https://github.com/ansible-collections/kubernetes.core/pull/971).
minor_changes:
- Add support of skip-schema-validation in ``helm`` module (https://github.com/ansible-collections/kubernetes.core/pull/995)
- kustomize - Add support of local environ (https://github.com/ansible-collections/kubernetes.core/pull/786).
release_summary: This release adds minor changes and bugfixes, including support
of skip-schema-validation in ``helm`` module and removing deprecated ``ansible.module_utils.six``
imports.
fragments:
- 20241030-support-of-evrion-for-kustomize-lookup-plugin.yaml
- 20250731-fix-k8s_cp-initcontainers.yaml
- 20250916-skip-schema-validation.yaml
- 20250922-remove-ansible-six-imports.yaml
- 6_2_0.yml
release_date: '2025-10-07'
6.3.0:
changes:
bugfixes:
- Add idempotency for ``helm_pull`` module (https://github.com/ansible-collections/kubernetes.core/pull/1055).
- Fixed a bug where setting ``K8S_AUTH_VERIFY_SSL=true`` (or any string value)
caused the value to be treated as a separate ``kubectl`` command argument.
(https://github.com/ansible-collections/kubernetes.core/pull/1049).
- Limit supported versions of Helm to <4.0.0 (https://github.com/ansible-collections/kubernetes.core/pull/1039).
- Replace passing ``warnings`` to ``exit_json`` with ``AnsibleModule.warn``
in the ``k8s_drain``, ``k8s_rollback.py`` and ``k8s_scale.py`` modules as
it deprecated in ``ansible-core>=2.19.0`` and will be removed in ``ansible-core>=2.23.0``
(https://github.com/ansible-collections/kubernetes.core/pull/1033).
- k8s - Fix return block from the module documentation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
- meta - Add ``k8s_cluster_info``, ``k8s_json_patch`` and ``k8s_rollback`` to
k8s action group (https://github.com/ansible-collections/kubernetes.core/pull/992).
deprecated_features:
- helm - the ``status.values`` return value has been deprecated and will be
removed in a release after 2027-01-08. Use ``status.release_values`` instead
(https://github.com/ansible-collections/kubernetes.core/pull/1056).
- helm_info - the ``status.values`` return value has been deprecated and will
be removed in a release after 2027-01-08. Use ``status.release_values`` instead
(https://github.com/ansible-collections/kubernetes.core/pull/1056).
minor_changes:
- Remove deprecated import from ``ansible.module_utils._text`` (https://github.com/ansible-collections/kubernetes.core/pull/1053).
- helm - add ``release_values`` key to ``status`` return value that can be accessed
using Jinja2 dot notation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
- helm_info - add ``release_values`` key to ``status`` return value that can
be accessed using Jinja2 dot notation (https://github.com/ansible-collections/kubernetes.core/pull/1056).
release_summary: This release includes bugfixes such as implementing idempotency
for the ``helm_pull`` module as well as a security update for selectively
redacting sensitive information from kubeconfig.
security_fixes:
- Selectively redact sensitive info from kubeconfig instead of applying blanket
``no_log=True`` (https://github.com/ansible-collections/kubernetes.core/pull/1014).
fragments:
- 1033-warnings-deprecations.yaml
- 20251002-fix-k8s-actiongroup.yaml
- 20251007-selective-kubeconfig-redaction.yaml
- 20251115-limit-versions-of-helm.yaml
- 20251220-fix-K8S_AUTH_VERIFY_SSL-in-kubectl-connecton-plugion.yaml
- 20251228-1053-remove-deprecated-import.yaml
- 20260107-add-idempodency-for-helm-pull.yaml
- 20260108-fix-sanity-failures.yml
- 6-3-0.yaml
release_date: '2026-02-03'
6.4.0:
changes:
bugfixes:
- Helm - Allow taking ownership of existing Kubernetes resources on the first
installation of a Helm release. Previously, the ``take_ownership`` parameter
was always disabled during the initial install, preventing resource adoption
(https://github.com/ansible-collections/kubernetes.core/pull/1034).
minor_changes:
- helm_info - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
- helm_plugin - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
- helm_plugin_info - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
- helm_pull - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
- helm_registry_auth - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
- helm_registry_auth - add new option plain_http to allow insecure http connection
when running ``helm registry login`` (https://github.com/ansible-collections/kubernetes.core/pull/1090).
- helm_repository - Ensure compatibility with Helm v4 (https://github.com/ansible-collections/kubernetes.core/issues/1038).
- k8s_drain - Add support for ``check_mode`` (https://github.com/ansible-collections/kubernetes.core/pull/1086).
- k8s_drain - Convert module warnings into informational displays when users
explicitly request the deletion of unmanaged pods, pods with local storage,
or those managed by a ``DaemonSet`` (https://github.com/ansible-collections/kubernetes.core/issues/1037).
release_summary: This release adds Helm v4 compatibility across the Helm modules
and improves ``k8s_drain`` with check mode. When you explicitly allow evicting
unmanaged pods, pods with local storage, or pods managed by a ``DaemonSet``,
those cases are reported as informational output instead of module warnings.
fragments:
- 20251224-take-ownership-helm-initialization.yaml
- 20260203-k8s_drain-warning-fixes.yaml
- 20260213-support-helm-v4-for-helm-plugin-modules.yaml
- release-6-4-0.yml
release_date: '2026-04-22'

View File

@@ -1,2 +0,0 @@
deprecated_features:
- k8s - the ``k8s`` inventory plugin has been deprecated and will be removed in release 4.0.0 (https://github.com/ansible-collections/kubernetes.core/issues/31).

View File

@@ -1,3 +0,0 @@
---
bugfixes:
- helm - Put the chart_ref into quotes when running ``helm show chart``, ``helm upgrade`` and ``helm dependency update`` commands (https://github.com/ansible-collections/kubernetes.core/issues/653).

View File

@@ -1,3 +0,0 @@
---
minor_changes:
- k8s - add new option delete_all to support deletion of all resources when state is set to absent. (https://github.com/ansible-collections/kubernetes.core/issues/504)

View File

@@ -1,3 +0,0 @@
---
minor_changes:
- helm - add reuse_values and reset_values support to helm module (https://github.com/ansible-collections/kubernetes.core/issues/394).

View File

@@ -1,3 +0,0 @@
---
bugfixes:
- k8s_scale - fix issue when scaling StatefulSets with updateStrategy=OnDelete (https://github.com/ansible-collections/kubernetes.core/issues/579).

View File

@@ -1,3 +0,0 @@
---
bugfixes:
- k8s_scale - clean handling of ResourceTimeout exception (https://github.com/ansible-collections/kubernetes.core/issues/583).

View File

@@ -1,3 +0,0 @@
---
bugfixes:
- helm - fix post_renderer argument breaking the helm deploy_command (https://github.com/ansible-collections/kubernetes.core/pull/586).

View File

@@ -1,3 +0,0 @@
---
bugfixes:
- helm - use post_renderer when checking 'changed' status for a helm release (https://github.com/ansible-collections/kubernetes.core/pull/588).

View File

@@ -1,3 +0,0 @@
---
bugfixes:
- helm - fix issue occurring when uninstalling chart with statues others than 'deployed' (https://github.com/ansible-collections/kubernetes.core/issues/319).

View File

@@ -1,3 +0,0 @@
---
minor_changes:
- k8s_drain - add ability to filter the list of pods to be drained by a pod label selector (https://github.com/ansible-collections/kubernetes.core/issues/474).

View File

@@ -1,3 +0,0 @@
---
trivial:
- add dependency with `install_helm` for `helm_set_values` and `helm_kubeconfig` integration tests (https://github.com/ansible-collections/kubernetes.core/pull/612).

View File

@@ -1,2 +0,0 @@
minor_changes:
- k8s, k8s_info - add a hidden_fields option to allow fields to be hidden in the results of k8s and k8s_info

View File

@@ -1,3 +0,0 @@
---
trivial:
- add github workflow and fix sanity failures (https://github.com/ansible-collections/kubernetes.core/pull/614).

View File

@@ -1,3 +0,0 @@
---
bugfixes:
- helm - delete temporary file created when deploying chart with option release_values set (https://github.com/ansible-collections/kubernetes.core/issues/530).

View File

@@ -1,5 +0,0 @@
---
trivial:
- organize the workflows and pin ansible-lint to 6.21.x.
breaking_changes:
- Remove support for ansible-core < 2.14

View File

@@ -1,3 +0,0 @@
---
breaking_changes:
- Update python kubernetes library to 24.2.0 , helm/kind-action to 1.8.0, kubernetes >= 1.24.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -25,7 +25,7 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- helm (https://github.com/helm/helm/releases)
- helm >= 3.0.0 (https://github.com/helm/helm/releases)
- yaml (https://pypi.org/project/PyYAML/)
@@ -105,6 +105,27 @@ Parameters
<div style="font-size: small; color: darkgreen"><br/>aliases: kube_context</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>get_all_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 2.4.0</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>Set to <code>True</code> if you want to get all (computed) values of the release.</div>
<div>When <code>False</code> (default), only user supplied values are returned.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -127,7 +148,7 @@ Parameters
<b>kubeconfig</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">path</span>
<span style="color: purple">raw</span>
</div>
</td>
<td>
@@ -135,6 +156,7 @@ Parameters
<td>
<div>Helm option to specify kubeconfig path to use.</div>
<div>If the value is not specified in the task, the value of environment variable <code>K8S_AUTH_KUBECONFIG</code> will be used instead.</div>
<div>The configuration can be provided as dictionary. Added in version 2.4.0.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: kubeconfig_path</div>
</td>
</tr>
@@ -172,6 +194,32 @@ Parameters
<div style="font-size: small; color: darkgreen"><br/>aliases: namespace</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>release_state</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 2.3.0</div>
</td>
<td>
<b>Default:</b><br/><div style="color: blue">[]</div>
</td>
<td>
<div>Show releases as per their states.</div>
<div>Default value is <code>deployed</code> and <code>failed</code>.</div>
<div>If set to <code>all</code>, show all releases without any filter applied.</div>
<div>If set to <code>deployed</code>, show deployed releases.</div>
<div>If set to <code>failed</code>, show failed releases.</div>
<div>If set to <code>pending</code>, show pending releases.</div>
<div>If set to <code>superseded</code>, show superseded releases.</div>
<div>If set to <code>uninstalled</code>, show uninstalled releases, if <code>helm uninstall --keep-history</code> was used.</div>
<div>If set to <code>uninstalling</code>, show releases that are currently being uninstalled.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -204,16 +252,23 @@ Examples
.. code-block:: yaml
- name: Deploy latest version of Grafana chart inside monitoring namespace
- name: Gather information of Grafana chart inside monitoring namespace
kubernetes.core.helm_info:
name: test
release_namespace: monitoring
- name: Gather information about test-chart with pending state
kubernetes.core.helm_info:
name: test-chart
release_namespace: testenv
release_state:
- pending
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:
Common return values are documented `here <https://docs.ansible.com/projects/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
.. raw:: html
@@ -270,6 +325,42 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>hooks</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">list</span>
/ <span style="color: purple">elements=dictionary</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.4.0</div>
</td>
<td>always</td>
<td>
<div>Hooks of the release</div>
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>manifest</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">list</span>
/ <span style="color: purple">elements=dictionary</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.4.0</div>
</td>
<td>always</td>
<td>
<div>Manifest of the release</div>
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
@@ -302,6 +393,40 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>notes</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>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.4.0</div>
</td>
<td>always</td>
<td>
<div>Notes of the release</div>
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>release_values</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">dictionary</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 6.3.0</div>
</td>
<td>always</td>
<td>
<div>Dict of Values used to deploy.</div>
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
@@ -357,12 +482,13 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late
<b>values</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
<span style="color: purple">dictionary</span>
</div>
</td>
<td>always</td>
<td>
<div>Dict of Values used to deploy</div>
<div>This return value has been deprecated and will be removed in a release after 2027-01-08. Use RV(status.release_values) instead.</div>
<br/>
</td>
</tr>

View File

@@ -25,7 +25,7 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- helm (https://github.com/helm/helm/releases)
- helm >= 3.0.0 (https://github.com/helm/helm/releases)
- yaml (https://pypi.org/project/PyYAML/)
@@ -36,12 +36,12 @@ Parameters
<table border=0 cellpadding=0 class="documentation-table">
<tr>
<th colspan="1">Parameter</th>
<th colspan="2">Parameter</th>
<th>Choices/<font color="blue">Defaults</font></th>
<th width="100%">Comments</th>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>api_key</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -57,7 +57,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>atomic</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -76,7 +76,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>binary_path</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -91,7 +91,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>ca_cert</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -108,7 +108,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>chart_ref</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -127,7 +127,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>chart_repo_url</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -142,7 +142,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>chart_version</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -157,7 +157,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>context</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -174,7 +174,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>create_namespace</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -194,13 +194,14 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>dependency_update</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 2.4.0</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
@@ -209,7 +210,7 @@ Parameters
</ul>
</td>
<td>
<div>Run standelone <code>helm dependency update CHART</code> before the operation.</div>
<div>Run standalone <code>helm dependency update CHART</code> before the operation.</div>
<div>Run inline <code>--dependency-update</code> with <code>helm install</code> command. This feature is not supported yet with the <code>helm upgrade</code> command.</div>
<div>So we should consider to use <em>dependency_update</em> options with <em>replace</em> option enabled when specifying <em>chart_repo_url</em>.</div>
<div>The <em>dependency_update</em> option require the add of <code>dependencies</code> block in <code>Chart.yaml/requirements.yaml</code> file.</div>
@@ -218,7 +219,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>disable_hook</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -237,7 +238,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>force</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -256,7 +257,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>history_max</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -273,7 +274,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>host</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -289,12 +290,35 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<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>&nbsp;&larr;</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 &gt;= 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>
<b>kubeconfig</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">path</span>
<span style="color: purple">raw</span>
</div>
</td>
<td>
@@ -302,11 +326,49 @@ Parameters
<td>
<div>Helm option to specify kubeconfig path to use.</div>
<div>If the value is not specified in the task, the value of environment variable <code>K8S_AUTH_KUBECONFIG</code> will be used instead.</div>
<div>The configuration can be provided as dictionary. Added in version 2.4.0.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: kubeconfig_path</div>
</td>
</tr>
<tr>
<td colspan="1">
<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>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>Use HTTP instead of HTTPS when working with OCI registries</div>
<div>Requires Helm &gt;= 3.13.0</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>post_renderer</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.4.0</div>
</td>
<td>
</td>
<td>
<div>Path to an executable to be used for post rendering.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>purge</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -325,7 +387,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>release_name</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -342,7 +404,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>release_namespace</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -359,7 +421,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>release_state</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -379,7 +441,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>release_values</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -396,7 +458,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>replace</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -418,7 +480,130 @@ Parameters
</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>&nbsp;&larr;</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&#x27;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 &gt;= 3.9.12.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>reset_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 3.0.0</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li>no</li>
<li><div style="color: blue"><b>yes</b>&nbsp;&larr;</div></li>
</ul>
</td>
<td>
<div>When upgrading package, reset the values to the ones built into the chart.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>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 3.0.0</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li>no</li>
<li>yes</li>
</ul>
</td>
<td>
<div>When upgrading package, specifies wether to reuse the last release&#x27;s values and merge in any overrides from parameters <em>release_values</em>, <em>values_files</em> or <em>set_values</em>.</div>
<div>If <em>reset_values</em> is set to <code>True</code>, this is ignored.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>set_values</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=dictionary</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.4.0</div>
</td>
<td>
</td>
<td>
<div>Values to pass to chart configuration</div>
</td>
</tr>
<tr>
<td class="elbow-placeholder"></td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>value</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>Value to pass to chart configuration (e.g phase=prod).</div>
</td>
</tr>
<tr>
<td class="elbow-placeholder"></td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>value_type</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>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li><div style="color: blue"><b>raw</b>&nbsp;&larr;</div></li>
<li>string</li>
<li>json</li>
<li>file</li>
</ul>
</td>
<td>
<div>Use <code>raw</code> set individual value.</div>
<div>Use <code>string</code> to force a string for an individual value.</div>
<div>Use <code>file</code> to set individual values from a file when the value itself is too long for the command line or is dynamically generated.</div>
<div>Use <code>json</code> to set json values (scalars/objects/arrays). This feature requires helm&gt;=3.10.0.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>skip_crds</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -438,7 +623,49 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<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>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>Disables JSON schema validation for Chart and values.</div>
<div>This feature requires helm &gt;= 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>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>Helm will ignore the check for helm annotations and take ownership of the existing resources</div>
<div>This feature requires helm &gt;= 3.17.0</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>timeout</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -456,7 +683,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>update_repo_cache</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -475,7 +702,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>validate_certs</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -496,7 +723,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>values_files</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -517,7 +744,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>wait</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -537,7 +764,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>wait_timeout</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -556,6 +783,12 @@ Parameters
<br/>
Notes
-----
.. note::
- The default idempotency check can fail to report changes when ``release_state`` is set to ``present`` and ``chart_repo_url`` is defined. Install helm diff >= 3.4.1 for better results.
Examples
@@ -612,6 +845,15 @@ Examples
state: absent
update_repo_cache: true
- name: Deploy Grafana chart using set values on target
kubernetes.core.helm:
name: test
chart_ref: stable/grafana
release_namespace: monitoring
set_values:
- value: phase=prod
value_type: string
# From git
- name: Git clone stable repo on HEAD
ansible.builtin.git:
@@ -631,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:
@@ -657,11 +905,22 @@ Examples
logging:
enabled: True
# Deploy latest version
- name: Deploy latest version of Grafana chart using reuse_values
kubernetes.core.helm:
name: test
chart_ref: stable/grafana
release_namespace: monitoring
reuse_values: true
values:
replicas: 2
version: 3e8ec0b2dffa40fb97d5342e4af887de95faa8c61a62480dd7f8aa03dffcf533
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:
Common return values are documented `here <https://docs.ansible.com/projects/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
.. raw:: html
@@ -767,6 +1026,23 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>release_values</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">dictionary</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 6.3.0</div>
</td>
<td>always</td>
<td>
<div>Dict of Values used to deploy.</div>
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
@@ -822,12 +1098,13 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late
<b>values</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
<span style="color: purple">dictionary</span>
</div>
</td>
<td>always</td>
<td>
<div>Dict of Values used to deploy</div>
<div>Dict of Values used to deploy.</div>
<div>This return value has been deprecated and will be removed in a release after 2027-01-08. Use RV(status.release_values) instead.</div>
<br/>
</td>
</tr>

View File

@@ -25,7 +25,7 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- helm (https://github.com/helm/helm/releases)
- helm >= 3.0.0 (https://github.com/helm/helm/releases)
Parameters
@@ -126,7 +126,7 @@ Parameters
<b>kubeconfig</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">path</span>
<span style="color: purple">raw</span>
</div>
</td>
<td>
@@ -134,6 +134,7 @@ Parameters
<td>
<div>Helm option to specify kubeconfig path to use.</div>
<div>If the value is not specified in the task, the value of environment variable <code>K8S_AUTH_KUBECONFIG</code> will be used instead.</div>
<div>The configuration can be provided as dictionary. Added in version 2.4.0.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: kubeconfig_path</div>
</td>
</tr>
@@ -195,7 +196,7 @@ Examples
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:
Common return values are documented `here <https://docs.ansible.com/projects/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
.. raw:: html

View File

@@ -25,7 +25,7 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- helm (https://github.com/helm/helm/releases)
- helm >= 3.0.0 (https://github.com/helm/helm/releases)
Parameters
@@ -126,7 +126,7 @@ Parameters
<b>kubeconfig</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">path</span>
<span style="color: purple">raw</span>
</div>
</td>
<td>
@@ -134,6 +134,7 @@ Parameters
<td>
<div>Helm option to specify kubeconfig path to use.</div>
<div>If the value is not specified in the task, the value of environment variable <code>K8S_AUTH_KUBECONFIG</code> will be used instead.</div>
<div>The configuration can be provided as dictionary. Added in version 2.4.0.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: kubeconfig_path</div>
</td>
</tr>
@@ -150,7 +151,7 @@ Parameters
</td>
<td>
<div>Name of Helm plugin.</div>
<div>Required only if <code>state=absent</code>.</div>
<div>Required only if <code>state=absent</code> or <code>state=latest</code>.</div>
</td>
</tr>
<tr>
@@ -170,6 +171,23 @@ Parameters
<div>Required only if <code>state=present</code>.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>plugin_version</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<div>Plugin version to install. If this is not specified, the latest version is installed.</div>
<div>Ignored when <code>state=absent</code> or <code>state=latest</code>.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -183,10 +201,12 @@ Parameters
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li>absent</li>
<li><div style="color: blue"><b>present</b>&nbsp;&larr;</div></li>
<li>latest</li>
</ul>
</td>
<td>
<div>If <code>state=present</code> the Helm plugin will be installed.</div>
<div>If <code>state=latest</code> the Helm plugin will be updated. Added in version 2.3.0.</div>
<div>If <code>state=absent</code> the Helm plugin will be removed.</div>
</td>
</tr>
@@ -211,6 +231,28 @@ Parameters
<div style="font-size: small; color: darkgreen"><br/>aliases: verify_ssl</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>verify</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">boolean</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 6.4.0</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li>no</li>
<li><div style="color: blue"><b>yes</b>&nbsp;&larr;</div></li>
</ul>
</td>
<td>
<div>Verify the plugin signature before installing.</div>
<div>This option requires helm version &gt;= 4.0.0</div>
<div>Used with <em>state=present</em>.</div>
</td>
</tr>
</table>
<br/>
@@ -237,11 +279,22 @@ Examples
plugin_name: env
state: absent
- name: Install Helm plugin with a specific version
kubernetes.core.helm_plugin:
plugin_version: 2.0.1
plugin_path: https://domain/path/to/plugin.tar.gz
state: present
- name: Update Helm plugin
kubernetes.core.helm_plugin:
plugin_name: secrets
state: latest
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:
Common return values are documented `here <https://docs.ansible.com/projects/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
.. raw:: html

View File

@@ -27,7 +27,7 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- helm >= 3.0 (https://github.com/helm/helm/releases)
- helm >= 3.0.0 (https://github.com/helm/helm/releases)
Parameters
@@ -174,6 +174,28 @@ Parameters
<div>location to write the chart.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>force</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.3.0</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>Force download of the chart even if it already exists in the destination directory.</div>
<div>By default, the module will skip downloading if the chart with the same version already exists for idempotency.</div>
<div>When used with O(untar_chart=true), will remove any existing chart directory before extracting.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -193,6 +215,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>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>Use HTTP instead of HTTPS when working with OCI registries</div>
<div>Requires Helm &gt;= 3.13.0</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -279,7 +322,8 @@ Parameters
</td>
<td>
<div>Whether or not to check tls certificate for the chart download.</div>
<div>Requires helm &gt;= 3.3.0.</div>
<div>Requires helm &gt;= 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>
@@ -375,11 +419,28 @@ Examples
username: myuser
password: mypassword123
- name: Download Chart (force re-download even if exists)
kubernetes.core.helm_pull:
chart_ref: redis
repo_url: https://charts.bitnami.com/bitnami
chart_version: '17.0.0'
destination: /path/to/chart
force: yes
- name: Download and untar chart (force re-extraction even if directory exists)
kubernetes.core.helm_pull:
chart_ref: redis
repo_url: https://charts.bitnami.com/bitnami
chart_version: '17.0.0'
destination: /path/to/chart
untar_chart: yes
force: yes
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:
Common return values are documented `here <https://docs.ansible.com/projects/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
.. raw:: html
@@ -406,6 +467,23 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late
<div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">helm pull --repo test ...</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>msg</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>when chart already exists</td>
<td>
<div>A message indicating the result of the operation.</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;">Chart redis version 17.0.0 already exists in destination directory</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>

View File

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

View File

@@ -25,7 +25,7 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- helm (https://github.com/helm/helm/releases)
- helm >= 3.0.0 (https://github.com/helm/helm/releases)
- yaml (https://pypi.org/project/PyYAML/)
@@ -40,6 +40,22 @@ Parameters
<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>api_key</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<div>Token used to authenticate with the API. Can also be specified via <code>K8S_AUTH_API_KEY</code> environment variable.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -55,6 +71,138 @@ Parameters
<div>The path of a helm binary to use.</div>
</td>
</tr>
<tr>
<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">path</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<div>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 <code>K8S_AUTH_SSL_CA_CERT</code> environment variable.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: ssl_ca_cert</div>
</td>
</tr>
<tr>
<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">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.4.0</div>
</td>
<td>
</td>
<td>
<div>Helm option to specify which kubeconfig context to use.</div>
<div>If the value is not specified in the task, the value of environment variable <code>K8S_AUTH_CONTEXT</code> will be used instead.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: kube_context</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>force_update</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 2.4.0</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>Whether or not to replace (overwrite) the repo if it already exists.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: force</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>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<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>&nbsp;&larr;</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>
<b>kubeconfig</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 2.4.0</div>
</td>
<td>
</td>
<td>
<div>Helm option to specify kubeconfig path to use.</div>
<div>If the value is not specified in the task, the value of environment variable <code>K8S_AUTH_KUBECONFIG</code> will be used instead.</div>
<div>The configuration can be provided as dictionary.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: kubeconfig_path</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>pass_credentials</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 2.3.0</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>Pass credentials to all domains.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -142,6 +290,27 @@ Parameters
<div style="font-size: small; color: darkgreen"><br/>aliases: username</div>
</td>
</tr>
<tr>
<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>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li>no</li>
<li><div style="color: blue"><b>yes</b>&nbsp;&larr;</div></li>
</ul>
</td>
<td>
<div>Whether or not to verify the API server&#x27;s SSL certificates. Can also be specified via <code>K8S_AUTH_VERIFY_SSL</code> environment variable.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: verify_ssl</div>
</td>
</tr>
</table>
<br/>
@@ -167,7 +336,7 @@ Examples
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:
Common return values are documented `here <https://docs.ansible.com/projects/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
.. raw:: html

View File

@@ -20,6 +20,13 @@ Synopsis
Requirements
------------
The below requirements are needed on the host that executes this module.
- helm >= 3.0.0 (https://github.com/helm/helm/releases)
- yaml (https://pypi.org/project/PyYAML/)
Parameters
----------
@@ -28,12 +35,12 @@ Parameters
<table border=0 cellpadding=0 class="documentation-table">
<tr>
<th colspan="1">Parameter</th>
<th colspan="2">Parameter</th>
<th>Choices/<font color="blue">Defaults</font></th>
<th width="100%">Comments</th>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>binary_path</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -48,7 +55,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>chart_ref</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -67,7 +74,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>chart_repo_url</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -82,7 +89,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>chart_version</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -97,13 +104,14 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>dependency_update</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 2.4.0</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
@@ -119,7 +127,27 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>disable_hook</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 2.4.0</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>Prevent hooks from running during install.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>include_crds</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -138,7 +166,27 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<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>&nbsp;&larr;</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>
<b>output_dir</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -154,7 +202,61 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<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>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>Use HTTP instead of HTTPS when working with OCI registries</div>
<div>Requires Helm &gt;= 3.13.0</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>release_name</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.4.0</div>
</td>
<td>
</td>
<td>
<div>Release name to use in rendered templates.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: name</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>release_namespace</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.4.0</div>
</td>
<td>
</td>
<td>
<div>namespace scope for this request.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>release_values</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -171,7 +273,85 @@ Parameters
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>set_values</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=dictionary</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.4.0</div>
</td>
<td>
</td>
<td>
<div>Values to pass to chart configuration.</div>
</td>
</tr>
<tr>
<td class="elbow-placeholder"></td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>value</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>Value to pass to chart configuration (e.g phase=prod).</div>
</td>
</tr>
<tr>
<td class="elbow-placeholder"></td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>value_type</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>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li><div style="color: blue"><b>raw</b>&nbsp;&larr;</div></li>
<li>string</li>
<li>json</li>
<li>file</li>
</ul>
</td>
<td>
<div>Use <code>raw</code> set individual value.</div>
<div>Use <code>string</code> to force a string for an individual value.</div>
<div>Use <code>file</code> to set individual values from a file when the value itself is too long for the command line or is dynamically generated.</div>
<div>Use <code>json</code> to set json values (scalars/objects/arrays). This feature requires helm&gt;=3.10.0.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>show_only</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 2.4.0</div>
</td>
<td>
<b>Default:</b><br/><div style="color: blue">[]</div>
</td>
<td>
<div>Only show manifests rendered from the given templates.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>update_repo_cache</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -190,7 +370,7 @@ Parameters
</td>
</tr>
<tr>
<td colspan="1">
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>values_files</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
@@ -235,11 +415,29 @@ Examples
dest: myfile.yaml
content: "{{ result.stdout }}"
- name: Render MutatingWebhooksConfiguration for revision tag "canary", rev "1-13-0"
kubernetes.core.helm_template:
chart_ref: istio/istiod
chart_version: "1.13.0"
release_namespace: "istio-system"
show_only:
- "templates/revision-tags.yaml"
release_values:
revision: "1-13-0"
revisionTags:
- "canary"
register: result
- name: Write templates to file
copy:
dest: myfile.yaml
content: "{{ result.stdout }}"
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:
Common return values are documented `here <https://docs.ansible.com/projects/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
.. raw:: html

View File

@@ -27,8 +27,8 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- python >= 3.6
- kubernetes >= 12.0.0
- python >= 3.9
- kubernetes >= 24.2.0
- PyYAML >= 3.11
@@ -203,9 +203,29 @@ Parameters
</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>
<div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>no_proxy</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
<div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
<div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
<div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>

View File

@@ -25,8 +25,8 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- python >= 3.6
- kubernetes >= 12.0.0
- python >= 3.9
- kubernetes >= 24.2.0
Parameters
@@ -215,6 +215,7 @@ Parameters
</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>
<div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -271,6 +272,25 @@ Parameters
<div>This option is ignored when <em>content</em> is set or when <em>state</em> is set to <code>from_pod</code>.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>no_proxy</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
<div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
<div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
<div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -492,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.
@@ -538,7 +559,7 @@ Examples
state: from_pod
# copy content into a file in the remote pod
- name: Copy /tmp/foo from a remote pod to /tmp/bar locally
- name: Copy content into a file in the remote pod
kubernetes.core.k8s_cp:
state: to_pod
namespace: some-namespace

View File

@@ -29,8 +29,8 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- python >= 3.6
- kubernetes >= 12.0.0
- python >= 3.9
- kubernetes >= 24.2.0
Parameters
@@ -132,6 +132,7 @@ Parameters
</div>
</td>
<td>
<b>Default:</b><br/><div style="color: blue">{}</div>
</td>
<td>
<div>Specify options to delete pods.</div>
@@ -147,6 +148,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.3.0</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
@@ -155,7 +157,7 @@ Parameters
</ul>
</td>
<td>
<div>Continue even if there are pods using emptyDir (local data that will be deleted when the node is drained)</div>
<div>Continue even if there are pods using emptyDir (local data that will be deleted when the node is drained).</div>
</td>
</tr>
<tr>
@@ -334,6 +336,7 @@ Parameters
</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>
<div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -353,6 +356,25 @@ Parameters
<div>The name of the node.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>no_proxy</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
<div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
<div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
<div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -392,6 +414,25 @@ Parameters
<div>The fix for this k8s python library is here: https://github.com/kubernetes-client/python-base/pull/169</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>pod_selectors</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 3.0.0</div>
</td>
<td>
</td>
<td>
<div>Label selector to filter pods on the node.</div>
<div>This option has effect only when <code>state</code> is set to <em>drain</em>.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: label_selectors</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -574,6 +615,14 @@ Examples
state: cordon
name: foo
- name: Drain node "foo" using label selector to filter the list of pods to be drained.
kubernetes.core.k8s_drain:
state: drain
name: foo
pod_selectors:
- 'app!=csi-attacher'
- 'app!=csi-provisioner'
Return Values

View File

@@ -25,8 +25,8 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- python >= 3.6
- kubernetes >= 12.0.0
- python >= 3.9
- kubernetes >= 24.2.0
- PyYAML >= 3.11
@@ -117,7 +117,7 @@ Parameters
<td>
</td>
<td>
<div>The command to execute</div>
<div>The command to execute.</div>
</td>
</tr>
<tr>
@@ -134,6 +134,7 @@ Parameters
<td>
<div>The name of the container in the pod to connect to.</div>
<div>Defaults to only container if there is only one container in the pod.</div>
<div>If not specified, will choose the first container from the given pod as kubectl cmdline does.</div>
</td>
</tr>
<tr>
@@ -214,6 +215,7 @@ Parameters
</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>
<div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -230,7 +232,26 @@ Parameters
<td>
</td>
<td>
<div>The pod namespace name</div>
<div>The pod namespace name.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>no_proxy</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
<div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
<div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
<div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
</td>
</tr>
<tr>
@@ -285,7 +306,7 @@ Parameters
<td>
</td>
<td>
<div>The pod name</div>
<div>The pod name.</div>
</td>
</tr>
<tr>
@@ -302,7 +323,7 @@ Parameters
<td>
<div>The URL of an HTTP proxy to use for the connection.</div>
<div>Can also be specified via <em>K8S_AUTH_PROXY</em> environment variable.</div>
<div>Please note that this module does not pick up typical proxy settings from the environment (e.g. HTTP_PROXY).</div>
<div>Please note that this module does not pick up typical proxy settings from the environment (for example, HTTP_PROXY).</div>
</td>
</tr>
<tr>
@@ -449,6 +470,13 @@ Examples
msg: "cmd failed"
when: command_status.rc != 0
- name: Specify a container name to execute the command on
kubernetes.core.k8s_exec:
namespace: myproject
pod: busybox-test
container: manager
command: echo "hello"
Return Values

View File

@@ -28,8 +28,8 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- python >= 3.6
- kubernetes >= 12.0.0
- python >= 3.9
- kubernetes >= 24.2.0
- PyYAML >= 3.11
@@ -153,11 +153,30 @@ Parameters
</div>
</td>
<td>
<b>Default:</b><br/><div style="color: blue">[]</div>
</td>
<td>
<div>List of field selectors to use to filter results</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 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> 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>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -240,6 +259,7 @@ Parameters
</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>
<div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -254,6 +274,7 @@ Parameters
</div>
</td>
<td>
<b>Default:</b><br/><div style="color: blue">[]</div>
</td>
<td>
<div>List of label selectors to use to filter results</div>
@@ -295,6 +316,25 @@ Parameters
<div>If <em>resource definition</em> is provided, the <em>metadata.namespace</em> value from the <em>resource_definition</em> will override this option.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>no_proxy</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
<div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
<div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
<div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -661,6 +701,21 @@ Examples
wait_sleep: 10
wait_timeout: 360
- name: Wait for OpenShift bootstrap to complete
kubernetes.core.k8s_info:
api_version: v1
kind: ConfigMap
name: bootstrap
namespace: kube-system
register: ocp_bootstrap_status
until: >
ocp_bootstrap_status.resources is defined and
(ocp_bootstrap_status.resources | length > 0) and
(ocp_bootstrap_status.resources[0].data.status is defined) and
(ocp_bootstrap_status.resources[0].data.status == 'complete')
retries: 60
delay: 15
Return Values

View File

@@ -1,359 +0,0 @@
.. _kubernetes.core.k8s_inventory:
*******************
kubernetes.core.k8s
*******************
**Kubernetes (K8s) inventory source**
.. contents::
:local:
:depth: 1
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.6
- kubernetes >= 12.0.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&#x27;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 &#x27;k8s&#x27; plugin.</div>
</td>
</tr>
</table>
<br/>
Examples
--------
.. code-block:: yaml
# File must be named k8s.yaml or k8s.yml
# 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
# Use default config (~/.kube/config) file and active context, and return objects for a specific namespace
plugin: kubernetes.core.k8s
connections:
- namespaces:
- testing
# 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
------
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.

View File

@@ -27,8 +27,8 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- python >= 3.6
- kubernetes >= 12.0.0
- python >= 3.9
- kubernetes >= 24.2.0
- PyYAML >= 3.11
- jsonpatch
@@ -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>
@@ -220,6 +239,7 @@ Parameters
</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>
<div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -256,6 +276,25 @@ Parameters
<div>Use in conjunction with <em>api_version</em>, <em>kind</em>, and <em>name</em> to identify a specific object.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>no_proxy</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
<div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
<div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
<div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -594,7 +633,7 @@ Examples
path: /metadata/labels/app
value: myapp
- op: replace
patch: /spec/containers/0/image
path: /spec/containers/0/image
value: nginx

View File

@@ -28,8 +28,8 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- python >= 3.6
- kubernetes >= 12.0.0
- python >= 3.9
- kubernetes >= 24.2.0
- PyYAML >= 3.11
@@ -44,6 +44,27 @@ Parameters
<th>Choices/<font color="blue">Defaults</font></th>
<th width="100%">Comments</th>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>all_containers</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 2.4.0</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li>no</li>
<li>yes</li>
</ul>
</td>
<td>
<div>If set to <code>true</code>, retrieve all containers&#x27; logs in the pod(s).</div>
<div>mutually exclusive with <code>container</code>.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -141,7 +162,8 @@ Parameters
<td>
<div>Use to specify the container within a pod to grab the log from.</div>
<div>If there is only one container, this will default to that container.</div>
<div>If there is more than one container, this option is required.</div>
<div>If there is more than one container, this option is required or set <em>all_containers</em> to <code>true</code>.</div>
<div>mutually exclusive with <code>all_containers</code>.</div>
</td>
</tr>
<tr>
@@ -240,6 +262,7 @@ Parameters
</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>
<div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -254,6 +277,7 @@ Parameters
</div>
</td>
<td>
<b>Default:</b><br/><div style="color: blue">[]</div>
</td>
<td>
<div>List of label selectors to use to filter results</div>
@@ -295,6 +319,25 @@ Parameters
<div>If <em>resource definition</em> is provided, the <em>metadata.namespace</em> value from the <em>resource_definition</em> will override this option.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>no_proxy</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
<div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
<div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
<div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -334,6 +377,26 @@ Parameters
<div>The fix for this k8s python library is here: https://github.com/kubernetes-client/python-base/pull/169</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>previous</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 2.4.0</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>If <code>true</code>, print the logs for the previous instance of the container in a pod if it exists.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -435,6 +498,22 @@ Parameters
<div>A relative time in seconds before the current time from which to show logs.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>tail_lines</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">integer</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.4.0</div>
</td>
<td>
</td>
<td>
<div>A number of lines from the end of the logs to retrieve.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -519,8 +598,16 @@ Examples
kind: DeploymentConfig
namespace: testing
name: example
tail_lines: 100
register: log
# This will get the logs from all containers in Pod
- name: Get the logs from all containers in pod
kubernetes.core.k8s_log:
namespace: testing
name: some-pod
all_containers: true
Return Values

View File

@@ -26,8 +26,8 @@ Requirements
------------
The below requirements are needed on the local Ansible controller node that executes this lookup.
- python >= 3.6
- kubernetes >= 12.0.0
- python >= 3.9
- kubernetes >= 24.2.0
- PyYAML >= 3.11
@@ -438,106 +438,28 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late
<table border=0 cellpadding=0 class="documentation-table">
<tr>
<th colspan="2">Key</th>
<th colspan="1">Key</th>
<th>Returned</th>
<th width="100%">Description</th>
</tr>
<tr>
<td colspan="2">
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>_list</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">complex</span>
<span style="color: purple">list</span>
/ <span style="color: purple">elements=dictionary</span>
</div>
</td>
<td></td>
<td>
<div>One ore more object definitions returned from the API.</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;">[{&#x27;kind&#x27;: &#x27;ConfigMap&#x27;, &#x27;apiVersion&#x27;: &#x27;v1&#x27;, &#x27;metadata&#x27;: {&#x27;creationTimestamp&#x27;: &#x27;2022-03-04T13:59:49Z&#x27;, &#x27;name&#x27;: &#x27;my-config-map&#x27;, &#x27;namespace&#x27;: &#x27;default&#x27;, &#x27;resourceVersion&#x27;: &#x27;418&#x27;, &#x27;uid&#x27;: &#x27;5714b011-d090-4eac-8272-a0ea82ec0abd&#x27;}, &#x27;data&#x27;: {&#x27;key1&#x27;: &#x27;val1&#x27;}}]</div>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>api_version</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>success</td>
<td>
<div>The versioned schema of this representation of an object.</div>
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>kind</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>success</td>
<td>
<div>Represents the REST resource this object represents.</div>
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>metadata</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">complex</span>
</div>
</td>
<td>success</td>
<td>
<div>Standard object metadata. Includes name, namespace, annotations, labels, etc.</div>
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>spec</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">complex</span>
</div>
</td>
<td>success</td>
<td>
<div>Specific attributes of the object. Will vary based on the <em>api_version</em> and <em>kind</em>.</div>
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>status</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">complex</span>
</div>
</td>
<td>success</td>
<td>
<div>Current status details for the object.</div>
<br/>
</td>
</tr>
</table>
<br/><br/>
@@ -549,8 +471,8 @@ Status
Authors
~~~~~~~
- Chris Houseknecht <@chouseknecht>
- Fabian von Feilitzsch <@fabianvf>
- Chris Houseknecht (@chouseknecht)
- Fabian von Feilitzsch (@fabianvf)
.. hint::

View File

@@ -29,8 +29,8 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- python >= 3.6
- kubernetes >= 12.0.0
- python >= 3.9
- kubernetes >= 24.2.0
- PyYAML >= 3.11
- jsonpatch
@@ -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 &#x27;force=yes&#x27;</div>
<div>mutually exclusive with <code>merge_type</code></div>
<div>Mutually exclusive with <code>merge_type</code>.</div>
</td>
</tr>
<tr>
@@ -208,6 +208,30 @@ Parameters
<div>This has no effect on the validation step which is controlled by the <code>validate.fail_on_error</code> parameter.</div>
</td>
</tr>
<tr>
<td colspan="3">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>delete_all</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 3.0.0</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>When this option is set to <em>true</em> and <em>state=absent</em>, module will delete all resources of the specified resource type in the requested namespace.</div>
<div>Ignored when <code>state</code> is not set to <em>absent</em> or when one of (src), <code>name</code> or <code>resource_definition</code> is provided.</div>
<div>Parameter <code>kind</code> is required to use this option.</div>
<div>This parameter can be used with <code>label_selectors</code> to restrict the resources to be deleted.</div>
<div style="font-size: small; color: darkgreen"><br/>aliases: all</div>
</td>
</tr>
<tr>
<td colspan="3">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -336,6 +360,44 @@ Parameters
<div>If set to <code>yes</code>, and <em>state</em> is <code>present</code>, an existing object will be replaced.</div>
</td>
</tr>
<tr>
<td colspan="3">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>generate_name</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<div>Use to specify the basis of an object name and random characters will be added automatically on server to generate a unique name.</div>
<div>This option is ignored when <em>state</em> is not set to <code>present</code> or when <em>apply</em> is set to <code>yes</code>.</div>
<div>If <em>resource definition</em> is provided, the <em>metadata.generateName</em> value from the <em>resource_definition</em> will override this option.</div>
<div>If <em>resource definition</em> is provided, and contains <em>metadata.name</em>, this option is ignored.</div>
<div>mutually exclusive with <code>name</code>.</div>
</td>
</tr>
<tr>
<td colspan="3">
<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 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> 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>
<td colspan="3">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -417,6 +479,7 @@ Parameters
</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>
<div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -449,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&#x27;t updatable by the usual strategic merge. You may want to use <code>merge</code> if you see &quot;strategic merge patch format is not supported&quot;</div>
<div>For example, Custom Resource Definitions typically aren&#x27;t updatable by the usual strategic merge. You may want to use <code>merge</code> if you see &quot;strategic merge patch format is not supported&quot;.</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>[&#x27;strategic-merge&#x27;, &#x27;merge&#x27;]</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>
@@ -499,6 +561,25 @@ Parameters
<div>If <em>resource definition</em> is provided, the <em>metadata.namespace</em> value from the <em>resource_definition</em> will override this option.</div>
</td>
</tr>
<tr>
<td colspan="3">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>no_proxy</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
<div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
<div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
<div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
</td>
</tr>
<tr>
<td colspan="3">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -640,6 +721,63 @@ Parameters
<div style="font-size: small; color: darkgreen"><br/>aliases: definition, inline</div>
</td>
</tr>
<tr>
<td colspan="3">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>server_side_apply</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 2.3.0</div>
</td>
<td>
</td>
<td>
<div>When this option is set, apply runs in the server instead of the client.</div>
<div>Ignored if <code>apply</code> is not set or is set to False.</div>
<div>This option requires &quot;kubernetes &gt;= 19.15.0&quot;.</div>
</td>
</tr>
<tr>
<td class="elbow-placeholder"></td>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>field_manager</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>Name of the manager used to track field ownership.</div>
</td>
</tr>
<tr>
<td class="elbow-placeholder"></td>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>force_conflicts</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">boolean</span>
</div>
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li><div style="color: blue"><b>no</b>&nbsp;&larr;</div></li>
<li>yes</li>
</ul>
</td>
<td>
<div>A conflict is a special status error that occurs when an Server Side Apply operation tries to change a field, which another user also claims to manage.</div>
<div>When set to True, server-side apply will force the changes against conflicts.</div>
</td>
</tr>
<tr>
<td colspan="3">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -654,7 +792,8 @@ Parameters
<td>
<div>Provide a path to a file containing a valid YAML definition of an object or objects to be created or updated. Mutually exclusive with <em>resource_definition</em>. NOTE: <em>kind</em>, <em>api_version</em>, <em>name</em>, and <em>namespace</em> will be overwritten by corresponding values found in the configuration read in from the <em>src</em> file.</div>
<div>Reads from the local file system. To read from the Ansible controller&#x27;s file system, including vaulted files, use the file lookup plugin or template lookup plugin, combined with the from_yaml filter, and pass the result to <em>resource_definition</em>. See Examples below.</div>
<div>Mutually exclusive with <em>template</em> in case of <span class='module'>k8s</span> module.</div>
<div>The URL to manifest files that can be used to create the resource. Added in version 2.4.0.</div>
<div>Mutually exclusive with <em>template</em> in case of <span class='module'>kubernetes.core.k8s</span> module.</div>
</td>
</tr>
<tr>
@@ -1016,6 +1155,14 @@ Examples
state: present
definition: "{{ lookup('file', '/testing/deployment.yml') | from_yaml }}"
- name: >-
(Alternative) Read definition file from the Ansible controller file system.
In this case, the definition file contains multiple YAML documents, separated by ---.
If the definition file has been encrypted with Ansible Vault it will automatically be decrypted.
kubernetes.core.k8s:
state: present
definition: "{{ lookup('file', '/testing/deployment.yml') | from_yaml_all }}"
- name: Read definition template file from the Ansible controller file system
kubernetes.core.k8s:
state: present
@@ -1033,10 +1180,10 @@ Examples
kubernetes.core.k8s:
state: present
template:
- path: '/testing/deployment_one.j2'
- path: '/testing/deployment_two.j2'
variable_start_string: '[['
variable_end_string: ']]'
- path: '/testing/deployment_one.j2'
- path: '/testing/deployment_two.j2'
variable_start_string: '[['
variable_end_string: ']]'
- name: fail on validation errors
kubernetes.core.k8s:
@@ -1093,6 +1240,41 @@ Examples
labels:
support: patch
# Create object using generateName
- name: create resource using name generated by the server
kubernetes.core.k8s:
state: present
generate_name: pod-
definition:
apiVersion: v1
kind: Pod
spec:
containers:
- name: py
image: python:3.7-alpine
imagePullPolicy: IfNotPresent
# Server side apply
- name: Create configmap using server side apply
kubernetes.core.k8s:
namespace: testing
definition:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-configmap
apply: yes
server_side_apply:
field_manager: ansible
# Delete all Deployment from specified namespace
- name: Delete all Deployment from specified namespace
kubernetes.core.k8s:
api_version: apps/v1
namespace: testing
kind: Deployment
delete_all: true
Return Values

View File

@@ -27,8 +27,8 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- python >= 3.6
- kubernetes >= 12.0.0
- python >= 3.9
- kubernetes >= 24.2.0
- PyYAML >= 3.11
@@ -152,6 +152,7 @@ Parameters
</div>
</td>
<td>
<b>Default:</b><br/><div style="color: blue">[]</div>
</td>
<td>
<div>List of field selectors to use to filter results.</div>
@@ -238,6 +239,7 @@ Parameters
</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>
<div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -252,6 +254,7 @@ Parameters
</div>
</td>
<td>
<b>Default:</b><br/><div style="color: blue">[]</div>
</td>
<td>
<div>List of label selectors to use to filter results.</div>
@@ -293,6 +296,25 @@ Parameters
<div>If <em>resource definition</em> is provided, the <em>metadata.namespace</em> value from the <em>resource_definition</em> will override this option.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>no_proxy</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
<div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
<div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
<div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>

View File

@@ -25,8 +25,8 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- python >= 3.6
- kubernetes >= 12.0.0
- python >= 3.9
- kubernetes >= 24.2.0
- PyYAML >= 3.11
@@ -255,6 +255,7 @@ Parameters
</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>
<div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -270,6 +271,7 @@ Parameters
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.0.0</div>
</td>
<td>
<b>Default:</b><br/><div style="color: blue">[]</div>
</td>
<td>
<div>List of label selectors to use to filter results.</div>
@@ -311,6 +313,25 @@ Parameters
<div>If <em>resource definition</em> is provided, the <em>metadata.namespace</em> value from the <em>resource_definition</em> will override this option.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>no_proxy</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
<div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
<div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
<div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -497,7 +518,8 @@ Parameters
<td>
<div>Provide a path to a file containing a valid YAML definition of an object or objects to be created or updated. Mutually exclusive with <em>resource_definition</em>. NOTE: <em>kind</em>, <em>api_version</em>, <em>name</em>, and <em>namespace</em> will be overwritten by corresponding values found in the configuration read in from the <em>src</em> file.</div>
<div>Reads from the local file system. To read from the Ansible controller&#x27;s file system, including vaulted files, use the file lookup plugin or template lookup plugin, combined with the from_yaml filter, and pass the result to <em>resource_definition</em>. See Examples below.</div>
<div>Mutually exclusive with <em>template</em> in case of <span class='module'>k8s</span> module.</div>
<div>The URL to manifest files that can be used to create the resource. Added in version 2.4.0.</div>
<div>Mutually exclusive with <em>template</em> in case of <span class='module'>kubernetes.core.k8s</span> module.</div>
</td>
</tr>
<tr>

View File

@@ -24,8 +24,8 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- python >= 3.6
- kubernetes >= 12.0.0
- python >= 3.9
- kubernetes >= 24.2.0
Parameters
@@ -220,6 +220,7 @@ Parameters
</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>
<div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>
@@ -280,6 +281,25 @@ Parameters
<div>Use to specify a Service object namespace.</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>no_proxy</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">string</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.3.0</div>
</td>
<td>
</td>
<td>
<div>The comma separated list of hosts/domains/IP/CIDR that shouldn&#x27;t go through proxy. Can also be specified via K8S_AUTH_NO_PROXY environment variable.</div>
<div>Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).</div>
<div>This feature requires kubernetes&gt;=19.15.0. When kubernetes library is less than 19.15.0, it fails even no_proxy set in correct.</div>
<div>example value is &quot;localhost,.local,.example.com,127.0.0.1,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16&quot;</div>
</td>
</tr>
<tr>
<td colspan="2">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -468,7 +488,8 @@ Parameters
<td>
<div>Provide a path to a file containing a valid YAML definition of an object or objects to be created or updated. Mutually exclusive with <em>resource_definition</em>. NOTE: <em>kind</em>, <em>api_version</em>, <em>name</em>, and <em>namespace</em> will be overwritten by corresponding values found in the configuration read in from the <em>src</em> file.</div>
<div>Reads from the local file system. To read from the Ansible controller&#x27;s file system, including vaulted files, use the file lookup plugin or template lookup plugin, combined with the from_yaml filter, and pass the result to <em>resource_definition</em>. See Examples below.</div>
<div>Mutually exclusive with <em>template</em> in case of <span class='module'>k8s</span> module.</div>
<div>The URL to manifest files that can be used to create the resource. Added in version 2.4.0.</div>
<div>Mutually exclusive with <em>template</em> in case of <span class='module'>kubernetes.core.k8s</span> module.</div>
</td>
</tr>
<tr>

View File

@@ -26,8 +26,8 @@ Requirements
------------
The below requirements are needed on the host that executes this module.
- python >= 3.6
- kubernetes >= 12.0.0
- python >= 3.9
- kubernetes >= 24.2.0
Parameters
@@ -182,6 +182,7 @@ Parameters
</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>
<div>Multiple Kubernetes config file can be provided using separator &#x27;;&#x27; for Windows platform or &#x27;:&#x27; for others platforms.</div>
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version &gt;= 17.17.0. Added in version 2.2.0.</div>
</td>
</tr>

View File

@@ -8,7 +8,6 @@ kubernetes.core.kubectl
**Execute tasks in pods running on Kubernetes.**
Version added: 1.2.1
.. contents::
:local:
@@ -209,6 +208,28 @@ Parameters
</td>
<td>
<div>Path to a kubectl config file. Defaults to <em>~/.kube/config</em></div>
<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>
@@ -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 }}"
@@ -355,7 +452,7 @@ Status
Authors
~~~~~~~
- xuxinkun
- xuxinkun (@xuxinkun)
.. hint::

View File

@@ -77,6 +77,44 @@ Parameters
<div>If omitted, &#x27;.&#x27; 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
@@ -133,106 +183,27 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late
<table border=0 cellpadding=0 class="documentation-table">
<tr>
<th colspan="2">Key</th>
<th colspan="1">Key</th>
<th>Returned</th>
<th width="100%">Description</th>
</tr>
<tr>
<td colspan="2">
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>_list</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">complex</span>
<span style="color: purple">string</span>
</div>
</td>
<td></td>
<td>
<div>One ore more object definitions returned from the tool execution.</div>
<div>YAML string for the object definitions returned from the tool execution.</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;">{&#x27;kind&#x27;: &#x27;ConfigMap&#x27;, &#x27;apiVersion&#x27;: &#x27;v1&#x27;, &#x27;metadata&#x27;: {&#x27;name&#x27;: &#x27;my-config-map&#x27;, &#x27;namespace&#x27;: &#x27;default&#x27;}, &#x27;data&#x27;: {&#x27;key1&#x27;: &#x27;val1&#x27;}}</div>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>api_version</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>success</td>
<td>
<div>The versioned schema of this representation of an object.</div>
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>kind</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>success</td>
<td>
<div>Represents the REST resource this object represents.</div>
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>metadata</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">complex</span>
</div>
</td>
<td>success</td>
<td>
<div>Standard object metadata. Includes name, namespace, annotations, labels, etc.</div>
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>spec</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">complex</span>
</div>
</td>
<td>success</td>
<td>
<div>Specific attributes of the object. Will vary based on the <em>api_version</em> and <em>kind</em>.</div>
<br/>
</td>
</tr>
<tr>
<td class="elbow-placeholder">&nbsp;</td>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>status</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">complex</span>
</div>
</td>
<td>success</td>
<td>
<div>Current status details for the object.</div>
<br/>
</td>
</tr>
</table>
<br/><br/>
@@ -244,7 +215,7 @@ Status
Authors
~~~~~~~
- Aubin Bikouo <@abikouo>
- Aubin Bikouo (@abikouo)
.. hint::

View File

@@ -25,7 +25,7 @@ tags:
- openshift
- okd
- cluster
version: 2.4.0
version: 6.4.0
build_ignore:
- .DS_Store
- "*.tar.gz"

View File

@@ -1,5 +1,5 @@
---
requires_ansible: '>=2.14.0'
requires_ansible: '>=2.16.0'
action_groups:
helm:
@@ -8,24 +8,26 @@ action_groups:
- helm_repository
k8s:
- k8s
- k8s_exec
- k8s_info
- k8s_log
- k8s_scale
- k8s_service
- k8s_cluster_info
- k8s_cp
- k8s_drain
- k8s_exec
- k8s_info
- k8s_json_patch
- k8s_log
- k8s_rollback
- k8s_scale
- k8s_service
plugin_routing:
inventory:
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

View File

@@ -20,35 +20,22 @@ from ansible.errors import (
AnsibleError,
AnsibleFileNotFound,
)
from ansible.module_utils._text import to_bytes, to_native, to_text
from ansible.module_utils.common.text.converters 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

View File

@@ -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
@@ -180,7 +264,8 @@ import subprocess
import tempfile
from ansible.errors import AnsibleError, AnsibleFileNotFound
from ansible.module_utils._text import to_bytes
from ansible.module_utils.common.text.converters import to_bytes
from ansible.module_utils.parsing.convert_bool import boolean
from ansible.module_utils.six.moves import shlex_quote
from ansible.parsing.yaml.loader import AnsibleLoader
from ansible.plugins.connection import BUFSIZE, ConnectionBase
@@ -240,9 +325,12 @@ class Connection(ConnectionBase):
# Build command options based on doc string
doc_yaml = AnsibleLoader(self.documentation).get_single_data()
for key in doc_yaml.get("options"):
if key.endswith("verify_ssl") and self.get_option(key) != "":
# Translate verify_ssl to skip_verify_ssl, and output as string
skip_verify_ssl = not self.get_option(key)
if key == "validate_certs" and self.get_option(key) != "":
# Translate validate_certs to --insecure-skip-tls-verify flag
# validate_certs=True means verify certs (don't skip verification)
# validate_certs=False means don't verify certs (skip verification)
validate_certs_value = boolean(self.get_option(key), strict=False)
skip_verify_ssl = not validate_certs_value
local_cmd.append(
"{0}={1}".format(
self.connection_options[key], str(skip_verify_ssl).lower()
@@ -301,6 +389,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 +430,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 +480,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 +521,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(

View File

@@ -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
"""

View File

@@ -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).

View File

@@ -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
)

View File

@@ -86,14 +86,48 @@ DOCUMENTATION = """
description:
- Provide a username for authenticating with the API. Can also be specified via K8S_AUTH_USERNAME environment
variable.
no_proxy:
description:
- The comma separated list of hosts/domains/IP/CIDR that shouldn't go through proxy.
Can also be specified via K8S_AUTH_NO_PROXY environment variable.
- Please note that this module does not pick up typical proxy settings from the environment (e.g. NO_PROXY).
- This feature requires kubernetes>=19.15.0.
When kubernetes library is less than 19.15.0, it fails even if no_proxy is set correctly.
type: str
password:
description:
- Provide a password for authenticating with the API. Can also be specified via K8S_AUTH_PASSWORD environment
variable.
proxy:
description:
- The URL of an HTTP proxy to use for the connection. Can also be specified via K8S_AUTH_PROXY environment variable.
- Please note that this module does not pick up typical proxy settings from the environment (e.g. HTTP_PROXY).
type: str
proxy_headers:
description:
- The Header used for the HTTP proxy.
- Documentation can be found here
U(https://urllib3.readthedocs.io/en/latest/reference/urllib3.util.html?highlight=proxy_headers#urllib3.util.make_headers).
type: dict
suboptions:
proxy_basic_auth:
type: str
description:
- Colon-separated username:password for proxy basic authentication header.
- Can also be specified via K8S_AUTH_PROXY_HEADERS_PROXY_BASIC_AUTH environment.
basic_auth:
type: str
description:
- Colon-separated username:password for basic authentication header.
- Can also be specified via K8S_AUTH_PROXY_HEADERS_BASIC_AUTH environment.
user_agent:
type: str
description:
- String representing the user-agent you want, such as foo/1.0.
- Can also be specified via K8S_AUTH_PROXY_HEADERS_USER_AGENT environment.
client_cert:
description:
- Path to a certificate used to authenticate with the API. Can also be specified via K8S_AUTH_CERT_FILE
environment
- 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:

View File

@@ -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")]

View File

@@ -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,

View File

@@ -1,16 +1,64 @@
from __future__ import absolute_import, division, print_function
from ansible.module_utils.six import string_types
__metaclass__ = type
import warnings
def list_dict_str(value):
if isinstance(value, (list, dict, string_types)):
if isinstance(value, (list, dict, str)):
return value
raise TypeError
def extract_sensitive_values_from_kubeconfig(kubeconfig_data):
"""
Extract only sensitive string values from kubeconfig data for no_log_values.
:arg kubeconfig_data: Dictionary containing kubeconfig data
:returns: Set of sensitive string values to be added to no_log_values
"""
values = set()
sensitive_fields = {
"token",
"password",
"secret",
"client-key-data",
"client-certificate-data",
"certificate-authority-data",
"api_key",
"access-token",
"refresh-token",
}
# Check API version and warn if not v1
if isinstance(kubeconfig_data, dict):
api_version = kubeconfig_data.get("apiVersion", "v1")
if api_version != "v1":
warnings.warn(
f"Kubeconfig API version '{api_version}' is not 'v1'. "
f"Sensitive field redaction is only guaranteed for API version 'v1'. "
f"Some sensitive data may not be properly redacted from the logs.",
UserWarning,
)
def _extract_recursive(data, current_path=""):
if isinstance(data, dict):
for key, value in data.items():
path = f"{current_path}.{key}" if current_path else key
if key in sensitive_fields:
if isinstance(value, str):
values.add(value)
else:
_extract_recursive(value, path)
elif isinstance(data, list):
for i, item in enumerate(data):
_extract_recursive(item, f"{current_path}[{i}]")
_extract_recursive(kubeconfig_data)
return values
AUTH_PROXY_HEADERS_SPEC = dict(
proxy_basic_auth=dict(type="str", no_log=True),
basic_auth=dict(type="str", no_log=True),

View File

@@ -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

View File

@@ -23,7 +23,7 @@ from abc import ABCMeta, abstractmethod
from select import select
from tempfile import NamedTemporaryFile, TemporaryFile
from ansible.module_utils._text import to_native
from ansible.module_utils.common.text.converters import to_native
# from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import AnsibleModule
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.exceptions import (
@@ -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)
)
)
@@ -278,11 +278,15 @@ class K8SCopyFromPod(K8SCopy):
def run(self):
self.files_to_copy = self.list_remote_files()
if self.files_to_copy == []:
# Using warn method instead of passing warnings to exit_json as it is
# deprecated in ansible-core>=2.19.0
self._module.warn(
"No file found from directory '{0}' into remote Pod.".format(
self.remote_path
)
)
self.module.exit_json(
changed=False,
warning="No file found from directory '{0}' into remote Pod.".format(
self.remote_path
),
)
self.copy()
@@ -435,11 +439,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)

View File

@@ -15,7 +15,9 @@ 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.args_common import (
extract_sensitive_values_from_kubeconfig,
)
from ansible_collections.kubernetes.core.plugins.module_utils.version import (
LooseVersion,
)
@@ -38,16 +40,20 @@ def parse_helm_plugin_list(output=None):
if not output:
return ret
parsing_grammar = None
for line in output:
if line.startswith("NAME"):
parsing_grammar = [s.strip().lower() for s in line.split("\t")]
continue
name, version, description = line.split("\t", 3)
name = name.strip()
version = version.strip()
description = description.strip()
if name == "":
if parsing_grammar is None:
continue
ret.append((name, version, description))
plugin = {
parsing_grammar[i]: v.strip()
for i, v in enumerate(line.split("\t", len(parsing_grammar)))
}
if plugin["name"] == "":
continue
ret.append(plugin)
return ret
@@ -77,7 +83,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,12 +119,19 @@ 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
# Redact sensitive fields from kubeconfig for logging purposes
if kubeconfig_content:
# Add original sensitive values to no_log_values to prevent them from appearing in logs
self._module.no_log_values.update(
extract_sensitive_values_from_kubeconfig(kubeconfig_content)
)
if self.params.get("ca_cert"):
ca_cert = self.params.get("ca_cert")
if LooseVersion(self.get_helm_version()) < LooseVersion("3.5.0"):
@@ -160,11 +172,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,14 +198,46 @@ 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
def is_helm_v4(self):
helm_version = self.get_helm_version()
if helm_version is None:
return False
return LooseVersion(helm_version) >= LooseVersion("4.0.0")
def is_helm_version_compatible_with_helm_diff(self, helm_diff_version):
"""
Return true if the helm version is compatible with the helm diff version
Helm v4 requires helm diff v3.14.0
"""
if not helm_diff_version:
return False
if self.is_helm_v4():
return LooseVersion(helm_diff_version) >= LooseVersion("3.14.0")
return True
def validate_helm_version(self, version="3.0.0"):
"""
Validate that Helm version is >= version (default version=3.0.0).
"""
helm_version = self.get_helm_version()
if helm_version is None:
self.fail_json(msg="Unable to determine Helm version")
if LooseVersion(helm_version) < LooseVersion(version):
self.fail_json(
msg="Helm version must be >= {0}, current version is {1}".format(
version, helm_version
)
)
def get_values(self, release_name, get_all=False):
"""
Get Values from deployed release

View File

@@ -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(

View File

@@ -3,6 +3,9 @@ from typing import Optional
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.common.text.converters import to_text
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
extract_sensitive_values_from_kubeconfig,
)
from ansible_collections.kubernetes.core.plugins.module_utils.version import (
LooseVersion,
)
@@ -33,6 +36,15 @@ class AnsibleK8SModule:
self._module = self.settings["module_class"](**kwargs)
# Apply kubeconfig redaction for logging purposes
if hasattr(self._module, "params") and hasattr(self._module, "no_log_values"):
kubeconfig = self._module.params.get("kubeconfig")
if kubeconfig and isinstance(kubeconfig, dict):
# Add sensitive values to no_log_values to prevent them from appearing in logs
self._module.no_log_values.update(
extract_sensitive_values_from_kubeconfig(kubeconfig)
)
if self.settings["check_k8s"]:
self.requires("kubernetes")
self.has_at_least("kubernetes", "24.2.0", warn=True)

View File

@@ -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)

View File

@@ -3,7 +3,7 @@
from typing import Dict
from ansible.module_utils._text import to_native
from ansible.module_utils.common.text.converters import to_native
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
get_api_client,
)
@@ -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

View File

@@ -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="3.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

View File

@@ -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,
}

View File

@@ -0,0 +1,91 @@
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import hashlib
import os
import traceback
try:
import yaml
IMP_YAML = True
IMP_YAML_ERR = None
except ImportError:
IMP_YAML = False
IMP_YAML_ERR = traceback.format_exc()
def load_yaml_file(path):
if not path or not os.path.exists(path):
return {}
with open(path, "r") as f:
return yaml.safe_load(f) or {}
def deep_merge(base, updates):
result = base.copy()
for key, value in updates.items():
if key in result and isinstance(result[key], dict) and isinstance(value, dict):
result[key] = deep_merge(result[key], value)
else:
result[key] = value
return result
def merge_by_name(existing, new):
merged = {}
for item in existing:
if isinstance(item, dict) and "name" in item:
merged[item["name"]] = item
for item in new:
if not isinstance(item, dict) or "name" not in item:
continue
name = item["name"]
behavior = item.get("behavior", "merge")
item_copy = {k: v for k, v in item.items() if k != "behavior"}
if name in merged:
if behavior == "keep":
continue
elif behavior == "replace":
merged[name] = item_copy
else:
result = {"name": name}
for key in ["cluster", "user", "context"]:
if key in merged[name] or key in item_copy:
existing_config = merged[name].get(key, {})
new_config = item_copy.get(key, {})
result[key] = deep_merge(existing_config, new_config)
for key in merged[name]:
if key not in ["name", "cluster", "user", "context"]:
result[key] = merged[name][key]
for key in item_copy:
if (
key not in ["name", "cluster", "user", "context"]
and key not in result
):
result[key] = item_copy[key]
merged[name] = result
else:
merged[name] = item_copy
return list(merged.values())
def hash_data(data):
"""Generate SHA-256 hash for idempotency checking."""
return hashlib.sha256(yaml.safe_dump(data, sort_keys=True).encode()).hexdigest()
def write_file(dest, data):
if not dest:
return False
with open(dest, "w") as f:
yaml.safe_dump(data, f, sort_keys=False)
return True

View File

@@ -14,14 +14,14 @@ 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)
- Matthieu Diehr (@d-matt)
requirements:
- "helm (https://github.com/helm/helm/releases)"
- "helm >= 3.0.0 (https://github.com/helm/helm/releases)"
- "yaml (https://pypi.org/project/PyYAML/)"
description:
@@ -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:
- 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:
@@ -373,9 +419,18 @@ status:
returned: always
description: The Date of last update
values:
type: str
type: dict
returned: always
description: Dict of Values used to deploy
description:
- Dict of Values used to deploy.
- This return value has been deprecated and will be removed in a release after
2027-01-08. Use RV(status.release_values) instead.
release_values:
type: dict
returned: always
description:
- Dict of Values used to deploy.
version_added: 6.3.0
stdout:
type: str
description: Full `helm` command stdout, in case you want to display it or examine the event log
@@ -445,9 +500,13 @@ def get_release_status(module, release_name, all_status=False):
"--filter",
release_name,
]
if all_status:
if all_status and not module.is_helm_v4():
# --all has been removed from `helm list` command on helm v4
list_command.append("--all")
elif not all_status:
# The default behavior to display only deployed releases has been removed from
# Helm v4
list_command.append("--deployed")
rc, out, err = module.run_helm_command(list_command)
release = get_release(yaml.safe_load(out), release_name)
@@ -455,7 +514,8 @@ def get_release_status(module, release_name, all_status=False):
if release is None: # not install
return None
release["values"] = module.get_values(release_name)
release["release_values"] = module.get_values(release_name)
release["values"] = release["release_values"]
return release
@@ -476,12 +536,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 +585,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 +603,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 +643,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 +680,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
@@ -624,8 +743,8 @@ def get_plugin_version(plugin):
return None
for line in out:
if line[0] == plugin:
return line[1]
if line["name"] == plugin:
return line["version"]
return None
@@ -639,6 +758,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 +778,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 +793,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 +901,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
@@ -750,6 +932,9 @@ def main():
if not IMP_YAML:
module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR)
# Validate Helm version >=3.0.0
module.validate_helm_version()
changed = False
chart_ref = module.params.get("chart_ref")
@@ -778,6 +963,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 +977,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'
@@ -797,8 +1014,7 @@ def main():
if wait:
helm_version = module.get_helm_version()
if LooseVersion(helm_version) < LooseVersion("3.7.0"):
opt_result["warnings"] = []
opt_result["warnings"].append(
module.warn(
"helm uninstall support option --wait for helm release >= 3.7.0"
)
wait = False
@@ -815,7 +1031,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 +1065,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,19 +1092,31 @@ 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
else:
helm_diff_version = get_plugin_version("diff")
if helm_diff_version and (
not chart_repo_url
or (
chart_repo_url
and LooseVersion(helm_diff_version) >= LooseVersion("3.4.1")
helm_version_compatible = module.is_helm_version_compatible_with_helm_diff(
helm_diff_version
)
if (
helm_diff_version
and helm_version_compatible
and (
not chart_repo_url
or (
chart_repo_url
and LooseVersion(helm_diff_version) >= LooseVersion("3.4.1")
)
)
):
(would_change, prepared) = helmdiff_check(
would_change, prepared = helmdiff_check(
module,
release_name,
chart_ref,
@@ -896,23 +1126,34 @@ 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}
else:
module.warn(
"The default idempotency check can fail to report changes in certain cases. "
"Install helm diff >= 3.4.1 for better results."
)
if helm_diff_version and not helm_version_compatible:
module.warn(
"Idempotency checks are currently disabled due to a version mismatch."
f" Helm version {module.get_helm_version()} requires helm-diff >= 3.14.0,"
f" but the environment is currently running {helm_diff_version}."
" Please align the plugin versions to restore standard behavior."
)
else:
module.warn(
"The default idempotency check can fail to report changes in certain cases. "
"Install helm diff >= 3.4.1 for better results."
)
would_change = default_check(
release_status, chart_info, release_values, values_files
)
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,14 +1176,24 @@ 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
if module.check_mode:
check_status = {"values": {"current": {}, "declared": {}}}
check_status = {
"values": {"current": {}, "declared": {}},
"release_values": {"current": {}, "declared": {}},
}
if release_status:
check_status["values"]["current"] = release_status["values"]
check_status["values"]["current"] = release_status["release_values"]
check_status["values"]["declared"] = release_status
check_status["release_values"]["current"] = release_status["release_values"]
check_status["release_values"]["declared"] = release_status
module.exit_json(
changed=changed,

View File

@@ -14,13 +14,13 @@ 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)
requirements:
- "helm (https://github.com/helm/helm/releases)"
- "helm >= 3.0.0 (https://github.com/helm/helm/releases)"
- "yaml (https://pypi.org/project/PyYAML/)"
description:
@@ -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
"""
@@ -115,26 +115,35 @@ status:
returned: always
description: The Date of last update
values:
type: str
type: dict
returned: always
description: Dict of Values used to deploy
description:
- Dict of Values used to deploy
- This return value has been deprecated and will be removed in a release after
2027-01-08. Use RV(status.release_values) instead.
release_values:
type: dict
returned: always
description:
- Dict of Values used to deploy.
version_added: 6.3.0
hooks:
type: list
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
@@ -202,7 +211,8 @@ def get_release_status(module, release_name, release_state, get_all_values=False
if release is None: # not install
return None
release["values"] = module.get_values(release_name, get_all_values)
release["release_values"] = module.get_values(release_name, get_all_values)
release["values"] = release["release_values"]
release["manifest"] = module.get_manifest(release_name)
release["notes"] = module.get_notes(release_name)
release["hooks"] = module.get_hooks(release_name)
@@ -235,6 +245,9 @@ def main():
if not IMP_YAML:
module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR)
# Validate Helm version >=3.0.0
module.validate_helm_version()
release_name = module.params.get("release_name")
release_state = module.params.get("release_state")
get_all_values = module.params.get("get_all_values")

View File

@@ -12,11 +12,11 @@ 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:
- "helm (https://github.com/helm/helm/releases)"
- "helm >= 3.0.0 (https://github.com/helm/helm/releases)"
description:
- Manages Helm plugins.
options:
@@ -47,7 +47,15 @@ options:
- Ignored when C(state=absent) or C(state=latest).
required: false
type: str
version_added: "2.3.0"
version_added: 2.3.0
verify:
description:
- Verify the plugin signature before installing.
- This option requires helm version >= 4.0.0
- Used with I(state=present).
type: bool
default: true
version_added: 6.4.0
extends_documentation_fragment:
- kubernetes.core.helm_common_options
"""
@@ -118,6 +126,9 @@ from ansible_collections.kubernetes.core.plugins.module_utils.helm_args_common i
HELM_AUTH_ARG_SPEC,
HELM_AUTH_MUTUALLY_EXCLUSIVE,
)
from ansible_collections.kubernetes.core.plugins.module_utils.version import (
LooseVersion,
)
def argument_spec():
@@ -138,6 +149,10 @@ def argument_spec():
default="present",
choices=["present", "absent", "latest"],
),
verify=dict(
type="bool",
default=True,
),
)
)
return arg_spec
@@ -161,6 +176,9 @@ def main():
mutually_exclusive=mutually_exclusive(),
)
# Validate helm version >= 3.0.0
module.validate_helm_version()
state = module.params.get("state")
helm_cmd_common = module.get_helm_binary() + " plugin"
@@ -168,8 +186,19 @@ def main():
if state == "present":
helm_cmd_common += " install %s" % module.params.get("plugin_path")
plugin_version = module.params.get("plugin_version")
verify = module.params.get("verify")
if plugin_version is not None:
helm_cmd_common += " --version=%s" % plugin_version
if not verify:
helm_version = module.get_helm_version()
if LooseVersion(helm_version) < LooseVersion("4.0.0"):
module.warn(
"verify parameter requires helm >= 4.0.0, current version is {0}".format(
helm_version
)
)
else:
helm_cmd_common += " --verify=false"
if not module.check_mode:
rc, out, err = module.run_helm_command(
helm_cmd_common, fails_on_error=False
@@ -208,9 +237,9 @@ def main():
elif state == "absent":
plugin_name = module.params.get("plugin_name")
rc, output, err, command = module.get_helm_plugin_list()
out = parse_helm_plugin_list(output=output.splitlines())
plugins = parse_helm_plugin_list(output=output.splitlines())
if not out:
if not plugins:
module.exit_json(
failed=False,
changed=False,
@@ -221,12 +250,7 @@ def main():
rc=rc,
)
found = False
for line in out:
if line[0] == plugin_name:
found = True
break
if not found:
if all(plugin["name"] != plugin_name for plugin in plugins):
module.exit_json(
failed=False,
changed=False,
@@ -264,9 +288,9 @@ def main():
elif state == "latest":
plugin_name = module.params.get("plugin_name")
rc, output, err, command = module.get_helm_plugin_list()
out = parse_helm_plugin_list(output=output.splitlines())
plugins = parse_helm_plugin_list(output=output.splitlines())
if not out:
if not plugins:
module.exit_json(
failed=False,
changed=False,
@@ -277,12 +301,7 @@ def main():
rc=rc,
)
found = False
for line in out:
if line[0] == plugin_name:
found = True
break
if not found:
if all(plugin["name"] != plugin_name for plugin in plugins):
module.exit_json(
failed=False,
changed=False,

View File

@@ -12,11 +12,11 @@ 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:
- "helm (https://github.com/helm/helm/releases)"
- "helm >= 3.0.0 (https://github.com/helm/helm/releases)"
description:
- Gather information about Helm plugins installed in namespace.
options:
@@ -98,26 +98,16 @@ def main():
supports_check_mode=True,
)
plugin_name = module.params.get("plugin_name")
# Validate helm version >= 3.0.0
module.validate_helm_version()
plugin_list = []
plugin_name = module.params.get("plugin_name")
rc, output, err, command = module.get_helm_plugin_list()
out = parse_helm_plugin_list(output=output.splitlines())
for line in out:
if plugin_name is None:
plugin_list.append(
{"name": line[0], "version": line[1], "description": line[2]}
)
continue
if plugin_name == line[0]:
plugin_list.append(
{"name": line[0], "version": line[1], "description": line[2]}
)
break
plugins = parse_helm_plugin_list(output=output.splitlines())
if plugin_name is not None:
plugins = [plugin for plugin in plugins if plugin.get("name") == plugin_name]
module.exit_json(
changed=True,
@@ -125,7 +115,7 @@ def main():
stdout=output,
stderr=err,
rc=rc,
plugin_list=plugin_list,
plugin_list=plugins,
)

View File

@@ -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:
@@ -21,7 +21,7 @@ description:
- There are options for unpacking the chart after download.
requirements:
- "helm >= 3.0 (https://github.com/helm/helm/releases)"
- "helm >= 3.0.0 (https://github.com/helm/helm/releases)"
options:
chart_ref:
@@ -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'.
@@ -88,6 +89,14 @@ options:
- if set to true, will untar the chart after downloading it.
type: bool
default: False
force:
description:
- Force download of the chart even if it already exists in the destination directory.
- By default, the module will skip downloading if the chart with the same version already exists for idempotency.
- When used with O(untar_chart=true), will remove any existing chart directory before extracting.
type: bool
default: False
version_added: 6.3.0
destination:
description:
- location to write the chart.
@@ -113,6 +122,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"""
@@ -144,6 +160,23 @@ EXAMPLES = r"""
destination: /path/to/chart
username: myuser
password: mypassword123
- name: Download Chart (force re-download even if exists)
kubernetes.core.helm_pull:
chart_ref: redis
repo_url: https://charts.bitnami.com/bitnami
chart_version: '17.0.0'
destination: /path/to/chart
force: yes
- name: Download and untar chart (force re-extraction even if directory exists)
kubernetes.core.helm_pull:
chart_ref: redis
repo_url: https://charts.bitnami.com/bitnami
chart_version: '17.0.0'
destination: /path/to/chart
untar_chart: yes
force: yes
"""
RETURN = r"""
@@ -162,6 +195,11 @@ command:
description: Full `helm pull` command built by this module, in case you want to re-run the command outside the module or debug a problem.
returned: always
sample: helm pull --repo test ...
msg:
type: str
description: A message indicating the result of the operation.
returned: when chart already exists
sample: Chart redis version 17.0.0 already exists in destination directory
rc:
type: int
description: Helm pull command return code
@@ -169,6 +207,18 @@ rc:
sample: 1
"""
import os
import shutil
import tarfile
import uuid
try:
import yaml
HAS_YAML = True
except ImportError:
HAS_YAML = False
from ansible_collections.kubernetes.core.plugins.module_utils.helm import (
AnsibleHelmModule,
)
@@ -177,6 +227,115 @@ from ansible_collections.kubernetes.core.plugins.module_utils.version import (
)
def extract_chart_name(chart_ref):
"""
Extract chart name from chart reference.
Args:
chart_ref (str): Chart reference (name, URL, or OCI reference)
Returns:
str: Extracted chart name
"""
chart_name = chart_ref.split("/")[-1]
# Remove any query parameters or fragments from URL-based refs
if "?" in chart_name:
chart_name = chart_name.split("?")[0]
if "#" in chart_name:
chart_name = chart_name.split("#")[0]
# Remove .tgz extension if present
if chart_name.endswith(".tgz"):
chart_name = chart_name[:-4]
return chart_name
def chart_exists(destination, chart_ref, chart_version, untar_chart):
"""
Check if the chart already exists in the destination directory.
For untarred charts: check if directory exists with Chart.yaml matching version
For tarred charts: check if .tgz file exists and contains matching version
Args:
destination (str): Destination directory path
chart_ref (str): Chart reference (name or URL)
chart_version (str): Chart version to check for
untar_chart (bool): Whether to check for untarred or tarred chart
Returns:
bool: True if chart with matching version exists, False otherwise
"""
# YAML is required for version checking
if not HAS_YAML:
return False
# Without version, we can't reliably check
if not chart_version:
return False
# Extract chart name from chart_ref using shared helper
chart_name = extract_chart_name(chart_ref)
if untar_chart:
# Check for extracted directory
chart_dir = os.path.join(destination, chart_name)
chart_yaml_path = os.path.join(chart_dir, "Chart.yaml")
if os.path.isdir(chart_dir) and os.path.isfile(chart_yaml_path):
try:
with open(chart_yaml_path, "r", encoding="utf-8") as chart_file:
chart_metadata = yaml.safe_load(chart_file)
# Ensure chart_metadata is a dict and has a version that matches
if (
chart_metadata
and isinstance(chart_metadata, dict)
and chart_metadata.get("version") == chart_version
and chart_metadata.get("name") == chart_name
):
return True
except (yaml.YAMLError, IOError, OSError, TypeError):
# If we can't read or parse the file, treat as non-existent
pass
else:
# Check for .tgz file
chart_file = os.path.join(destination, f"{chart_name}-{chart_version}.tgz")
if os.path.isfile(chart_file):
try:
# Verify it's a valid tarball with matching version
with tarfile.open(chart_file, "r:gz") as tar:
# Try to extract Chart.yaml to verify version
# Look for Chart.yaml at the expected path: <chart-name>/Chart.yaml
expected_chart_yaml = f"{chart_name}/Chart.yaml"
try:
member = tar.getmember(expected_chart_yaml)
chart_yaml_file = tar.extractfile(member)
if chart_yaml_file:
try:
chart_metadata = yaml.safe_load(chart_yaml_file)
# Ensure chart_metadata is a dict and has a version that matches
if (
chart_metadata
and isinstance(chart_metadata, dict)
and chart_metadata.get("version") == chart_version
and chart_metadata.get("name") == chart_name
):
return True
except (yaml.YAMLError, TypeError):
# If we can't parse the YAML, treat as non-existent
pass
finally:
chart_yaml_file.close()
except KeyError:
# Chart.yaml not found at expected path
pass
except (tarfile.TarError, yaml.YAMLError, IOError, OSError, TypeError):
# If we can't read or parse the tarball, treat as non-existent
pass
return False
def main():
argspec = dict(
chart_ref=dict(type="str", required=True),
@@ -189,15 +348,19 @@ 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),
force=dict(type="bool", default=False),
destination=dict(type="path", required=True),
chart_ca_cert=dict(type="path"),
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,
@@ -209,19 +372,17 @@ def main():
mutually_exclusive=[("chart_version", "chart_devel")],
)
# Validate Helm version >=3.0.0
module.validate_helm_version()
helm_version = module.get_helm_version()
if LooseVersion(helm_version) < LooseVersion("3.0.0"):
module.fail_json(
msg="This module requires helm >= 3.0.0, current version is {0}".format(
helm_version
)
)
helm_pull_opt_versionning = dict(
skip_tls_certs_check="3.3.0",
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 +422,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():
@@ -273,8 +435,72 @@ def main():
module.params.get("chart_ref"),
" ".join(helm_pull_opts),
)
# Check if chart already exists (idempotency)
if module.params.get("chart_version") and not module.params.get("force"):
chart_exists_locally = chart_exists(
module.params.get("destination"),
module.params.get("chart_ref"),
module.params.get("chart_version"),
module.params.get("untar_chart"),
)
if chart_exists_locally:
module.exit_json(
failed=False,
changed=False,
msg="Chart {0} version {1} already exists in destination directory".format(
module.params.get("chart_ref"), module.params.get("chart_version")
),
command="",
stdout="",
stderr="",
rc=0,
)
# When both untar_chart and force are enabled, we need to remove the existing chart directory
# BEFORE running helm pull to prevent helm's "directory already exists" error.
# We do this by:
# 1. Renaming the existing directory to a temporary name (if it exists)
# 2. Running helm pull
# 3. On success: remove the temporary directory
# 4. On failure: restore the temporary directory and report the error
chart_dir_renamed = False
chart_dir = None
chart_dir_backup = None
if module.params.get("untar_chart") and module.params.get("force"):
chart_name = extract_chart_name(module.params.get("chart_ref"))
chart_dir = os.path.join(module.params.get("destination"), chart_name)
# Check if directory exists and contains a Chart.yaml (to be safe)
if os.path.isdir(chart_dir):
chart_yaml_path = os.path.join(chart_dir, "Chart.yaml")
# Only rename if it looks like a Helm chart directory (have Chart.yaml)
if os.path.isfile(chart_yaml_path):
if not module.check_mode:
# Rename to temporary backup name using uuid for uniqueness
backup_suffix = uuid.uuid4().hex[:8]
chart_dir_backup = os.path.join(
module.params.get("destination"),
f".{chart_name}_backup_{backup_suffix}",
)
os.rename(chart_dir, chart_dir_backup)
chart_dir_renamed = True
if not module.check_mode:
rc, out, err = module.run_helm_command(helm_cmd_common, fails_on_error=False)
# Handle cleanup/restore based on helm command result
if chart_dir_renamed:
if rc == 0:
# Success: remove the backup directory
if os.path.isdir(chart_dir_backup):
shutil.rmtree(chart_dir_backup)
else:
# Failure: restore the backup directory
if os.path.isdir(chart_dir_backup) and not os.path.exists(chart_dir):
os.rename(chart_dir_backup, chart_dir)
else:
rc, out, err = (0, "", "")

View File

@@ -0,0 +1,284 @@
#!/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
plain_http:
description:
- Use insecure HTTP connections for C(helm registry login).
- Requires Helm >= 3.18.0
required: false
type: bool
default: False
version_added: 6.4.0
binary_path:
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),
plain_http=dict(type="bool", default=False),
)
def login(
command,
host,
insecure,
username,
password,
key_file,
cert_file,
ca_file,
plain_http,
):
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
if plain_http:
login_command += " --plain-http"
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,
)
# Validate Helm version >=3.8.0
module.validate_helm_version(version="3.8.0")
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")
plain_http = module.params.get("plain_http")
helm_version = module.get_helm_version()
if plain_http:
if LooseVersion(helm_version) < LooseVersion("3.18.0"):
module.warn(
"plain_http option requires helm >= 3.18.0, current version is {0}".format(
helm_version
)
)
# reset option
plain_http = False
helm_cmd = module.get_helm_binary()
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,
plain_http,
)
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,
)
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()

View File

@@ -14,13 +14,13 @@ module: helm_repository
short_description: Manage Helm repositories.
version_added: "0.11.0"
version_added: 0.11.0
author:
- Lucas Boisserie (@LucasBoisserie)
requirements:
- "helm (https://github.com/helm/helm/releases)"
- "helm >= 3.0.0 (https://github.com/helm/helm/releases)"
- "yaml (https://pypi.org/project/PyYAML/)"
description:
@@ -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
@@ -281,6 +295,9 @@ def main():
if not IMP_YAML:
module.fail_json(msg=missing_required_lib("yaml"), exception=IMP_YAML_ERR)
# Validate Helm version >= 3.0.0
module.validate_helm_version()
changed = False
repo_name = module.params.get("repo_name")
@@ -290,6 +307,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 +326,7 @@ def main():
repo_password,
pass_credentials,
force_update,
insecure_skip_tls_verify,
)
changed = True
elif repository_status["url"] != repo_url:

View File

@@ -21,6 +21,10 @@ author:
description:
- Render chart templates to an output directory or as text of concatenated yaml documents.
requirements:
- "helm >= 3.0.0 (https://github.com/helm/helm/releases)"
- "yaml (https://pypi.org/project/PyYAML/)"
options:
binary_path:
description:
@@ -53,7 +57,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 +76,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 +150,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 +229,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 +242,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 +250,7 @@ def template(
values_files=None,
include_crds=False,
set_values=None,
plain_http=False,
):
cmd += " template "
@@ -251,6 +274,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 +318,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 +339,32 @@ 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)
# Validate Helm version >=3.0.0
module.validate_helm_version()
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 +382,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:

View File

@@ -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"
@@ -383,28 +383,24 @@ result:
contains:
api_version:
description: The versioned schema of this representation of an object.
returned: success
returned: when O(resource_definition) or O(src) contains a single object.
type: str
kind:
description: Represents the REST resource this object represents.
returned: success
returned: when O(resource_definition) or O(src) contains a single object.
type: str
metadata:
description: Standard object metadata. Includes name, namespace, annotations, labels, etc.
returned: success
returned: when O(resource_definition) or O(src) contains a single object.
type: complex
spec:
description: Specific attributes of the object. Will vary based on the I(api_version) and I(kind).
returned: success
returned: when O(resource_definition) or O(src) contains a single object.
type: complex
status:
description: Current status details for the object.
returned: success
returned: when O(resource_definition) or O(src) contains a single object.
type: complex
items:
description: Returned only when multiple yaml documents are passed to src or resource_definition
returned: when resource_definition or src contains list of objects
type: list
duration:
description: elapsed time of task in seconds
returned: when C(wait) is true
@@ -414,6 +410,46 @@ result:
description: error while trying to create/delete the object.
returned: error
type: complex
results:
description: An array of created, patched, or otherwise present objects.
returned: when O(resource_definition) or O(src) contains a list of objects.
type: complex
contains:
api_version:
description: The versioned schema of this representation of an object.
returned: when O(resource_definition) or O(src) contains a single object.
type: str
kind:
description: Represents the REST resource this object represents.
returned: when O(resource_definition) or O(src) contains a single object.
type: str
metadata:
description: Standard object metadata. Includes name, namespace, annotations, labels, etc.
returned: when O(resource_definition) or O(src) contains a single object.
type: complex
spec:
description: Specific attributes of the object. Will vary based on the I(api_version) and I(kind).
returned: when O(resource_definition) or O(src) contains a single object.
type: complex
status:
description: Current status details for the object.
returned: when O(resource_definition) or O(src) contains a single object.
type: complex
duration:
description: elapsed time of task in seconds
returned: when C(wait) is true
type: int
sample: 48
error:
description: error while trying to create/delete the object.
returned: error
type: complex
method:
description:
- The method used to deploy the resource.
returned: success
type: str
sample: create
"""
import copy
@@ -460,7 +496,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)

View File

@@ -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

View File

@@ -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"""
@@ -139,7 +140,7 @@ result:
import copy
from ansible.module_utils._text import to_native
from ansible.module_utils.common.text.converters import to_native
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
AnsibleModule,
)

View File

@@ -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,11 +144,12 @@ result:
"""
import copy
import json
import time
import traceback
from datetime import datetime
from ansible.module_utils._text import to_native
from ansible.module_utils.common.text.converters import to_native
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
AnsibleModule,
)
@@ -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 = [], [], [], [], []
@@ -217,7 +230,7 @@ def filter_pods(pods, force, ignore_daemonset, delete_emptydir_data):
else:
to_delete.append((pod.metadata.namespace, pod.metadata.name))
warnings, errors = [], []
warnings, errors, info = [], [], []
if unmanaged:
pod_names = ",".join([pod[0] + "/" + pod[1] for pod in unmanaged])
if not force:
@@ -229,7 +242,7 @@ def filter_pods(pods, force, ignore_daemonset, delete_emptydir_data):
)
else:
# Pod not managed will be deleted as 'force' is true
warnings.append(
info.append(
"Deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: {0}.".format(
pod_names
)
@@ -251,7 +264,7 @@ def filter_pods(pods, force, ignore_daemonset, delete_emptydir_data):
"cannot delete Pods with local storage: {0}.".format(pod_names)
)
else:
warnings.append("Deleting Pods with local storage: {0}.".format(pod_names))
info.append("Deleting Pods with local storage: {0}.".format(pod_names))
for pod in localStorage:
to_delete.append((pod[0], pod[1]))
@@ -265,8 +278,8 @@ def filter_pods(pods, force, ignore_daemonset, delete_emptydir_data):
)
)
else:
warnings.append("Ignoring DaemonSet-managed Pods: {0}.".format(pod_names))
return to_delete, warnings, errors
info.append("Ignoring DaemonSet-managed Pods: {0}.".format(pod_names))
return to_delete, warnings, errors, info
class K8sDrainAnsible(object):
@@ -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:
@@ -317,24 +334,25 @@ class K8sDrainAnsible(object):
def evict_pods(self, pods):
for namespace, name in pods:
try:
if self._drain_options.get("disable_eviction"):
self._api_instance.delete_namespaced_pod(
name=name, namespace=namespace, body=self._delete_options
)
else:
body = v1_eviction(
delete_options=self._delete_options,
metadata=V1ObjectMeta(name=name, namespace=namespace),
)
self._api_instance.create_namespaced_pod_eviction(
name=name, namespace=namespace, body=body
)
if not self._module.check_mode:
if self._drain_options.get("disable_eviction"):
self._api_instance.delete_namespaced_pod(
name=name, namespace=namespace, body=self._delete_options
)
else:
body = v1_eviction(
delete_options=self._delete_options,
metadata=V1ObjectMeta(name=name, namespace=namespace),
)
self._api_instance.create_namespaced_pod_eviction(
name=name, namespace=namespace, body=body
)
self._changed = True
except ApiException as exc:
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:
@@ -345,11 +363,7 @@ class K8sDrainAnsible(object):
)
def list_pods(self):
params = {
"field_selector": "spec.nodeName={name}".format(
name=self._module.params.get("name")
)
}
params = {"field_selector": "spec.nodeName=" + self._module.params.get("name")}
pod_selectors = self._module.params.get("pod_selectors")
if pod_selectors:
params["label_selector"] = ",".join(pod_selectors)
@@ -359,7 +373,8 @@ class K8sDrainAnsible(object):
# Mark node as unschedulable
result = []
if not node_unschedulable:
self.patch_node(unschedulable=True)
if not self._module.check_mode:
self.patch_node(unschedulable=True)
result.append(
"node {0} marked unschedulable.".format(self._module.params.get("name"))
)
@@ -374,7 +389,8 @@ class K8sDrainAnsible(object):
def _revert_node_patch():
if self._changed:
self._changed = False
self.patch_node(unschedulable=False)
if not self._module.check_mode:
self.patch_node(unschedulable=False)
try:
pod_list = self.list_pods()
@@ -384,7 +400,7 @@ class K8sDrainAnsible(object):
delete_emptydir_data = self._drain_options.get(
"delete_emptydir_data", False
)
pods, warnings, errors = filter_pods(
pods, warnings, errors, info = filter_pods(
pod_list.items, force, ignore_daemonset, delete_emptydir_data
)
if errors:
@@ -414,17 +430,25 @@ class K8sDrainAnsible(object):
if pods:
self.evict_pods(pods)
number_pod = len(pods)
if self._drain_options.get("wait_timeout") is not None:
warn = self.wait_for_pod_deletion(
pods,
self._drain_options.get("wait_timeout"),
self._drain_options.get("wait_sleep"),
if self._module.check_mode:
result.append(
"Would have deleted {0} Pod(s) from node if not in check mode.".format(
number_pod
)
)
if warn:
warnings.append(warn)
result.append("{0} Pod(s) deleted from node.".format(number_pod))
else:
wait_timeout = self._drain_options.get("wait_timeout")
wait_sleep = self._drain_options.get("wait_sleep")
if wait_timeout is not None:
warn = self.wait_for_pod_deletion(pods, wait_timeout, wait_sleep)
if warn:
warnings.append(warn)
result.append("{0} Pod(s) deleted from node.".format(number_pod))
if warnings:
return dict(result=" ".join(result), warnings=warnings)
for warning in warnings:
self._module.warn(warning)
for line in info:
self._module.debug(line)
return dict(result=" ".join(result))
def patch_node(self, unschedulable):
@@ -465,7 +489,8 @@ class K8sDrainAnsible(object):
self._module.exit_json(
result="node {0} already marked unschedulable.".format(name)
)
self.patch_node(unschedulable=True)
if not self._module.check_mode:
self.patch_node(unschedulable=True)
result["result"] = "node {0} marked unschedulable.".format(name)
self._changed = True
@@ -474,7 +499,8 @@ class K8sDrainAnsible(object):
self._module.exit_json(
result="node {0} already marked schedulable.".format(name)
)
self.patch_node(unschedulable=False)
if not self._module.check_mode:
self.patch_node(unschedulable=False)
result["result"] = "node {0} marked schedulable.".format(name)
self._changed = True
@@ -517,7 +543,9 @@ def argspec():
def main():
module = AnsibleK8SModule(module_class=AnsibleModule, argument_spec=argspec())
module = AnsibleK8SModule(
module_class=AnsibleModule, argument_spec=argspec(), supports_check_mode=True
)
if not HAS_EVICTION_API:
module.fail_json(

View File

@@ -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)"
@@ -131,11 +131,11 @@ except ImportError:
# ImportError are managed by the common module already.
pass
from ansible.module_utils._text import to_native
from ansible.module_utils.common.text.converters 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,

View File

@@ -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
@@ -119,6 +120,21 @@ EXAMPLES = r"""
namespace: default
wait_sleep: 10
wait_timeout: 360
- name: Wait for OpenShift bootstrap to complete
kubernetes.core.k8s_info:
api_version: v1
kind: ConfigMap
name: bootstrap
namespace: kube-system
register: ocp_bootstrap_status
until: >
ocp_bootstrap_status.resources is defined and
(ocp_bootstrap_status.resources | length > 0) and
(ocp_bootstrap_status.resources[0].data.status is defined) and
(ocp_bootstrap_status.resources[0].data.status == 'complete')
retries: 60
delay: 15
"""
RETURN = r"""

View File

@@ -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.
@@ -127,8 +135,8 @@ error:
import copy
import traceback
from ansible.module_utils._text import to_native
from ansible.module_utils.basic import missing_required_lib
from ansible.module_utils.common.text.converters import to_native
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
AnsibleModule,
)
@@ -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

View File

@@ -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"

View File

@@ -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:
@@ -168,7 +168,9 @@ def perform_action(svc, resource):
module.params["kind"],
resource["metadata"]["name"],
)
result = {"changed": False, "warnings": [warn]}
if warn:
module.warn(warn)
result = {"changed": False}
return result
if module.params["kind"] == "Deployment":

View File

@@ -149,7 +149,7 @@ except ImportError:
# Handled in module setup
pass
from ansible.module_utils._text import to_native
from ansible.module_utils.common.text.converters import to_native
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
AnsibleModule,
)
@@ -243,10 +243,12 @@ def execute_module(client, module):
module.fail_json(msg=error, **return_attributes)
def _continue_or_exit(warn):
if warn:
module.warn(warn)
if multiple_scale:
return_attributes["results"].append({"warning": warn, "changed": False})
return_attributes["results"].append({"changed": False})
else:
module.exit_json(warning=warn, **return_attributes)
module.exit_json(**return_attributes)
for existing in existing_items:
if kind.lower() == "job":

View File

@@ -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.
@@ -126,7 +126,7 @@ result:
import copy
from ansible.module_utils._text import to_native
from ansible.module_utils.common.text.converters import to_native
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
AnsibleModule,
)

View File

@@ -0,0 +1,441 @@
#!/usr/bin/python
#
# Copyright (c) Ansible Project
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
DOCUMENTATION = r"""
---
module: kubeconfig
short_description: Generate, update, and optionally write Kubernetes kubeconfig files
version_added: "6.5.0"
author: "Youssef Khalid Ali (@YoussefKhalidAli)"
description:
- Build, update, and manage Kubernetes kubeconfig files using structured input.
- Supports loading an existing kubeconfig file and merging clusters, users, and contexts.
- Can optionally write the resulting kubeconfig to a destination path.
- Ensures idempotent behavior by only updating files when changes occur.
requirements:
- "PyYAML >= 5.1"
notes:
- Input data is merged by resource name (cluster, user, context).
- Updates under O(clusters), O(users), and O(contexts) are matched by C(name) against the kubeconfig loaded from O(path).
- For an existing C(name), each entry's C(behavior) suboption controls the update.
- The default is V(merge), which merges nested C(cluster), C(user), and C(context) data so unspecified keys are preserved.
- With V(replace), the previous entry for that name is dropped and only the new definition is used.
- With V(keep), the existing entry is left unchanged.
- This can be used to move kubeconfig files to a different location with different content.
- This module does not validate cluster connectivity or authentication.
- The module supports C(check_mode) and will not write files when enabled.
- The structure follows standard Kubernetes kubeconfig format as defined in the Kubernetes documentation.
- Tokens and sensitive data should be protected using ansible-vault or environment variables.
options:
path:
description:
- Path to an existing kubeconfig file to load and merge from.
- If the file does not exist, a new kubeconfig will be created.
- This becomes the default destination if O(dest) is not specified.
type: str
required: true
dest:
description:
- Destination path where the final kubeconfig should be written.
- If not specified, the kubeconfig will be saved to O(path).
- Allows copying and modifying a kubeconfig to a new location.
type: str
required: false
clusters:
description:
- List of cluster definitions to merge into the kubeconfig.
- Each cluster is identified by its C(name).
- When C(name) matches an existing cluster, the default C(behavior) is V(merge).
- See the C(behavior) suboption for V(replace) and V(keep).
type: list
elements: dict
required: false
default: []
suboptions:
name:
description:
- Unique name identifier for the cluster.
type: str
required: true
behavior:
description:
- How to handle merging if a cluster with this name already exists.
- C(merge) - Update only the specified fields, preserve others (default).
- C(replace) - Replace the entire cluster definition.
- C(keep) - Keep existing cluster, skip this entry.
type: str
choices: ['merge', 'replace', 'keep']
default: merge
cluster:
description:
- Cluster configuration details.
type: dict
required: true
suboptions:
server:
description:
- Kubernetes API server URL (e.g., C(https://k8s.example.com:6443)).
type: str
required: true
certificate-authority:
description:
- Path to a CA certificate file for validating the API server certificate.
type: str
certificate-authority-data:
description:
- Base64 encoded CA certificate data.
- Use this instead of C(certificate-authority) for embedded certificates.
type: str
insecure-skip-tls-verify:
description:
- If true, the server's certificate will not be validated.
type: bool
proxy-url:
description:
- Optional proxy URL for cluster connections.
type: str
tls-server-name:
description:
- Server name to use for server certificate validation.
type: str
users:
description:
- List of user authentication configurations.
- Each user is identified by its C(name).
- When C(name) matches an existing user, the default C(behavior) is V(merge).
- See the C(behavior) suboption for V(replace) and V(keep).
type: list
elements: dict
required: false
default: []
suboptions:
name:
description:
- Unique name identifier for the user.
type: str
required: true
behavior:
description:
- How to handle merging if a user with this name already exists.
- C(merge) - Update only the specified fields, preserve others (default).
- C(replace) - Replace the entire user definition.
- C(keep) - Keep existing user, skip this entry.
type: str
choices: ['merge', 'replace', 'keep']
default: merge
user:
description:
- User authentication configuration.
type: dict
required: true
suboptions:
token:
description:
- Bearer token for authentication.
type: str
username:
description:
- Username for basic authentication.
type: str
password:
description:
- Password for basic authentication.
type: str
client-certificate:
description:
- Path to client certificate file.
- Used for certificate-based authentication.
type: str
client-key:
description:
- Path to client private key file.
- Must be provided with C(client-certificate).
type: str
client-certificate-data:
description:
- Base64 encoded client certificate.
- Use instead of C(client-certificate) for embedded certificates.
type: str
client-key-data:
description:
- Base64 encoded client private key.
- Use instead of C(client-key) for embedded keys.
type: str
auth-provider:
description:
- Authentication provider configuration (e.g., for GCP, Azure).
type: dict
exec:
description:
- Exec-based credential plugin configuration.
- Used for external authentication providers.
type: dict
contexts:
description:
- List of context definitions linking users and clusters.
- Each context is identified by its C(name).
- When C(name) matches an existing context, the default C(behavior) is V(merge).
- See the C(behavior) suboption for V(replace) and V(keep).
type: list
elements: dict
required: false
default: []
suboptions:
name:
description:
- Unique name identifier for the context.
type: str
required: true
behavior:
description:
- How to handle merging if a context with this name already exists.
- C(merge) - Update only the specified fields, preserve others (default).
- C(replace) - Replace the entire context definition.
- C(keep) - Keep existing context, skip this entry.
type: str
choices: ['merge', 'replace', 'keep']
default: merge
context:
description:
- Context configuration linking cluster and user.
type: dict
required: true
suboptions:
cluster:
description:
- Name of the cluster to use (must match a cluster name in O(clusters)).
type: str
required: true
user:
description:
- Name of the user to authenticate as (must match a user name in O(users)).
type: str
required: true
namespace:
description:
- Default namespace to use for this context.
- If not specified, defaults to C(default).
type: str
preferences:
description:
- Kubeconfig preferences.
- Used for client-side settings like color output, default editor, etc.
type: dict
required: false
default: {}
current_context:
description:
- Name of the context to set as current/active.
- This context will be used by default when using kubectl.
- Must match one of the context names defined in O(contexts).
type: str
required: false
seealso:
- name: Kubernetes kubeconfig documentation
description: Official Kubernetes documentation for kubeconfig files
link: https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/
- name: kubectl config documentation
description: kubectl commands for working with kubeconfig files
link: https://kubernetes.io/docs/reference/kubectl/generated/kubectl_config/
"""
EXAMPLES = r"""
# Create a new kubeconfig file with a single cluster
- name: Create basic kubeconfig
kubernetes.core.kubeconfig:
path: /home/user/.kube/config
clusters:
- name: production-cluster
cluster:
server: https://prod.k8s.example.com:6443
certificate-authority-data: LS0tLS1CRUdJTi...
users:
- name: admin-user
user:
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9...
contexts:
- name: prod-admin
context:
cluster: production-cluster
user: admin-user
namespace: production
current_context: prod-admin
- name: Copy and modify kubeconfig
kubernetes.core.kubeconfig:
path: /home/user/.kube/config
dest: /home/user/.kube/config-backup
clusters:
- name: new-cluster
cluster:
server: https://new.example.com:6443
- name: Switch current context
kubernetes.core.kubeconfig:
path: ~/.kube/config
current_context: prod-context
- name: Update user credentials
kubernetes.core.kubeconfig:
path: ~/.kube/config
users:
- name: admin-user
user:
token: "{{ new_admin_token }}"
"""
RETURN = r"""
kubeconfig:
description: The complete kubeconfig data structure.
type: dict
returned: always
dest:
description: The path where the kubeconfig was written.
type: str
returned: always
sample: /home/user/.kube/config
"""
import os
import traceback
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.common.text.converters import to_native
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
extract_sensitive_values_from_kubeconfig,
)
from ansible_collections.kubernetes.core.plugins.module_utils.kubeconfig import (
hash_data,
load_yaml_file,
merge_by_name,
write_file,
)
try:
import yaml
IMP_YAML = True
IMP_YAML_ERR = None
except ImportError:
IMP_YAML = False
IMP_YAML_ERR = traceback.format_exc()
def run_module():
module_args = dict(
path=dict(type="str", required=True),
dest=dict(type="str", required=False),
clusters=dict(type="list", elements="dict", required=False, default=[]),
users=dict(type="list", elements="dict", required=False, default=[]),
contexts=dict(type="list", elements="dict", required=False, default=[]),
preferences=dict(type="dict", required=False, default={}),
current_context=dict(type="str", required=False),
)
module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
path = module.params["path"]
dest = module.params["dest"] or path
clusters_input = module.params["clusters"]
users_input = module.params["users"]
contexts_input = module.params["contexts"]
preferences = module.params["preferences"]
current_context = module.params["current_context"]
# Load existing kubeconfig
try:
if not IMP_YAML:
module.fail_json(
msg=missing_required_lib("pyyaml"),
exception=IMP_YAML_ERR,
)
existing = load_yaml_file(path) if path else {}
except Exception as e:
module.fail_json(
msg="Failed to load existing kubeconfig: %s" % to_native(e),
exception=traceback.format_exc(),
)
clusters = merge_by_name(existing.get("clusters", []), clusters_input)
users = merge_by_name(existing.get("users", []), users_input)
contexts = merge_by_name(existing.get("contexts", []), contexts_input)
# Build final kubeconfig
kubeconfig = {
"apiVersion": "v1",
"kind": "Config",
"preferences": preferences or existing.get("preferences", {}),
"clusters": clusters,
"users": users,
"contexts": contexts,
"current-context": current_context or existing.get("current-context") or "",
}
changed = False
old_data = {}
if os.path.exists(dest):
try:
with open(dest, "r") as f:
old_data = yaml.safe_load(f) or {}
except Exception as e:
module.fail_json(
msg="Failed to read destination file: %s" % to_native(e),
exception=traceback.format_exc(),
)
old_hash = hash_data(old_data)
new_hash = hash_data(kubeconfig)
if old_hash != new_hash:
if not module.check_mode:
try:
write_file(dest, kubeconfig)
except Exception as e:
module.fail_json(
msg="Failed to write kubeconfig: %s" % to_native(e),
exception=traceback.format_exc(),
)
changed = True
if isinstance(kubeconfig, dict):
module.no_log_values.update(
extract_sensitive_values_from_kubeconfig(kubeconfig)
)
module.exit_json(
changed=changed,
kubeconfig=kubeconfig,
dest=dest,
msg=(
"Kubeconfig file has been updated."
if changed
else "Kubeconfig file is already up to date."
),
)
def main():
run_module()
if __name__ == "__main__":
main()

Some files were not shown because too many files have changed in this diff Show More