mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-05-11 20:12:18 +00:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
96464f1ea8 | ||
|
|
fe4858d556 | ||
|
|
07e8a76f2d | ||
|
|
0488b79f0f | ||
|
|
4fa6465f3e | ||
|
|
e1b341d9be | ||
|
|
8feb564b4d | ||
|
|
42832bc9d2 | ||
|
|
19b2efd0dd | ||
|
|
1c3bf95b74 | ||
|
|
018c92429b | ||
|
|
9267e03538 | ||
|
|
eb3ab99709 | ||
|
|
a1ac6b99dc | ||
|
|
4ad57fdb6c | ||
|
|
ee9939c54f | ||
|
|
c1549db1bb | ||
|
|
c6bd8ab453 | ||
|
|
6299f242a2 | ||
|
|
cd55f596ab | ||
|
|
00bbf16cff | ||
|
|
31fd4058f1 | ||
|
|
5c748bd4e9 | ||
|
|
1c295560ba | ||
|
|
615d3d8bd0 | ||
|
|
4854d7fbd9 | ||
|
|
baa59f388c | ||
|
|
e071ae73b6 | ||
|
|
00cb40094a | ||
|
|
ef829b8a56 | ||
|
|
d86a652c36 | ||
|
|
a4242f0131 | ||
|
|
d75e9a0fa3 | ||
|
|
5044cfc030 | ||
|
|
ddd7e79a12 | ||
|
|
edc979ff11 | ||
|
|
37c1f911cb | ||
|
|
80a5bf623a | ||
|
|
8f653558f6 | ||
|
|
1c0734dd4e | ||
|
|
e6d138dbf0 | ||
|
|
eed4ebb0af | ||
|
|
d3031fcbd3 | ||
|
|
e756cedf33 |
@@ -1,2 +1,7 @@
|
||||
# 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]
|
||||
# stable-3 branch support ansible-core>=2.14.0
|
||||
meta/runtime.yml meta-runtime[unsupported-version]
|
||||
|
||||
@@ -2,5 +2,7 @@
|
||||
profile: production
|
||||
|
||||
exclude_paths:
|
||||
- .ansible/
|
||||
- tests/integration
|
||||
- tests/unit
|
||||
- tests/sanity
|
||||
60
.github/stale.yml
vendored
60
.github/stale.yml
vendored
@@ -1,60 +0,0 @@
|
||||
---
|
||||
# Configuration for probot-stale - https://github.com/probot/stale
|
||||
|
||||
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
||||
daysUntilStale: 90
|
||||
|
||||
# Number of days of inactivity before an Issue or Pull Request with the stale
|
||||
# label is closed. Set to false to disable. If disabled, issues still need to be
|
||||
# closed manually, but will remain marked as stale.
|
||||
daysUntilClose: 30
|
||||
|
||||
# Only issues or pull requests with all of these labels are check if stale.
|
||||
# Defaults to `[]` (disabled)
|
||||
onlyLabels: []
|
||||
|
||||
# Issues or Pull Requests with these labels will never be considered stale. Set
|
||||
# to `[]` to disable
|
||||
exemptLabels:
|
||||
- security
|
||||
- planned
|
||||
- priority/critical
|
||||
- lifecycle/frozen
|
||||
- verified
|
||||
|
||||
# Set to true to ignore issues in a project (defaults to false)
|
||||
exemptProjects: false
|
||||
|
||||
# Set to true to ignore issues in a milestone (defaults to false)
|
||||
exemptMilestones: true
|
||||
|
||||
# Set to true to ignore issues with an assignee (defaults to false)
|
||||
exemptAssignees: false
|
||||
|
||||
# Label to use when marking as stale
|
||||
staleLabel: lifecycle/stale
|
||||
|
||||
# Limit the number of actions per hour, from 1-30. Default is 30
|
||||
limitPerRun: 30
|
||||
|
||||
pulls:
|
||||
markComment: |-
|
||||
PRs go stale after 90 days of inactivity.
|
||||
If there is no further activity, the PR will be closed in another 30 days.
|
||||
|
||||
unmarkComment: >-
|
||||
This pull request is no longer stale.
|
||||
|
||||
closeComment: >-
|
||||
This pull request has been closed due to inactivity.
|
||||
|
||||
issues:
|
||||
markComment: |-
|
||||
Issues go stale after 90 days of inactivity.
|
||||
If there is no further activity, the issue will be closed in another 30 days.
|
||||
|
||||
unmarkComment: >-
|
||||
This issue is no longer stale.
|
||||
|
||||
closeComment: >-
|
||||
This issue has been closed due to inactivity.
|
||||
16
.github/workflows/integration-tests.yaml
vendored
16
.github/workflows/integration-tests.yaml
vendored
@@ -50,6 +50,7 @@ jobs:
|
||||
source: "./source"
|
||||
cloud_common: "./cloudcommon"
|
||||
ansible_posix: "./ansible_posix"
|
||||
community_general: "./community_general"
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -61,7 +62,7 @@ jobs:
|
||||
- true
|
||||
- false
|
||||
workflow-id: ${{ fromJson(needs.splitter.outputs.test_jobs) }}
|
||||
name: "integration-py${{ matrix.python-version }}-${{ matrix.ansible-version }}-${{ matrix.workflow-id }}"
|
||||
name: "integration-py${{ matrix.python-version }}-${{ matrix.ansible-version }}-${{ matrix.workflow-id }}-enable_turbo=${{ matrix.enable-turbo-mode }}"
|
||||
steps:
|
||||
- name: Read target
|
||||
id: read-targets
|
||||
@@ -118,6 +119,13 @@ jobs:
|
||||
path: ${{ env.ansible_posix }}
|
||||
ref: main
|
||||
|
||||
- name: checkout ansible-collections/community.general
|
||||
uses: ansible-network/github_actions/.github/actions/checkout_dependency@main
|
||||
with:
|
||||
repository: ansible-collections/community.general
|
||||
path: ${{ env.community_general }}
|
||||
ref: main
|
||||
|
||||
- name: install cloud.common collection
|
||||
uses: ansible-network/github_actions/.github/actions/build_install_collection@main
|
||||
with:
|
||||
@@ -130,6 +138,12 @@ 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:
|
||||
|
||||
5
.github/workflows/linters.yaml
vendored
5
.github/workflows/linters.yaml
vendored
@@ -19,6 +19,5 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run ansible-lint
|
||||
uses: ansible/ansible-lint@v24.2.3
|
||||
- name: run-ansible-lint
|
||||
uses: ansible/ansible-lint@v25.1.2
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -13,6 +13,7 @@ changelogs/.plugin-cache.yaml
|
||||
tests/output
|
||||
tests/integration/cloud-config-*
|
||||
.cache
|
||||
.ansible
|
||||
|
||||
# Helm charts
|
||||
tests/integration/*-chart-*.tgz
|
||||
|
||||
@@ -5,16 +5,24 @@ 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
|
||||
|
||||
@@ -4,56 +4,48 @@ Kubernetes Collection Release Notes
|
||||
|
||||
.. contents:: Topics
|
||||
|
||||
v5.0.0
|
||||
v3.3.1
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
This major release drops support for ``ansible-core<2.15``.
|
||||
This release fixes the CI issues with the ``linters`` workflow.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- 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
|
||||
v3.3.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).
|
||||
- inventory/k8s.py - Defer removal of k8s inventory plugin to version 6.0.0 (https://github.com/ansible-collections/kubernetes.core/pull/734).
|
||||
- k8s_drain - Improve error message for pod disruption budget when draining a node (https://github.com/ansible-collections/kubernetes.core/issues/797).
|
||||
|
||||
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).
|
||||
- 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 6.0.0 (https://github.com/ansible-collections/kubernetes.core/pull/734).
|
||||
|
||||
v3.1.0
|
||||
======
|
||||
|
||||
2
Makefile
2
Makefile
@@ -1,5 +1,5 @@
|
||||
# Also needs to be updated in galaxy.yml
|
||||
VERSION = 5.0.0
|
||||
VERSION = 3.3.1
|
||||
|
||||
TEST_ARGS ?= ""
|
||||
PYTHON_VERSION ?= `python -c 'import platform; print(".".join(platform.python_version_tuple()[0:2]))'`
|
||||
|
||||
66
README.md
66
README.md
@@ -4,12 +4,16 @@
|
||||
|
||||
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.
|
||||
|
||||
<!--start requires_ansible-->
|
||||
## Ansible version compatibility
|
||||
## Requirements
|
||||
|
||||
This collection has been tested against following Ansible versions: **>=2.15.0**.
|
||||
<!--start requires_ansible-->
|
||||
### Ansible version compatibility
|
||||
|
||||
This collection has been tested against following Ansible versions: **>=2.14.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`).
|
||||
@@ -18,43 +22,43 @@ A collection may contain metadata that identifies these versions.
|
||||
PEP440 is the schema used to describe the versions of Ansible.
|
||||
<!--end requires_ansible-->
|
||||
|
||||
## Python Support
|
||||
### Python Support
|
||||
|
||||
* Collection supports 3.9+
|
||||
|
||||
Note: Python2 is deprecated from [1st January 2020](https://www.python.org/doc/sunset-python-2/). Please switch to Python3.
|
||||
|
||||
## Kubernetes Version Support
|
||||
### Kubernetes Version Support
|
||||
|
||||
This collection supports Kubernetes versions >= 1.24.
|
||||
|
||||
## Included content
|
||||
### Included content
|
||||
|
||||
Click on the name of a plugin or module to view that content's documentation:
|
||||
|
||||
<!--start collection content-->
|
||||
### Connection plugins
|
||||
#### Connection plugins
|
||||
Name | Description
|
||||
--- | ---
|
||||
[kubernetes.core.kubectl](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.kubectl_connection.rst)|Execute tasks in pods running on Kubernetes.
|
||||
|
||||
### K8s filter plugins
|
||||
#### K8s filter plugins
|
||||
Name | Description
|
||||
--- | ---
|
||||
kubernetes.core.k8s_config_resource_name|Generate resource name for the given resource of type ConfigMap, Secret
|
||||
|
||||
### Inventory plugins
|
||||
#### Inventory plugins
|
||||
Name | Description
|
||||
--- | ---
|
||||
[kubernetes.core.k8s](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_inventory.rst)|Kubernetes (K8s) inventory source
|
||||
|
||||
### Lookup plugins
|
||||
#### Lookup plugins
|
||||
Name | Description
|
||||
--- | ---
|
||||
[kubernetes.core.k8s](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_lookup.rst)|Query the K8s API
|
||||
[kubernetes.core.kustomize](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.kustomize_lookup.rst)|Build a set of kubernetes resources using a 'kustomization.yaml' file.
|
||||
|
||||
### Modules
|
||||
#### Modules
|
||||
Name | Description
|
||||
--- | ---
|
||||
[kubernetes.core.helm](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_module.rst)|Manages Kubernetes packages with the Helm package manager
|
||||
@@ -79,9 +83,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 +95,7 @@ You can also include it in a `requirements.yml` file and install it via `ansible
|
||||
---
|
||||
collections:
|
||||
- name: kubernetes.core
|
||||
version: 5.0.0
|
||||
version: 3.3.1
|
||||
```
|
||||
|
||||
### Installing the Kubernetes Python Library
|
||||
@@ -102,7 +104,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`:
|
||||
|
||||
@@ -189,12 +191,16 @@ defined in the playbook using `environment` keyword as above, you must set it us
|
||||
|
||||
Please read more about Ansible Turbo mode - [here](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/ansible_turbo_mode.rst).
|
||||
|
||||
## Testing and Development
|
||||
## Contributing to this collection
|
||||
|
||||
If you want to develop new content for this collection or improve what's already here, the easiest way to work on the collection is to clone it into one of the configured [`COLLECTIONS_PATHS`](https://docs.ansible.com/ansible/latest/reference_appendices/config.html#collections-paths), and work on it there.
|
||||
|
||||
See [Contributing to kubernetes.core](CONTRIBUTING.md).
|
||||
|
||||
## Testing
|
||||
|
||||
[](https://github.com/ansible-collections/kubernetes.core/actions/workflows/linters.yaml) [](https://github.com/ansible-collections/kubernetes.core/actions/workflows/integration-tests.yaml) [](https://github.com/ansible-collections/kubernetes.core/actions/workflows/sanity-tests.yaml) [](https://github.com/ansible-collections/kubernetes.core/actions/workflows/unit-tests.yaml) [](https://app.codecov.io/gh/ansible-collections/kubernetes.core)
|
||||
|
||||
### Testing with `ansible-test`
|
||||
|
||||
The `tests` directory contains configuration for running sanity and integration tests using [`ansible-test`](https://docs.ansible.com/ansible/latest/dev_guide/testing_integration.html).
|
||||
@@ -231,10 +237,36 @@ 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.
|
||||
|
||||
## Support
|
||||
|
||||
<!--List available communication channels. In addition to channels specific to your collection, we also recommend to use the following ones.-->
|
||||
|
||||
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).
|
||||
|
||||
## More Information
|
||||
|
||||
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.
|
||||
|
||||
## 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
|
||||
|
||||
@@ -854,58 +854,54 @@ releases:
|
||||
- 652-fix-json-patch-action.yml
|
||||
- 654-helm-expand-user.yml
|
||||
release_date: '2024-05-16'
|
||||
4.0.0:
|
||||
3.2.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:
|
||||
- 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).
|
||||
- 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:
|
||||
- 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``.
|
||||
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
|
||||
- 20240530-defer-removal-and-ansible-core-support-update.yaml
|
||||
- 5.0.0.yml
|
||||
release_date: '2024-05-31'
|
||||
- 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-22'
|
||||
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'
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
---
|
||||
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).
|
||||
3
changelogs/fragments/20250324-k8s_info-templating.yaml
Normal file
3
changelogs/fragments/20250324-k8s_info-templating.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
minor_changes:
|
||||
- action/k8s_info - update templating mechanism with changes from ``ansible-core 2.19`` (https://github.com/ansible-collections/kubernetes.core/pull/888).
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
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).
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
minor_changes:
|
||||
- Bump version of ansible-lint to 25.1.2 (https://github.com/ansible-collections/kubernetes.core/pull/919).
|
||||
@@ -443,7 +443,7 @@ Parameters
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.5.0</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.0.0</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
@@ -463,7 +463,7 @@ Parameters
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.5.0</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.0.0</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
|
||||
@@ -423,7 +423,7 @@ Parameters
|
||||
<span style="color: purple">list</span>
|
||||
/ <span style="color: purple">elements=string</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.5.0</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.0.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
|
||||
@@ -168,7 +168,7 @@ Parameters
|
||||
<span style="color: purple">list</span>
|
||||
/ <span style="color: purple">elements=string</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.5.0</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.0.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
|
||||
@@ -121,7 +121,7 @@ Parameters
|
||||
<td>
|
||||
<div><code>apply</code> compares the desired resource definition with the previously supplied resource definition, ignoring properties that are automatically generated</div>
|
||||
<div><code>apply</code> works better with Services than 'force=yes'</div>
|
||||
<div>Mutually exclusive with <code>merge_type</code>.</div>
|
||||
<div>mutually exclusive with <code>merge_type</code></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -216,7 +216,7 @@ Parameters
|
||||
<div style="font-size: small">
|
||||
<span style="color: purple">boolean</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.5.0</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.0.0</div>
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
@@ -389,7 +389,7 @@ Parameters
|
||||
<span style="color: purple">list</span>
|
||||
/ <span style="color: purple">elements=string</span>
|
||||
</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.5.0</div>
|
||||
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.0.0</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
@@ -513,17 +513,18 @@ Parameters
|
||||
</td>
|
||||
<td>
|
||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||
<li>json</li>
|
||||
<li>merge</li>
|
||||
<li>strategic-merge</li>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<div>Whether to override the default patch merge approach with a specific type. By default, the strategic merge will typically be used.</div>
|
||||
<div>For example, Custom Resource Definitions typically aren't updatable by the usual strategic merge. You may want to use <code>merge</code> if you see "strategic merge patch format is not supported".</div>
|
||||
<div>For example, Custom Resource Definitions typically aren't updatable by the usual strategic merge. You may want to use <code>merge</code> if you see "strategic merge patch format is not supported"</div>
|
||||
<div>See <a href='https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/#use-a-json-merge-patch-to-update-a-deployment'>https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/#use-a-json-merge-patch-to-update-a-deployment</a></div>
|
||||
<div>If more than one <code>merge_type</code> is given, the merge_types will be tried in order. This defaults to <code>['strategic-merge', 'merge']</code>, which is ideal for using the same parameters on resource kinds that combine Custom Resources and built-in resources.</div>
|
||||
<div>Mutually exclusive with <code>apply</code>.</div>
|
||||
<div><em>merge_type=json</em> has been removed in version 4.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> is deprecated and will be removed in version 4.0.0. Please use <span class='module'>kubernetes.core.k8s_json_patch</span> instead.</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -25,7 +25,7 @@ tags:
|
||||
- openshift
|
||||
- okd
|
||||
- cluster
|
||||
version: 5.0.0
|
||||
version: 3.3.1
|
||||
build_ignore:
|
||||
- .DS_Store
|
||||
- "*.tar.gz"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
requires_ansible: '>=2.15.0'
|
||||
requires_ansible: '>=2.14.0'
|
||||
|
||||
action_groups:
|
||||
helm:
|
||||
|
||||
@@ -25,30 +25,18 @@ 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 ":"
|
||||
@@ -207,7 +195,6 @@ 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):
|
||||
template_params.append(self.get_template_args(template))
|
||||
@@ -230,17 +217,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 +245,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)
|
||||
overrides = {}
|
||||
for key, value in iteritems(template_item):
|
||||
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:
|
||||
|
||||
@@ -125,19 +125,19 @@ import json
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable
|
||||
|
||||
try:
|
||||
from kubernetes.dynamic.exceptions import DynamicApiError
|
||||
|
||||
HAS_K8S_MODULE_HELPER = True
|
||||
k8s_import_exception = None
|
||||
except ImportError as e:
|
||||
HAS_K8S_MODULE_HELPER = False
|
||||
k8s_import_exception = e
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.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:
|
||||
|
||||
@@ -94,7 +94,8 @@ def get_binary_from_path(name, opt_dirs=None):
|
||||
|
||||
def run_command(command):
|
||||
cmd = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
return cmd.communicate()
|
||||
stdout, stderr = cmd.communicate()
|
||||
return cmd.returncode, stdout, stderr
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
@@ -140,9 +141,18 @@ class LookupModule(LookupBase):
|
||||
if enable_helm:
|
||||
command += ["--enable-helm"]
|
||||
|
||||
(out, err) = run_command(command)
|
||||
if err:
|
||||
raise AnsibleLookupError(
|
||||
"kustomize command failed with: {0}".format(err.decode("utf-8"))
|
||||
)
|
||||
(ret, out, err) = run_command(command)
|
||||
if ret != 0:
|
||||
if err:
|
||||
raise AnsibleLookupError(
|
||||
"kustomize command failed. exit code: {0}, error: {1}".format(
|
||||
ret, err.decode("utf-8")
|
||||
)
|
||||
)
|
||||
else:
|
||||
raise AnsibleLookupError(
|
||||
"kustomize command failed with unknown error. exit code: {0}".format(
|
||||
ret
|
||||
)
|
||||
)
|
||||
return [out.decode("utf-8")]
|
||||
|
||||
@@ -149,7 +149,6 @@ 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(
|
||||
@@ -159,7 +158,6 @@ def k8s_apply(resource, definition, **kwargs):
|
||||
return resource.get(
|
||||
name=definition["metadata"]["name"],
|
||||
namespace=definition["metadata"].get("namespace"),
|
||||
**kwargs
|
||||
)
|
||||
return resource.patch(
|
||||
body=desired,
|
||||
|
||||
@@ -18,7 +18,7 @@ AUTH_PROXY_HEADERS_SPEC = dict(
|
||||
)
|
||||
|
||||
AUTH_ARG_SPEC = {
|
||||
"kubeconfig": {"type": "raw"},
|
||||
"kubeconfig": {"type": "raw", "no_log": True},
|
||||
"context": {},
|
||||
"host": {},
|
||||
"api_key": {"no_log": True},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -77,7 +77,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
|
||||
"""
|
||||
@@ -184,10 +183,10 @@ class AnsibleHelmModule(object):
|
||||
def get_helm_version(self):
|
||||
command = self.get_helm_binary() + " version"
|
||||
rc, out, err = self.run_command(command)
|
||||
m = re.match(r'version.BuildInfo{Version:"v([0-9\.]*)",', out)
|
||||
m = re.match(r'version.BuildInfo{Version:"v(.*?)",', out)
|
||||
if m:
|
||||
return m.group(1)
|
||||
m = re.match(r'Client: &version.Version{SemVer:"v([0-9\.]*)", ', out)
|
||||
m = re.match(r'Client: &version.Version{SemVer:"v(.*?)", ', out)
|
||||
if m:
|
||||
return m.group(1)
|
||||
return None
|
||||
|
||||
@@ -16,6 +16,7 @@ HELM_AUTH_ARG_SPEC = dict(
|
||||
type="raw",
|
||||
aliases=["kubeconfig_path"],
|
||||
fallback=(env_fallback, ["K8S_AUTH_KUBECONFIG"]),
|
||||
no_log=True,
|
||||
),
|
||||
host=dict(type="str", fallback=(env_fallback, ["K8S_AUTH_HOST"])),
|
||||
ca_cert=dict(
|
||||
|
||||
@@ -139,7 +139,6 @@ 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
|
||||
@@ -173,7 +172,7 @@ def perform_action(svc, definition: Dict, params: Dict) -> Dict:
|
||||
return result
|
||||
|
||||
if params.get("apply"):
|
||||
instance, warnings = svc.apply(resource, definition, existing)
|
||||
instance = svc.apply(resource, definition, existing)
|
||||
result["method"] = "apply"
|
||||
elif not existing:
|
||||
if state == "patched":
|
||||
@@ -184,19 +183,16 @@ def perform_action(svc, definition: Dict, params: Dict) -> Dict:
|
||||
)
|
||||
)
|
||||
return result
|
||||
instance, warnings = svc.create(resource, definition)
|
||||
instance = svc.create(resource, definition)
|
||||
result["method"] = "create"
|
||||
result["changed"] = True
|
||||
elif params.get("force", False):
|
||||
instance, warnings = svc.replace(resource, definition, existing)
|
||||
instance = svc.replace(resource, definition, existing)
|
||||
result["method"] = "replace"
|
||||
else:
|
||||
instance, warnings = svc.update(resource, definition, existing)
|
||||
instance = svc.update(resource, definition, existing)
|
||||
result["method"] = "update"
|
||||
|
||||
if warnings:
|
||||
result["warnings"] = warnings
|
||||
|
||||
# If needed, wait and/or create diff
|
||||
success = True
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
import copy
|
||||
from json import loads
|
||||
from re import compile
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
from ansible.module_utils.common.dict_transformations import dict_merge
|
||||
@@ -144,12 +142,18 @@ class K8sService:
|
||||
name: str,
|
||||
namespace: str,
|
||||
merge_type: str = None,
|
||||
) -> Tuple[Dict, List[str]]:
|
||||
) -> Dict:
|
||||
if merge_type == "json":
|
||||
self.module.deprecate(
|
||||
msg="json as a merge_type value is deprecated. Please use the k8s_json_patch module instead.",
|
||||
version="4.0.0",
|
||||
collection_name="kubernetes.core",
|
||||
)
|
||||
try:
|
||||
params = dict(name=name, namespace=namespace, serialize=False)
|
||||
params = dict(name=name, namespace=namespace)
|
||||
if merge_type:
|
||||
params["content_type"] = "application/{0}-patch+json".format(merge_type)
|
||||
return decode_response(self.client.patch(resource, definition, **params))
|
||||
return self.client.patch(resource, definition, **params).to_dict()
|
||||
except Exception as e:
|
||||
reason = e.body if hasattr(e, "body") else e
|
||||
msg = "Failed to patch object: {0}".format(reason)
|
||||
@@ -326,124 +330,123 @@ class K8sService:
|
||||
result["resources"].append(hide_fields(res, hidden_fields))
|
||||
return result
|
||||
|
||||
def create(self, resource: Resource, definition: Dict) -> Tuple[Dict, List[str]]:
|
||||
def create(self, resource: Resource, definition: Dict) -> Dict:
|
||||
namespace = definition["metadata"].get("namespace")
|
||||
name = definition["metadata"].get("name")
|
||||
|
||||
if self._client_side_dry_run:
|
||||
return _encode_stringdata(definition), []
|
||||
|
||||
try:
|
||||
return decode_response(
|
||||
self.client.create(
|
||||
resource, definition, namespace=namespace, serialize=False
|
||||
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
|
||||
)
|
||||
)
|
||||
)
|
||||
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
|
||||
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
|
||||
|
||||
def apply(
|
||||
self,
|
||||
resource: Resource,
|
||||
definition: Dict,
|
||||
existing: Optional[ResourceInstance] = None,
|
||||
) -> Tuple[Dict, List[str]]:
|
||||
) -> Dict:
|
||||
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:
|
||||
return dict_merge(existing.to_dict(), patch), []
|
||||
k8s_obj = dict_merge(existing.to_dict(), patch)
|
||||
else:
|
||||
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
|
||||
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
|
||||
|
||||
def replace(
|
||||
self,
|
||||
resource: Resource,
|
||||
definition: Dict,
|
||||
existing: ResourceInstance,
|
||||
) -> Tuple[Dict, List[str]]:
|
||||
) -> Dict:
|
||||
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:
|
||||
return _encode_stringdata(definition), []
|
||||
|
||||
try:
|
||||
return decode_response(
|
||||
self.client.replace(
|
||||
k8s_obj = _encode_stringdata(definition)
|
||||
else:
|
||||
try:
|
||||
k8s_obj = self.client.replace(
|
||||
resource,
|
||||
definition,
|
||||
name=name,
|
||||
namespace=namespace,
|
||||
append_hash=append_hash,
|
||||
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
|
||||
).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
|
||||
|
||||
def update(
|
||||
self, resource: Resource, definition: Dict, existing: ResourceInstance
|
||||
) -> Tuple[Dict, List[str]]:
|
||||
) -> Dict:
|
||||
name = definition["metadata"].get("name")
|
||||
namespace = definition["metadata"].get("namespace")
|
||||
|
||||
if self._client_side_dry_run:
|
||||
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
|
||||
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
|
||||
|
||||
def delete(
|
||||
self,
|
||||
@@ -473,7 +476,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",
|
||||
@@ -540,83 +543,3 @@ def hide_field(definition: dict, hidden_field: str) -> dict:
|
||||
else:
|
||||
del definition[split[0]]
|
||||
return definition
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -137,14 +137,14 @@ 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
|
||||
|
||||
#Helm options
|
||||
disable_hook:
|
||||
|
||||
@@ -189,7 +189,7 @@ def main():
|
||||
repo_password=dict(
|
||||
type="str", no_log=True, aliases=["password", "chart_repo_password"]
|
||||
),
|
||||
pass_credentials=dict(type="bool", default=False),
|
||||
pass_credentials=dict(type="bool", default=False, no_log=False),
|
||||
skip_tls_certs_check=dict(type="bool", default=False),
|
||||
chart_devel=dict(type="bool"),
|
||||
untar_chart=dict(type="bool", default=False),
|
||||
|
||||
@@ -57,14 +57,15 @@ 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) has been removed in version 4.0.0. Please use M(kubernetes.core.k8s_json_patch) instead.
|
||||
- mutually exclusive with C(apply)
|
||||
- I(merge_type=json) is deprecated and will be removed in version 4.0.0. Please use M(kubernetes.core.k8s_json_patch) instead.
|
||||
choices:
|
||||
- json
|
||||
- merge
|
||||
- strategic-merge
|
||||
type: list
|
||||
@@ -100,7 +101,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:
|
||||
@@ -181,7 +182,7 @@ 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:
|
||||
@@ -191,7 +192,7 @@ options:
|
||||
- Only field definitions that don't reference list items are supported (so V(spec.containers[0]) would not work)
|
||||
type: list
|
||||
elements: str
|
||||
version_added: 2.5.0
|
||||
version_added: 3.0.0
|
||||
|
||||
requirements:
|
||||
- "python >= 3.9"
|
||||
@@ -459,7 +460,7 @@ def argspec():
|
||||
argument_spec.update(copy.deepcopy(AUTH_ARG_SPEC))
|
||||
argument_spec.update(copy.deepcopy(WAIT_ARG_SPEC))
|
||||
argument_spec["merge_type"] = dict(
|
||||
type="list", elements="str", choices=["merge", "strategic-merge"]
|
||||
type="list", elements="str", choices=["json", "merge", "strategic-merge"]
|
||||
)
|
||||
argument_spec["validate"] = dict(type="dict", default=None, options=validate_spec())
|
||||
argument_spec["append_hash"] = dict(type="bool", default=False)
|
||||
|
||||
@@ -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:
|
||||
@@ -143,6 +143,7 @@ result:
|
||||
"""
|
||||
|
||||
import copy
|
||||
import json
|
||||
import time
|
||||
import traceback
|
||||
from datetime import datetime
|
||||
@@ -187,6 +188,17 @@ except ImportError:
|
||||
HAS_EVICTION_API = False
|
||||
|
||||
|
||||
def format_dynamic_api_exc(exc):
|
||||
if exc.body:
|
||||
if exc.headers and exc.headers.get("Content-Type") == "application/json":
|
||||
message = json.loads(exc.body).get("message")
|
||||
if message:
|
||||
return message
|
||||
return exc.body
|
||||
else:
|
||||
return "%s Reason: %s" % (exc.status, exc.reason)
|
||||
|
||||
|
||||
def filter_pods(pods, force, ignore_daemonset, delete_emptydir_data):
|
||||
k8s_kind_mirror = "kubernetes.io/config.mirror"
|
||||
daemonSet, unmanaged, mirror, localStorage, to_delete = [], [], [], [], []
|
||||
@@ -291,16 +303,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 +323,7 @@ class K8sDrainAnsible(object):
|
||||
msg="Exception raised: {0}".format(exc.reason)
|
||||
)
|
||||
pod = None
|
||||
del pods[-1]
|
||||
except Exception as e:
|
||||
self._module.fail_json(msg="Exception raised: {0}".format(to_native(e)))
|
||||
if not pods:
|
||||
@@ -334,7 +350,7 @@ class K8sDrainAnsible(object):
|
||||
if exc.reason != "Not Found":
|
||||
self._module.fail_json(
|
||||
msg="Failed to delete pod {0}/{1} due to: {2}".format(
|
||||
namespace, name, exc.reason
|
||||
namespace, name, to_native(format_dynamic_api_exc(exc))
|
||||
)
|
||||
)
|
||||
except Exception as exc:
|
||||
|
||||
@@ -135,7 +135,7 @@ from ansible.module_utils._text import to_native
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
|
||||
AnsibleModule,
|
||||
)
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.common import (
|
||||
AUTH_ARG_SPEC,
|
||||
)
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
|
||||
@@ -219,6 +219,12 @@ 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,
|
||||
|
||||
@@ -51,7 +51,7 @@ options:
|
||||
- Only field definitions that don't reference list items are supported (so V(spec.containers[0]) would not work)
|
||||
type: list
|
||||
elements: str
|
||||
version_added: 2.5.0
|
||||
version_added: 3.0.0
|
||||
|
||||
extends_documentation_fragment:
|
||||
- kubernetes.core.k8s_auth_options
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
loop_control:
|
||||
loop_var: helm_version
|
||||
with_items:
|
||||
- "v3.7.0"
|
||||
- "v3.8.0"
|
||||
|
||||
@@ -17,8 +17,7 @@
|
||||
- name: Initial chart installation
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: redis
|
||||
chart_repo_url: https://charts.bitnami.com/bitnami
|
||||
chart_ref: oci://registry-1.docker.io/bitnamicharts/redis
|
||||
release_name: test-redis
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
create_namespace: true
|
||||
@@ -42,8 +41,7 @@
|
||||
- name: Upgrade chart using reuse_values=true
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: redis
|
||||
chart_repo_url: https://charts.bitnami.com/bitnami
|
||||
chart_ref: oci://registry-1.docker.io/bitnamicharts/redis
|
||||
release_name: test-redis
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
reuse_values: true
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
assert:
|
||||
that:
|
||||
- install is changed
|
||||
- install.status.chart == chart_test+"-"+chart_test_version
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- install.status.status | lower == 'deployed'
|
||||
|
||||
- name: Check helm_info content
|
||||
@@ -95,7 +95,7 @@
|
||||
- name: "Assert that {{ chart_test }} is installed from {{ source }} with helm_info"
|
||||
assert:
|
||||
that:
|
||||
- content_info.status.chart == chart_test+"-"+chart_test_version
|
||||
- content_info.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- content_info.status.status | lower == 'deployed'
|
||||
- release_state_content_info.status.status | lower == 'deployed'
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
assert:
|
||||
that:
|
||||
- install is not changed
|
||||
- install.status.chart == chart_test+"-"+chart_test_version
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- install.status.status | lower == 'deployed'
|
||||
|
||||
- name: "Add vars to {{ chart_test }} from {{ source }}"
|
||||
@@ -130,7 +130,7 @@
|
||||
that:
|
||||
- install is changed
|
||||
- install.status.status | lower == 'deployed'
|
||||
- install.status.chart == chart_test+"-"+chart_test_version
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- "install.status['values'].revisionHistoryLimit == 0"
|
||||
|
||||
- name: Check idempotency after adding vars
|
||||
@@ -148,7 +148,7 @@
|
||||
that:
|
||||
- install is not changed
|
||||
- install.status.status | lower == 'deployed'
|
||||
- install.status.chart == chart_test+"-"+chart_test_version
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- "install.status['values'].revisionHistoryLimit == 0"
|
||||
|
||||
- name: "Remove Vars to {{ chart_test }} from {{ source }}"
|
||||
@@ -165,7 +165,7 @@
|
||||
that:
|
||||
- install is changed
|
||||
- install.status.status | lower == 'deployed'
|
||||
- install.status.chart == chart_test+"-"+chart_test_version
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- install.status['values'] == {}
|
||||
|
||||
- name: Check idempotency after removing vars
|
||||
@@ -182,7 +182,7 @@
|
||||
that:
|
||||
- install is not changed
|
||||
- install.status.status | lower == 'deployed'
|
||||
- install.status.chart == chart_test+"-"+chart_test_version
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- install.status['values'] == {}
|
||||
|
||||
- name: "Upgrade {{ chart_test }} from {{ source }}"
|
||||
@@ -199,7 +199,7 @@
|
||||
that:
|
||||
- install is changed
|
||||
- install.status.status | lower == 'deployed'
|
||||
- install.status.chart == chart_test+"-"+chart_test_version_upgrade
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version_upgrade }}"
|
||||
|
||||
- name: Check idempotency after upgrade
|
||||
helm:
|
||||
@@ -215,7 +215,7 @@
|
||||
that:
|
||||
- install is not changed
|
||||
- install.status.status | lower == 'deployed'
|
||||
- install.status.chart == chart_test+"-"+chart_test_version_upgrade
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version_upgrade }}"
|
||||
|
||||
- name: "Remove {{ chart_test }} from {{ source }}"
|
||||
helm:
|
||||
@@ -316,7 +316,7 @@
|
||||
that:
|
||||
- install is changed
|
||||
- install.status.status | lower == 'deployed'
|
||||
- install.status.chart == chart_test+"-"+chart_test_version
|
||||
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
|
||||
- "install.status['values'].revisionHistoryLimit == 0"
|
||||
|
||||
- name: "Install {{ chart_test }} from {{ source }} with values_files (again)"
|
||||
@@ -357,7 +357,7 @@
|
||||
- result is changed
|
||||
- result is not failed
|
||||
- result.rc == 0
|
||||
- result.command is match(helm_binary+" template "+chart_source)
|
||||
- result.command is match("{{ helm_binary }} template {{ chart_source }}")
|
||||
|
||||
- name: Check templates created
|
||||
stat:
|
||||
@@ -374,8 +374,8 @@
|
||||
chart_ref: "{{ chart_source }}"
|
||||
chart_version: "{{ chart_source_version | default(omit) }}"
|
||||
disable_hook: True
|
||||
release_name: "MyRelease"
|
||||
release_namespace: "MyReleaseNamespace"
|
||||
release_name: "myrelease"
|
||||
release_namespace: "myreleasenamespace"
|
||||
show_only:
|
||||
- "templates/configmap.yaml"
|
||||
release_values:
|
||||
@@ -388,7 +388,7 @@
|
||||
- result is changed
|
||||
- result is not failed
|
||||
- result.rc == 0
|
||||
- result.command is match(helm_binary+" template MyRelease "+chart_source)
|
||||
- result.command is match(helm_binary+" template myrelease "+chart_source)
|
||||
- result.stdout is search("ThisValue")
|
||||
when: chart_source is search("test-chart")
|
||||
# limit assertion of test result to controlled (local) chart_source
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: test-chart-deployment-time
|
||||
description: A chart with a config map containing the deployment time in data
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "default"
|
||||
@@ -0,0 +1,7 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ default "ansible-configmap" .Values.myConfigmapName }}
|
||||
data:
|
||||
myValue: {{ default "test" .Values.myValue }}
|
||||
deploymentTime: {{ now }}
|
||||
@@ -2,3 +2,4 @@
|
||||
dependencies:
|
||||
- remove_namespace
|
||||
- install_helm
|
||||
- setup_helm_registry
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
- name: Test helm diff functionality
|
||||
vars:
|
||||
test_chart_ref: "/tmp/test-chart"
|
||||
redis_chart_version: '17.0.5'
|
||||
|
||||
block:
|
||||
|
||||
@@ -24,7 +23,7 @@
|
||||
name: test-chart
|
||||
namespace: "{{ helm_namespace }}"
|
||||
chart_ref: "{{ test_chart_ref }}"
|
||||
create_namespace: yes
|
||||
create_namespace: true
|
||||
register: install
|
||||
|
||||
- assert:
|
||||
@@ -49,8 +48,8 @@
|
||||
name: test-chart
|
||||
namespace: "{{ helm_namespace }}"
|
||||
chart_ref: "{{ test_chart_ref }}"
|
||||
check_mode: yes
|
||||
diff: yes
|
||||
check_mode: true
|
||||
diff: true
|
||||
register: diff_result
|
||||
|
||||
- name: Check if helm diff check is correct
|
||||
@@ -79,7 +78,7 @@
|
||||
namespace: "{{ helm_namespace }}"
|
||||
chart_ref: "{{ test_chart_ref }}"
|
||||
check_mode: yes
|
||||
diff: yes
|
||||
diff: true
|
||||
register: diff_result
|
||||
|
||||
- name: Check if no diff in check mode when no change
|
||||
@@ -101,7 +100,7 @@
|
||||
|
||||
- name: Modify values
|
||||
blockinfile:
|
||||
create: yes
|
||||
create: true
|
||||
path: "{{ test_chart_ref }}/values.yml"
|
||||
block: |
|
||||
---
|
||||
@@ -206,52 +205,76 @@
|
||||
- install is not changed
|
||||
|
||||
# Test helm diff with chart_repo_url
|
||||
- name: Define Redis chart values
|
||||
set_fact:
|
||||
redis_chart_values:
|
||||
commonLabels:
|
||||
phase: testing
|
||||
company: RedHat
|
||||
image:
|
||||
tag: 6.2.6-debian-10-r135
|
||||
architecture: standalone
|
||||
|
||||
- name: Install Redis chart
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_repo_url: https://charts.bitnami.com/bitnami
|
||||
chart_ref: redis
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: redis-chart
|
||||
chart_version: "{{ redis_chart_version }}"
|
||||
release_values: "{{ redis_chart_values }}"
|
||||
|
||||
- name: Upgrade Redis chart
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_repo_url: https://charts.bitnami.com/bitnami
|
||||
chart_ref: redis
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: redis-chart
|
||||
chart_version: "{{ redis_chart_version }}"
|
||||
release_values: "{{ redis_chart_values }}"
|
||||
check_mode: yes
|
||||
register: redis_upgrade
|
||||
|
||||
- name: Assert that module raised a warning
|
||||
assert:
|
||||
that:
|
||||
- not redis_upgrade.changed
|
||||
- redis_upgrade.warnings is defined
|
||||
- redis_upgrade.warnings | length == 1
|
||||
- redis_upgrade.warnings[0] == "The default idempotency check can fail to report changes in certain cases. Install helm diff >= 3.4.1 for better results."
|
||||
|
||||
- name: Uninstall helm diff
|
||||
helm_plugin:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
state: absent
|
||||
plugin_name: diff
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
|
||||
- name: Define chart variables
|
||||
set_fact:
|
||||
test_chart_values:
|
||||
myValue: 'Some ConfigMap data value'
|
||||
myConfigmapName: 'ansible-config-from-url'
|
||||
test_chart_version: 0.1.0
|
||||
test_chart_ref_url: "oci://localhost:6035/testing/test-chart-deployment-time"
|
||||
|
||||
- name: Deploy chart to remote registry
|
||||
block:
|
||||
- name: Create local directory to copy chart in
|
||||
ansible.builtin.tempfile:
|
||||
suffix: .chart
|
||||
state: directory
|
||||
register: _tmpd
|
||||
|
||||
- name: Copy local registry
|
||||
ansible.builtin.copy:
|
||||
dest: "{{ _tmpd.path }}"
|
||||
src: '{{ role_path }}/files/test-chart-deployment-time'
|
||||
|
||||
- name: Push chart to helm registry
|
||||
ansible.builtin.include_role:
|
||||
name: push_to_helm_registry
|
||||
vars:
|
||||
chart_local_path: '{{ _tmpd.path }}/test-chart-deployment-time'
|
||||
chart_repo_path: 'testing'
|
||||
always:
|
||||
- name: Delete temporary directory
|
||||
ansible.builtin.file:
|
||||
state: absent
|
||||
path: '{{ _tmpd.path }}'
|
||||
|
||||
- name: Log into Helm registry
|
||||
ansible.builtin.command: "{{ helm_binary }} registry login -u testuser -p 'pass123!' localhost:6035"
|
||||
|
||||
- name: Install chart from remote URL
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "{{ test_chart_ref_url }}"
|
||||
chart_version: 0.1.0
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: another-chart
|
||||
release_values: "{{ test_chart_values }}"
|
||||
|
||||
- name: Upgrade chart
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: "{{ test_chart_ref_url }}"
|
||||
chart_version: 0.1.0
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: another-chart
|
||||
release_values: "{{ test_chart_values }}"
|
||||
check_mode: true
|
||||
register: _upgrade
|
||||
|
||||
- name: Assert that module raised a warning
|
||||
assert:
|
||||
that:
|
||||
- not _upgrade.changed
|
||||
- _upgrade.warnings is defined
|
||||
- _upgrade.warnings | length == 1
|
||||
- _upgrade.warnings[0] == "The default idempotency check can fail to report changes in certain cases. Install helm diff >= 3.4.1 for better results."
|
||||
|
||||
- name: Install helm diff (version=3.4.1)
|
||||
helm_plugin:
|
||||
@@ -260,37 +283,36 @@
|
||||
plugin_path: https://github.com/databus23/helm-diff
|
||||
plugin_version: 3.4.1
|
||||
|
||||
- name: Upgrade Redis chart once again
|
||||
- name: Upgrade chart once again
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_repo_url: https://charts.bitnami.com/bitnami
|
||||
chart_ref: redis
|
||||
chart_ref: "{{ test_chart_ref_url }}"
|
||||
chart_version: 0.1.0
|
||||
namespace: "{{ helm_namespace }}"
|
||||
name: redis-chart
|
||||
chart_version: "{{ redis_chart_version }}"
|
||||
release_values: "{{ redis_chart_values }}"
|
||||
check_mode: yes
|
||||
register: redis_upgrade_2
|
||||
name: another-chart
|
||||
release_values: "{{ test_chart_values }}"
|
||||
check_mode: true
|
||||
register: _upgrade_2
|
||||
|
||||
- name: Assert that module raised a warning
|
||||
assert:
|
||||
that:
|
||||
- redis_upgrade_2.changed
|
||||
- redis_upgrade_2.warnings is not defined
|
||||
- _upgrade_2.changed
|
||||
- _upgrade_2.warnings is not defined
|
||||
|
||||
always:
|
||||
- name: Remove chart directory
|
||||
file:
|
||||
path: "{{ test_chart_ref }}"
|
||||
state: absent
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
|
||||
- name: Uninstall helm diff
|
||||
helm_plugin:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
state: absent
|
||||
plugin_name: diff
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
|
||||
- name: Remove helm namespace
|
||||
k8s:
|
||||
@@ -299,6 +321,6 @@
|
||||
name: "{{ helm_namespace }}"
|
||||
state: absent
|
||||
wait: true
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
|
||||
- include_tasks: reuse_values.yml
|
||||
|
||||
@@ -18,7 +18,12 @@
|
||||
- set_fact:
|
||||
saved_kubeconfig_path: "{{ _dir.path }}/config"
|
||||
|
||||
- block:
|
||||
- vars:
|
||||
helm_repo_name: autoscaler
|
||||
helm_repo_url: "https://kubernetes.github.io/autoscaler"
|
||||
helm_release_name: "autoscaler"
|
||||
helm_chart_name: "cluster-autoscaler"
|
||||
block:
|
||||
- name: Copy default kubeconfig
|
||||
copy:
|
||||
remote_src: true
|
||||
@@ -59,14 +64,14 @@
|
||||
- plugin_info.plugin_list != []
|
||||
|
||||
# helm_repository, helm, helm_info
|
||||
- name: Add test_bitnami chart repository
|
||||
- name: 'Add "{{ helm_repo_name }}" chart repository'
|
||||
helm_repository:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
name: test_bitnami
|
||||
name: "{{ helm_repo_name }}"
|
||||
kubeconfig: "{{ test_kubeconfig | default(omit) }}"
|
||||
validate_certs: "{{ test_validate_certs | default(omit) }}"
|
||||
ca_cert: "{{ test_ca_cert | default(omit) }}"
|
||||
repo_url: https://charts.bitnami.com/bitnami
|
||||
repo_url: "{{ helm_repo_url }}"
|
||||
register: repository
|
||||
|
||||
- name: Assert that repository was added
|
||||
@@ -77,8 +82,8 @@
|
||||
- name: Install chart from repository added before
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
name: rabbitmq
|
||||
chart_ref: test_bitnami/rabbitmq
|
||||
name: "{{ helm_release_name }}"
|
||||
chart_ref: "{{ helm_repo_name }}/{{ helm_chart_name }}"
|
||||
namespace: "{{ helm_namespace }}"
|
||||
update_repo_cache: true
|
||||
kubeconfig: "{{ test_kubeconfig | default(omit) }}"
|
||||
@@ -98,7 +103,7 @@
|
||||
kubeconfig: "{{ test_kubeconfig | default(omit) }}"
|
||||
validate_certs: "{{ test_validate_certs | default(omit) }}"
|
||||
ca_cert: "{{ test_ca_cert | default(omit) }}"
|
||||
name: "rabbitmq"
|
||||
name: "{{ helm_release_name }}"
|
||||
namespace: "{{ helm_namespace }}"
|
||||
register: chart_info
|
||||
|
||||
@@ -112,7 +117,7 @@
|
||||
- name: Remove chart
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
name: rabbitmq
|
||||
name: "{{ helm_release_name }}"
|
||||
namespace: "{{ helm_namespace }}"
|
||||
kubeconfig: "{{ test_kubeconfig | default(omit) }}"
|
||||
validate_certs: "{{ test_validate_certs | default(omit) }}"
|
||||
@@ -131,7 +136,7 @@
|
||||
kubeconfig: "{{ test_kubeconfig | default(omit) }}"
|
||||
validate_certs: "{{ test_validate_certs | default(omit) }}"
|
||||
ca_cert: "{{ test_ca_cert | default(omit) }}"
|
||||
name: "rabbitmq"
|
||||
name: "{{ helm_release_name }}"
|
||||
namespace: "{{ helm_namespace }}"
|
||||
register: chart_info
|
||||
|
||||
@@ -143,7 +148,7 @@
|
||||
- name: Remove chart repository
|
||||
helm_repository:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
name: test_bitnami
|
||||
name: "{{ helm_repo_name }}"
|
||||
kubeconfig: "{{ test_kubeconfig | default(omit) }}"
|
||||
validate_certs: "{{ test_validate_certs | default(omit) }}"
|
||||
ca_cert: "{{ test_ca_cert | default(omit) }}"
|
||||
@@ -192,6 +197,6 @@
|
||||
- name: Delete helm repository
|
||||
helm_repository:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
name: test_bitnami
|
||||
name: "{{ helm_repo_name }}"
|
||||
state: absent
|
||||
ignore_errors: true
|
||||
|
||||
@@ -180,6 +180,7 @@
|
||||
- '"--username ansible" in _result.command'
|
||||
- '"--password ***" in _result.command'
|
||||
- '"--keyring pubring.gpg" in _result.command'
|
||||
- '"Module did not set no_log for pass_credentials" not in _result.stderr'
|
||||
|
||||
- name: Download chart using chart_ref
|
||||
helm_pull:
|
||||
@@ -203,9 +204,8 @@
|
||||
- name: Download chart using untar_chart
|
||||
helm_pull:
|
||||
binary_path: "{{ helm_path }}"
|
||||
chart_ref: redis
|
||||
chart_ref: "oci://registry-1.docker.io/bitnamicharts/redis"
|
||||
destination: "{{ destination }}"
|
||||
repo_url: "https://charts.bitnami.com/bitnami"
|
||||
untar_chart: true
|
||||
register: _result
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
- name: Install helm using set_values parameters
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: mariadb
|
||||
chart_repo_url: https://charts.bitnami.com/bitnami
|
||||
chart_ref: oci://registry-1.docker.io/bitnamicharts/mariadb
|
||||
release_name: test-mariadb
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
create_namespace: true
|
||||
@@ -36,8 +35,7 @@
|
||||
- name: Install helm using set_values parameters
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: apache
|
||||
chart_repo_url: https://charts.bitnami.com/bitnami
|
||||
chart_ref: oci://registry-1.docker.io/bitnamicharts/apache
|
||||
release_name: test-apache
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
create_namespace: true
|
||||
@@ -79,8 +77,7 @@
|
||||
- name: Install helm using set_values parameters
|
||||
helm:
|
||||
binary_path: "{{ helm_binary }}"
|
||||
chart_ref: minio
|
||||
chart_repo_url: https://charts.bitnami.com/bitnami
|
||||
chart_ref: oci://registry-1.docker.io/bitnamicharts/minio
|
||||
release_name: test-minio
|
||||
release_namespace: "{{ helm_namespace }}"
|
||||
create_namespace: true
|
||||
@@ -107,3 +104,11 @@
|
||||
file:
|
||||
state: absent
|
||||
path: "{{ ymlfile.path }}"
|
||||
ignore_errors: true
|
||||
|
||||
- name: Delete namespace
|
||||
k8s:
|
||||
state: absent
|
||||
kind: namespace
|
||||
name: "{{ helm_namespace }}"
|
||||
ignore_errors: true
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
---
|
||||
helm_version: v3.7.0
|
||||
helm_version: v3.8.0
|
||||
helm_install_path: /tmp/helm
|
||||
helm_default_archive_name: "helm-{{ helm_version }}-{{ ansible_system | lower }}-amd64.tar.gz"
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
assert:
|
||||
that:
|
||||
- k8s_configmap is changed
|
||||
- k8s_configmap.result.metadata.annotations|default(False)
|
||||
- '"annotations" in k8s_configmap.result.metadata'
|
||||
- k8s_configmap.result.metadata.annotations != {}
|
||||
|
||||
- name: Add same configmap again
|
||||
k8s:
|
||||
@@ -467,7 +468,7 @@
|
||||
assert:
|
||||
that:
|
||||
- k8s_secret is changed
|
||||
- k8s_secret.result.data.foo
|
||||
- k8s_secret.result.data.foo != ""
|
||||
|
||||
- name: Add same secret
|
||||
k8s:
|
||||
@@ -748,7 +749,7 @@
|
||||
assert:
|
||||
that:
|
||||
- _create is changed
|
||||
- not _info.resources
|
||||
- _info.resources | length == 0
|
||||
|
||||
# server side apply over kubernetes client releases
|
||||
- name: Create temporary directory
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
- name: Assert that there are pods
|
||||
assert:
|
||||
that:
|
||||
- pods_create.resources
|
||||
- pods_create.resources | length > 0
|
||||
|
||||
- name: Remove the daemonset
|
||||
k8s:
|
||||
@@ -74,7 +74,7 @@
|
||||
- name: Assert that deleting the daemonset deleted the pods
|
||||
assert:
|
||||
that:
|
||||
- not pods_delete.resources
|
||||
- pods_delete.resources | length == 0
|
||||
|
||||
# test deletion using label selector
|
||||
- name: Deploy load balancer
|
||||
@@ -152,6 +152,27 @@
|
||||
register: _deployment
|
||||
failed_when: _deployment.resources | length == 0
|
||||
|
||||
- name: Trying to delete nginx deployment in check mode and with deleteOptions set
|
||||
k8s:
|
||||
kind: Deployment
|
||||
api_version: apps/v1
|
||||
namespace: "{{ test_namespace }}"
|
||||
name: nginx-d
|
||||
state: absent
|
||||
delete_options:
|
||||
propagationPolicy: Foreground
|
||||
check_mode: true
|
||||
register: _delete
|
||||
|
||||
- name: Validate that Deployment nginx-d still exists
|
||||
k8s_info:
|
||||
kind: Deployment
|
||||
api_version: apps/v1
|
||||
namespace: "{{ test_namespace }}"
|
||||
name: nginx-d
|
||||
register: _deployment
|
||||
failed_when: _deployment.resources | length != 1
|
||||
|
||||
- name: Trying to delete using delete_all=true but missing kind option
|
||||
k8s:
|
||||
api_version: apps/v1
|
||||
|
||||
@@ -182,7 +182,7 @@
|
||||
- name: assert that pods are running on cordoned node
|
||||
assert:
|
||||
that:
|
||||
- Pod.resources | selectattr('status.phase', 'equalto', 'Running') | selectattr('spec.nodeName', 'equalto', node_to_drain) | list | length > 0
|
||||
- "{{ Pod.resources | selectattr('status.phase', 'equalto', 'Running') | selectattr('spec.nodeName', 'equalto', node_to_drain) | list | length > 0 }}"
|
||||
|
||||
- name: Uncordon node
|
||||
k8s_drain:
|
||||
@@ -236,7 +236,7 @@
|
||||
assert:
|
||||
that:
|
||||
- drain_result is changed
|
||||
- '"node "+node_to_drain+" marked unschedulable." in drain_result.result'
|
||||
- '"node {{ node_to_drain }} marked unschedulable." in drain_result.result'
|
||||
|
||||
- name: assert that unmanaged pod were deleted
|
||||
k8s_info:
|
||||
@@ -244,7 +244,7 @@
|
||||
kind: Pod
|
||||
name: '{{ drain_pod_name }}'
|
||||
register: _result
|
||||
failed_when: _result.resources
|
||||
failed_when: _result.resources | length > 0
|
||||
|
||||
- name: assert that emptyDir pod was deleted
|
||||
k8s_info:
|
||||
@@ -338,7 +338,7 @@
|
||||
assert:
|
||||
that:
|
||||
- disable_evict is changed
|
||||
- '"node "+node_to_drain+" marked unschedulable." in disable_evict.result'
|
||||
- '"node {{ node_to_drain }} marked unschedulable." in disable_evict.result'
|
||||
|
||||
- name: assert that unmanaged pod were deleted
|
||||
k8s_info:
|
||||
@@ -346,7 +346,7 @@
|
||||
kind: Pod
|
||||
name: '{{ drain_pod_name }}-01'
|
||||
register: _result
|
||||
failed_when: _result.resources
|
||||
failed_when: _result.resources | length > 0
|
||||
|
||||
# test: drain using pod_selectors
|
||||
- name: Uncordon node
|
||||
@@ -401,7 +401,7 @@
|
||||
assert:
|
||||
that:
|
||||
- drain_pod_selector is changed
|
||||
- '"node "+node_to_drain+" marked unschedulable." in drain_pod_selector.result'
|
||||
- '"node {{ node_to_drain }} marked unschedulable." in drain_pod_selector.result'
|
||||
|
||||
- name: assert that pod created before is still running
|
||||
k8s_info:
|
||||
@@ -429,8 +429,8 @@
|
||||
assert:
|
||||
that:
|
||||
- drain_pod_selector_equal is changed
|
||||
- '"node "+node_to_drain+" already marked unschedulable." in drain_pod_selector_equal.result'
|
||||
- '"Deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: "+test_namespace+"/ansible-drain-pod." in drain_pod_selector_equal.warnings'
|
||||
- '"node {{ node_to_drain }} already marked unschedulable." in drain_pod_selector_equal.result'
|
||||
- '"Deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: {{ test_namespace }}/ansible-drain-pod." in drain_pod_selector_equal.warnings'
|
||||
|
||||
- name: Uncordon node
|
||||
k8s_drain:
|
||||
|
||||
@@ -394,9 +394,11 @@
|
||||
register: k8s_info_testing6
|
||||
failed_when: not k8s_info_testing6.resources or k8s_info_testing6.resources[0].status.phase != "Active"
|
||||
|
||||
- name: Create large configmap data
|
||||
command: dd if=/dev/urandom bs=500K count=1
|
||||
register: cmap_data
|
||||
- name: Create a file with specific size and attributes, to be used as swap space
|
||||
community.general.filesize:
|
||||
path: /tmp/configmap.bin
|
||||
size: 500K
|
||||
source: /dev/urandom
|
||||
|
||||
- name: Create configmap with large value
|
||||
k8s:
|
||||
@@ -407,7 +409,7 @@
|
||||
name: testmap
|
||||
namespace: testing
|
||||
data:
|
||||
testkey: "{{ cmap_data.stdout | b64encode }}"
|
||||
testkey: "{{ lookup('file', '/tmp/configmap.bin') | b64encode }}"
|
||||
wait: true
|
||||
register: result
|
||||
|
||||
@@ -424,7 +426,7 @@
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result.resources[0].data.testkey == (cmap_data.stdout | b64encode)
|
||||
- result.resources[0].data.testkey == (lookup('file', '/tmp/configmap.bin') | b64encode)
|
||||
|
||||
# test setting module defaults for kubernetes.core.k8s_info
|
||||
- block:
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
label_selectors:
|
||||
- "job=gc"
|
||||
register: wait_job
|
||||
until: wait_job.resources
|
||||
until: wait_job.resources | length > 0
|
||||
retries: 5
|
||||
delay: 10
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
label_selectors:
|
||||
- "job=gc"
|
||||
register: wait_job
|
||||
until: wait_job.resources
|
||||
until: wait_job.resources | length > 0
|
||||
retries: 5
|
||||
delay: 10
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
label_selectors:
|
||||
- "job=gc"
|
||||
register: wait_job
|
||||
until: wait_job.resources
|
||||
until: wait_job.resources | length > 0
|
||||
retries: 5
|
||||
delay: 10
|
||||
|
||||
@@ -225,7 +225,7 @@
|
||||
|
||||
- name: Assert job is deleted
|
||||
assert:
|
||||
that: not job.resources
|
||||
that: job.resources | length == 0
|
||||
|
||||
always:
|
||||
- name: Delete namespace
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
- name: assert pod has been created
|
||||
assert:
|
||||
that:
|
||||
- pods.resources | length == 1
|
||||
- "{{ pods.resources | length == 1 }}"
|
||||
|
||||
- name: create pod using generate_name parameter should succeed
|
||||
k8s:
|
||||
@@ -86,7 +86,7 @@
|
||||
- name: assert pod has been created
|
||||
assert:
|
||||
that:
|
||||
- pods.resources | length == 2
|
||||
- "{{ pods.resources | length == 2 }}"
|
||||
|
||||
- name: create pod using metadata.generateName parameter should succeed
|
||||
k8s:
|
||||
@@ -102,7 +102,7 @@
|
||||
- name: assert pod has been created
|
||||
assert:
|
||||
that:
|
||||
- pods.resources | length == 3
|
||||
- "{{ pods.resources | length == 3 }}"
|
||||
|
||||
- name: create object using metadata.generateName should support wait option
|
||||
k8s:
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
- result.changed
|
||||
- result.result.metadata.labels.label2 == "bar"
|
||||
- result.result.spec.containers[0].image == "busybox:glibc"
|
||||
- result.diff
|
||||
- result.diff != {}
|
||||
|
||||
- name: Describe pod
|
||||
kubernetes.core.k8s_info:
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
assert:
|
||||
that:
|
||||
- fake_pod is failed
|
||||
- fake_pod.msg == "Pod "+test_namespace+"/this_pod_does_exist not found."
|
||||
- 'fake_pod.msg == "Pod {{ test_namespace }}/this_pod_does_exist not found."'
|
||||
|
||||
- name: create hello-world deployment
|
||||
k8s:
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
- name: Update directory permissions
|
||||
file:
|
||||
path: "{{ manifests_dir.path }}"
|
||||
mode: 0755
|
||||
mode: '0755'
|
||||
|
||||
- name: Create manifests files
|
||||
copy:
|
||||
|
||||
@@ -129,7 +129,7 @@
|
||||
that:
|
||||
- scale_down is changed
|
||||
- '"duration" in scale_down'
|
||||
- scale_down.diff
|
||||
- scale_down.diff != {}
|
||||
|
||||
- name: Scale the deployment once again (idempotency)
|
||||
k8s_scale:
|
||||
@@ -274,7 +274,7 @@
|
||||
assert:
|
||||
that:
|
||||
- scale_down_no_wait is changed
|
||||
- scale_down_no_wait.diff
|
||||
- scale_down_no_wait.diff != {}
|
||||
- scale_down_no_wait_pods.resources | length == 1
|
||||
|
||||
# scale multiple resource using label selectors
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
assert:
|
||||
that:
|
||||
- _result.result.status.phase == 'Running'
|
||||
- _result.result.spec.nodeName == node_to_taint
|
||||
- _result.result.spec.nodeName == "{{ node_to_taint }}"
|
||||
|
||||
- name: Taint node (check_mode)
|
||||
kubernetes.core.k8s_taint:
|
||||
@@ -89,8 +89,8 @@
|
||||
assert:
|
||||
that:
|
||||
- _result.changed
|
||||
- item['effect'] == taint_patch_1[0]['effect']
|
||||
- item['key'] == taint_patch_1[0]['key']
|
||||
- "{{ item['effect'] == taint_patch_1[0]['effect'] }}"
|
||||
- "{{ item['key'] == taint_patch_1[0]['key'] }}"
|
||||
loop: "{{ _result.result.spec.taints }}"
|
||||
|
||||
- name: Taint node (idempotency) - (check_mode)
|
||||
@@ -421,7 +421,7 @@
|
||||
- name: Assert that taints have been removed
|
||||
assert:
|
||||
that:
|
||||
- _result.resources | selectattr('spec.taints', 'undefined')
|
||||
- _result.resources | selectattr('spec.taints', 'undefined') | list | length > 0
|
||||
|
||||
always:
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
kubernetes.core.k8s_service:
|
||||
template: "pod_one.j2"
|
||||
state: present
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
register: r
|
||||
|
||||
- name: Check for expected failures in last tasks
|
||||
@@ -35,7 +35,7 @@
|
||||
k8s_pod_name_one: pod
|
||||
k8s_pod_namespace: "{{ template_namespace }}"
|
||||
register: r
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
|
||||
- name: Check if definition and template are mutually exclusive
|
||||
assert:
|
||||
@@ -52,7 +52,7 @@
|
||||
k8s_pod_name_one: pod
|
||||
k8s_pod_namespace: "{{ template_namespace }}"
|
||||
register: r
|
||||
ignore_errors: yes
|
||||
ignore_errors: true
|
||||
|
||||
- name: Check if src and template are mutually exclusive
|
||||
assert:
|
||||
@@ -63,7 +63,7 @@
|
||||
- name: Create pod using template (direct specification)
|
||||
kubernetes.core.k8s:
|
||||
template: "pod_one.j2"
|
||||
wait: yes
|
||||
wait: true
|
||||
wait_timeout: "{{ k8s_wait_timeout | default(omit) }}"
|
||||
vars:
|
||||
k8s_pod_name_one: pod-1
|
||||
@@ -79,7 +79,7 @@
|
||||
kubernetes.core.k8s:
|
||||
template:
|
||||
- default
|
||||
wait: yes
|
||||
wait: true
|
||||
wait_timeout: "{{ k8s_wait_timeout | default(omit) }}"
|
||||
vars:
|
||||
k8s_pod_name_one: pod-2
|
||||
@@ -96,7 +96,7 @@
|
||||
kubernetes.core.k8s:
|
||||
template:
|
||||
path: "pod_one.j2"
|
||||
wait: yes
|
||||
wait: true
|
||||
wait_timeout: "{{ k8s_wait_timeout | default(omit) }}"
|
||||
vars:
|
||||
k8s_pod_name_one: pod-3
|
||||
@@ -114,12 +114,11 @@
|
||||
path: "pod_two.j2"
|
||||
variable_start_string: '[['
|
||||
variable_end_string: ']]'
|
||||
wait: yes
|
||||
wait: true
|
||||
wait_timeout: "{{ k8s_wait_timeout | default(omit) }}"
|
||||
vars:
|
||||
k8s_pod_name_two: pod-4
|
||||
k8s_pod_namespace: "[[ template_namespace ]]"
|
||||
ansible_python_interpreter: "[[ ansible_playbook_python ]]"
|
||||
k8s_pod_namespace: "template-test"
|
||||
register: r
|
||||
|
||||
- name: Assert that pod creation succeeded using template
|
||||
@@ -131,7 +130,7 @@
|
||||
kubernetes.core.k8s:
|
||||
template:
|
||||
path: "pod_three.j2"
|
||||
wait: yes
|
||||
wait: true
|
||||
wait_timeout: "{{ k8s_wait_timeout | default(omit) }}"
|
||||
vars:
|
||||
k8s_pod_name_three_one: pod-5
|
||||
@@ -152,7 +151,7 @@
|
||||
variable_start_string: '[['
|
||||
variable_end_string: ']]'
|
||||
- path: "pod_three.j2"
|
||||
wait: yes
|
||||
wait: true
|
||||
wait_timeout: "{{ k8s_wait_timeout | default(omit) }}"
|
||||
vars:
|
||||
k8s_pod_name_one: pod-7
|
||||
@@ -213,8 +212,8 @@
|
||||
- name: check that resources creation failed
|
||||
assert:
|
||||
that:
|
||||
- resource.results.0.resources | length == 0
|
||||
- resource.results.1.resources | length == 0
|
||||
- '{{ resource.results[0].resources | length == 0 }}'
|
||||
- '{{ resource.results[1].resources | length == 0 }}'
|
||||
|
||||
- name: create pod without namespace (continue_on_error = true)
|
||||
kubernetes.core.k8s:
|
||||
@@ -239,63 +238,6 @@
|
||||
- resource.result.results | selectattr('changed') | list | length == 1
|
||||
- resource.result.results | selectattr('error', 'defined') | list | length == 1
|
||||
|
||||
# Test resource definition using template with 'omit'
|
||||
- name: Deploy configmap using template
|
||||
k8s:
|
||||
namespace: "{{ template_namespace }}"
|
||||
name: test-data
|
||||
template: configmap.yml.j2
|
||||
|
||||
- name: Read configmap created
|
||||
k8s_info:
|
||||
kind: configmap
|
||||
namespace: "{{ template_namespace }}"
|
||||
name: test-data
|
||||
register: _configmap
|
||||
|
||||
- name: Validate that the configmap does not contains annotations
|
||||
assert:
|
||||
that:
|
||||
- '"annotations" not in _configmap.resources.0.metadata'
|
||||
|
||||
- name: Create resource once again
|
||||
k8s:
|
||||
namespace: "{{ template_namespace }}"
|
||||
name: test-data
|
||||
template: configmap.yml.j2
|
||||
register: _configmap
|
||||
|
||||
- name: assert that nothing changed
|
||||
assert:
|
||||
that:
|
||||
- _configmap is not changed
|
||||
|
||||
- name: Create resource once again (using description)
|
||||
k8s:
|
||||
namespace: "{{ template_namespace }}"
|
||||
name: test-data
|
||||
template: configmap.yml.j2
|
||||
register: _configmap
|
||||
vars:
|
||||
k8s_configmap_desc: "This is a simple configmap used to test ansible k8s collection"
|
||||
|
||||
- name: assert that configmap was changed
|
||||
assert:
|
||||
that:
|
||||
- _configmap is changed
|
||||
|
||||
- name: Read configmap created
|
||||
k8s_info:
|
||||
kind: configmap
|
||||
namespace: "{{ template_namespace }}"
|
||||
name: test-data
|
||||
register: _configmap
|
||||
|
||||
- name: Validate that the configmap does not contains annotations
|
||||
assert:
|
||||
that:
|
||||
- _configmap.resources.0.metadata.annotations.description == "This is a simple configmap used to test ansible k8s collection"
|
||||
|
||||
always:
|
||||
- name: Remove namespace (Cleanup)
|
||||
kubernetes.core.k8s:
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
annotations:
|
||||
description: "{{ k8s_configmap_desc | default(omit) }}"
|
||||
data:
|
||||
key: "testing-template"
|
||||
@@ -5,6 +5,7 @@ k8s_pod_metadata:
|
||||
|
||||
k8s_pod_spec:
|
||||
serviceAccount: "{{ k8s_pod_service_account }}"
|
||||
nodeSelector: "{{ k8s_pod_node_selector }}"
|
||||
containers:
|
||||
- image: "{{ k8s_pod_image }}"
|
||||
imagePullPolicy: Always
|
||||
@@ -33,6 +34,8 @@ k8s_pod_ports: []
|
||||
|
||||
k8s_pod_env: []
|
||||
|
||||
k8s_pod_node_selector: {}
|
||||
|
||||
k8s_pod_template:
|
||||
metadata: "{{ k8s_pod_metadata }}"
|
||||
spec: "{{ k8s_pod_spec }}"
|
||||
|
||||
@@ -127,6 +127,48 @@
|
||||
- ds.result.status.currentNumberScheduled == ds.result.status.desiredNumberScheduled
|
||||
- updated_ds_pods.resources[0].spec.containers[0].image.endswith(":3")
|
||||
|
||||
- name: Create daemonset with nodeSelector and not existing label
|
||||
k8s:
|
||||
definition:
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: wait-daemonset-not-existing-label
|
||||
namespace: "{{ wait_namespace }}"
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: "{{ k8s_pod_name }}"
|
||||
template: "{{ k8s_pod_template }}"
|
||||
wait: yes
|
||||
wait_sleep: 5
|
||||
wait_timeout: "{{ k8s_wait_timeout | default(omit) }}"
|
||||
vars:
|
||||
k8s_pod_name: wait-daemonset-not-existing-label
|
||||
k8s_pod_image: gcr.io/kuar-demo/kuard-amd64:1
|
||||
k8s_pod_command:
|
||||
- sleep
|
||||
- "600"
|
||||
k8s_pod_node_selector:
|
||||
nonExisitingLabel: test-not-exiting-label
|
||||
register: ds_not_existing_label
|
||||
|
||||
- name: Get updated pods
|
||||
k8s_info:
|
||||
api_version: v1
|
||||
kind: Pod
|
||||
namespace: "{{ wait_namespace }}"
|
||||
label_selectors:
|
||||
- app=wait-daemonset-not-existing-label
|
||||
register: updated_ds_pods_not_existing_label
|
||||
|
||||
- name: Check that daemonset wait worked (when desired number is 0)
|
||||
assert:
|
||||
that:
|
||||
- ds_not_existing_label.result.status.currentNumberScheduled == ds_not_existing_label.result.status.desiredNumberScheduled
|
||||
- ds_not_existing_label.result.status.desiredNumberScheduled == 0
|
||||
- updated_ds_pods_not_existing_label.resources | length == 0
|
||||
|
||||
- name: Add a statefulset
|
||||
k8s:
|
||||
definition:
|
||||
|
||||
@@ -56,8 +56,8 @@
|
||||
# Without wantlist=True lookup should return mapping
|
||||
- test5 is mapping
|
||||
- test6 is mapping
|
||||
# errors='ignore'
|
||||
- test7 is string
|
||||
# errors='ignore' (return null with ansible-core 2.19)
|
||||
- test7 is string or not test7
|
||||
- test8 is not defined
|
||||
|
||||
- name: Create another namespace with label
|
||||
@@ -130,9 +130,9 @@
|
||||
assert:
|
||||
that:
|
||||
- result_configmap.apiVersion == 'v1'
|
||||
- result_configmap.metadata.name == configmap_name
|
||||
- result_configmap.metadata.namespace == test_namespace[2]
|
||||
- result_configmap.data.value == configmap_data
|
||||
- result_configmap.metadata.name == "{{ configmap_name }}"
|
||||
- result_configmap.metadata.namespace == "{{ test_namespace[2] }}"
|
||||
- result_configmap.data.value == "{{ configmap_data }}"
|
||||
|
||||
# test lookup plugin using src parameter
|
||||
- block:
|
||||
@@ -159,9 +159,9 @@
|
||||
assert:
|
||||
that:
|
||||
- src_configmap.apiVersion == 'v1'
|
||||
- src_configmap.metadata.name == configmap_name
|
||||
- src_configmap.metadata.namespace == test_namespace[2]
|
||||
- src_configmap.data.value == configmap_data
|
||||
- src_configmap.metadata.name == "{{ configmap_name }}"
|
||||
- src_configmap.metadata.namespace == "{{ test_namespace[2] }}"
|
||||
- src_configmap.data.value == "{{ configmap_data }}"
|
||||
|
||||
always:
|
||||
- name: Delete temporary file created
|
||||
@@ -198,9 +198,9 @@
|
||||
assert:
|
||||
that:
|
||||
- configmap_no_ssl.apiVersion == 'v1'
|
||||
- configmap_no_ssl.metadata.name == configmap_name
|
||||
- configmap_no_ssl.metadata.namespace == test_namespace[2]
|
||||
- configmap_no_ssl.data.value == configmap_data
|
||||
- configmap_no_ssl.metadata.name == "{{ configmap_name }}"
|
||||
- configmap_no_ssl.metadata.namespace == "{{ test_namespace[2] }}"
|
||||
- configmap_no_ssl.data.value == "{{ configmap_data }}"
|
||||
|
||||
- name: Retrieve configmap using authentication aliases (validate_certs=true)
|
||||
set_fact:
|
||||
@@ -210,9 +210,9 @@
|
||||
assert:
|
||||
that:
|
||||
- configmap_with_ssl.apiVersion == 'v1'
|
||||
- configmap_with_ssl.metadata.name == configmap_name
|
||||
- configmap_with_ssl.metadata.namespace == test_namespace[2]
|
||||
- configmap_with_ssl.data.value == configmap_data
|
||||
- configmap_with_ssl.metadata.name == "{{ configmap_name }}"
|
||||
- configmap_with_ssl.metadata.namespace == "{{ test_namespace[2] }}"
|
||||
- configmap_with_ssl.data.value == "{{ configmap_data }}"
|
||||
|
||||
always:
|
||||
- name: Delete temporary directory
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
- name: make script as executable
|
||||
file:
|
||||
path: "{{ tmp_dir_path }}/install_kustomize.sh"
|
||||
mode: 0755
|
||||
mode: '0755'
|
||||
|
||||
- name: Install kustomize
|
||||
command: "{{ tmp_dir_path }}/install_kustomize.sh"
|
||||
|
||||
1
tests/integration/targets/push_to_helm_registry/aliases
Normal file
1
tests/integration/targets/push_to_helm_registry/aliases
Normal file
@@ -0,0 +1 @@
|
||||
disabled
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
helm_binary_path: "helm"
|
||||
chart_repo_url: 'localhost:6035'
|
||||
chart_repo_username: testuser
|
||||
chart_repo_password: 'pass123!'
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
- name: Ensure we can log into the helm registry
|
||||
command: >-
|
||||
{{ helm_binary_path }} registry login
|
||||
-u {{ chart_repo_username }}
|
||||
-p {{ chart_repo_password }}
|
||||
{{ chart_repo_url }}
|
||||
|
||||
- name: Package chart and push to helm registry
|
||||
block:
|
||||
- name: Create temporary directory to store chart
|
||||
ansible.builtin.tempfile:
|
||||
state: directory
|
||||
suffix: .chart
|
||||
register: _tmpfile
|
||||
|
||||
- name: Package helm chart
|
||||
command: '{{ helm_binary_path }} package {{ chart_local_path }} --destination {{ _tmpfile.path }}'
|
||||
|
||||
- name: Locate helm chart package
|
||||
ansible.builtin.find:
|
||||
paths: "{{ _tmpfile.path }}"
|
||||
patterns: '*.tgz'
|
||||
register: _files
|
||||
|
||||
- name: Helm push chart to the registry
|
||||
command: '{{ helm_binary_path }} push {{ _files.files.0.path }} oci://{{ chart_repo_url }}/{{ chart_repo_path }}'
|
||||
|
||||
always:
|
||||
- name: Logout from registry
|
||||
command: '{{ helm_binary_path }} registry logout {{ chart_repo_url }}'
|
||||
ignore_errors: true
|
||||
|
||||
- name: Delete temporary directory
|
||||
ansible.builtin.file:
|
||||
state: absent
|
||||
path: '{{ _tmpfile.path }}'
|
||||
ignore_errors: true
|
||||
1
tests/integration/targets/setup_helm_registry/aliases
Normal file
1
tests/integration/targets/setup_helm_registry/aliases
Normal file
@@ -0,0 +1 @@
|
||||
disabled
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
# user: testuser, password: pass123!
|
||||
registry_credentials: testuser:$2y$05$d8tw6L1hojRFW.FjHOAnIOihJWAvFb0/Pu/30hLbQNJIYzCmlyBCi
|
||||
registry_name: helm_registry
|
||||
registry_port: 6035
|
||||
@@ -0,0 +1,3 @@
|
||||
---
|
||||
- name: Teardown registry
|
||||
include_tasks: teardown_registry.yml
|
||||
32
tests/integration/targets/setup_helm_registry/tasks/main.yml
Normal file
32
tests/integration/targets/setup_helm_registry/tasks/main.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
- name: Ensure we can talk to docker daemon
|
||||
ansible.builtin.shell:
|
||||
cmd: docker ps
|
||||
|
||||
- name: Create temporary directory to store file in
|
||||
tempfile:
|
||||
state: directory
|
||||
suffix: .helm_registry
|
||||
register: _tmpfile
|
||||
# notify:
|
||||
# - Teardown registry
|
||||
|
||||
- name: Create authentication file
|
||||
copy:
|
||||
content: "{{ registry_credentials }}"
|
||||
dest: "{{ _tmpfile.path }}/htpasswd"
|
||||
|
||||
- name: Remove existing registry
|
||||
ansible.builtin.include_tasks: remove_docker_container.yml
|
||||
|
||||
- name: Create registry container
|
||||
command: >-
|
||||
docker run -d
|
||||
-p {{ registry_port }}:5000
|
||||
--restart=always
|
||||
--name "{{ registry_name }}"
|
||||
-v "{{ _tmpfile.path }}:/auth"
|
||||
-e "REGISTRY_AUTH=htpasswd"
|
||||
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm"
|
||||
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd
|
||||
registry:2
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
- name: Inspect docker container
|
||||
command: docker container inspect {{ registry_name }} -f '{{ '{{' }} .State.Running {{ '}}' }}'
|
||||
register: _inspect
|
||||
ignore_errors: true
|
||||
|
||||
- name: Remove container
|
||||
when: _inspect.rc == 0
|
||||
block:
|
||||
- name: Stop running container
|
||||
command: docker container stop {{ registry_name }}
|
||||
when: _inspect.stdout == "true"
|
||||
|
||||
- name: Remove container
|
||||
command: docker container rm {{ registry_name }}
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
- name: Remove Docker container
|
||||
ansible.builtin.include_tasks: remove_docker_container.yml
|
||||
|
||||
- name: Delete temporary directory
|
||||
file:
|
||||
state: absent
|
||||
path: '{{ _tmpfile.path }}'
|
||||
ignore_errors: true
|
||||
@@ -4,10 +4,17 @@
|
||||
namespace_to_create: "{{ item.name | default(item) }}"
|
||||
namespace_labels: "{{ item.labels | default(omit) }}"
|
||||
with_items: "{{ test_namespace }}"
|
||||
when: test_namespace | type_debug == "list"
|
||||
when:
|
||||
- test_namespace is not string
|
||||
- test_namespace is not mapping
|
||||
- test_namespace is iterable
|
||||
|
||||
- include_tasks: tasks/create.yml
|
||||
vars:
|
||||
namespace_to_create: "{{ test_namespace }}"
|
||||
namespace_labels: "{{ test_namespace_labels | default(omit) }}"
|
||||
when: test_namespace | type_debug == "AnsibleUnicode"
|
||||
when:
|
||||
- test_namespace is string
|
||||
- test_namespace is iterable
|
||||
- test_namespace is sequence
|
||||
- test_namespace is not mapping
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
plugins/module_utils/client/discovery.py import-3.6!skip
|
||||
plugins/module_utils/client/discovery.py import-3.7!skip
|
||||
plugins/module_utils/client/discovery.py import-3.8!skip
|
||||
plugins/module_utils/client/discovery.py import-3.9!skip
|
||||
plugins/module_utils/client/discovery.py import-3.10!skip
|
||||
plugins/module_utils/client/discovery.py import-3.11!skip
|
||||
plugins/module_utils/client/resource.py import-3.6!skip
|
||||
plugins/module_utils/client/resource.py import-3.7!skip
|
||||
plugins/module_utils/client/resource.py import-3.8!skip
|
||||
plugins/module_utils/client/resource.py import-3.9!skip
|
||||
plugins/module_utils/client/resource.py import-3.10!skip
|
||||
plugins/module_utils/client/resource.py import-3.11!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.6!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.7!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.8!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.9!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.10!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.11!skip
|
||||
@@ -25,3 +34,4 @@ plugins/modules/k8s_service.py validate-modules:return-syntax-error
|
||||
plugins/modules/k8s_taint.py validate-modules:return-syntax-error
|
||||
tests/integration/targets/k8s_delete/files/deployments.yaml yamllint!skip
|
||||
tests/integration/targets/helm_diff/files/test-chart-reuse-values/templates/configmap.yaml yamllint!skip
|
||||
tests/integration/targets/helm_diff/files/test-chart-deployment-time/templates/configmap.yaml yamllint!skip
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
plugins/module_utils/client/discovery.py import-3.6!skip
|
||||
plugins/module_utils/client/discovery.py import-3.7!skip
|
||||
plugins/module_utils/client/discovery.py import-3.8!skip
|
||||
plugins/module_utils/client/discovery.py import-3.9!skip
|
||||
plugins/module_utils/client/discovery.py import-3.10!skip
|
||||
plugins/module_utils/client/discovery.py import-3.11!skip
|
||||
plugins/module_utils/client/resource.py import-3.6!skip
|
||||
plugins/module_utils/client/resource.py import-3.7!skip
|
||||
plugins/module_utils/client/resource.py import-3.8!skip
|
||||
plugins/module_utils/client/resource.py import-3.9!skip
|
||||
plugins/module_utils/client/resource.py import-3.10!skip
|
||||
plugins/module_utils/client/resource.py import-3.11!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.6!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.7!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.8!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.9!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.10!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.11!skip
|
||||
@@ -26,3 +35,4 @@ plugins/modules/k8s_scale.py validate-modules:return-syntax-error
|
||||
plugins/modules/k8s_service.py validate-modules:return-syntax-error
|
||||
plugins/modules/k8s_taint.py validate-modules:return-syntax-error
|
||||
tests/integration/targets/helm_diff/files/test-chart-reuse-values/templates/configmap.yaml yamllint!skip
|
||||
tests/integration/targets/helm_diff/files/test-chart-deployment-time/templates/configmap.yaml yamllint!skip
|
||||
|
||||
@@ -1,11 +1,20 @@
|
||||
plugins/module_utils/client/discovery.py import-3.6!skip
|
||||
plugins/module_utils/client/discovery.py import-3.7!skip
|
||||
plugins/module_utils/client/discovery.py import-3.8!skip
|
||||
plugins/module_utils/client/discovery.py import-3.9!skip
|
||||
plugins/module_utils/client/discovery.py import-3.10!skip
|
||||
plugins/module_utils/client/discovery.py import-3.11!skip
|
||||
plugins/module_utils/client/discovery.py import-3.12!skip
|
||||
plugins/module_utils/client/resource.py import-3.6!skip
|
||||
plugins/module_utils/client/resource.py import-3.7!skip
|
||||
plugins/module_utils/client/resource.py import-3.8!skip
|
||||
plugins/module_utils/client/resource.py import-3.9!skip
|
||||
plugins/module_utils/client/resource.py import-3.10!skip
|
||||
plugins/module_utils/client/resource.py import-3.11!skip
|
||||
plugins/module_utils/client/resource.py import-3.12!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.6!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.7!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.8!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.9!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.10!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.11!skip
|
||||
@@ -29,3 +38,4 @@ plugins/modules/k8s_scale.py validate-modules:return-syntax-error
|
||||
plugins/modules/k8s_service.py validate-modules:return-syntax-error
|
||||
plugins/modules/k8s_taint.py validate-modules:return-syntax-error
|
||||
tests/integration/targets/helm_diff/files/test-chart-reuse-values/templates/configmap.yaml yamllint!skip
|
||||
tests/integration/targets/helm_diff/files/test-chart-deployment-time/templates/configmap.yaml yamllint!skip
|
||||
|
||||
@@ -29,3 +29,4 @@ plugins/modules/k8s_scale.py validate-modules:return-syntax-error
|
||||
plugins/modules/k8s_service.py validate-modules:return-syntax-error
|
||||
plugins/modules/k8s_taint.py validate-modules:return-syntax-error
|
||||
tests/integration/targets/helm_diff/files/test-chart-reuse-values/templates/configmap.yaml yamllint!skip
|
||||
tests/integration/targets/helm_diff/files/test-chart-deployment-time/templates/configmap.yaml yamllint!skip
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
plugins/module_utils/client/discovery.py import-3.9!skip
|
||||
plugins/module_utils/client/discovery.py import-3.10!skip
|
||||
plugins/module_utils/client/discovery.py import-3.11!skip
|
||||
plugins/module_utils/client/discovery.py import-3.12!skip
|
||||
plugins/module_utils/client/resource.py import-3.9!skip
|
||||
plugins/module_utils/client/resource.py import-3.10!skip
|
||||
plugins/module_utils/client/discovery.py import-3.13!skip
|
||||
plugins/module_utils/client/resource.py import-3.11!skip
|
||||
plugins/module_utils/client/resource.py import-3.12!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.9!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.10!skip
|
||||
plugins/module_utils/client/resource.py import-3.13!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.11!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.12!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.13!skip
|
||||
plugins/module_utils/version.py pylint!skip
|
||||
plugins/modules/k8s.py validate-modules:parameter-type-not-in-doc
|
||||
plugins/modules/k8s_scale.py validate-modules:parameter-type-not-in-doc
|
||||
@@ -29,3 +26,4 @@ plugins/modules/k8s_scale.py validate-modules:return-syntax-error
|
||||
plugins/modules/k8s_service.py validate-modules:return-syntax-error
|
||||
plugins/modules/k8s_taint.py validate-modules:return-syntax-error
|
||||
tests/integration/targets/helm_diff/files/test-chart-reuse-values/templates/configmap.yaml yamllint!skip
|
||||
tests/integration/targets/helm_diff/files/test-chart-deployment-time/templates/configmap.yaml yamllint!skip
|
||||
|
||||
29
tests/sanity/ignore-2.19.txt
Normal file
29
tests/sanity/ignore-2.19.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
plugins/module_utils/client/discovery.py import-3.11!skip
|
||||
plugins/module_utils/client/discovery.py import-3.12!skip
|
||||
plugins/module_utils/client/discovery.py import-3.13!skip
|
||||
plugins/module_utils/client/resource.py import-3.11!skip
|
||||
plugins/module_utils/client/resource.py import-3.12!skip
|
||||
plugins/module_utils/client/resource.py import-3.13!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.11!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.12!skip
|
||||
plugins/module_utils/k8sdynamicclient.py import-3.13!skip
|
||||
plugins/module_utils/version.py pylint!skip
|
||||
plugins/modules/k8s.py validate-modules:parameter-type-not-in-doc
|
||||
plugins/modules/k8s_scale.py validate-modules:parameter-type-not-in-doc
|
||||
plugins/modules/k8s_service.py validate-modules:parameter-type-not-in-doc
|
||||
tests/unit/module_utils/fixtures/definitions.yml yamllint!skip
|
||||
tests/unit/module_utils/fixtures/deployments.yml yamllint!skip
|
||||
tests/integration/targets/k8s_delete/files/deployments.yaml yamllint!skip
|
||||
tests/unit/module_utils/fixtures/pods.yml yamllint!skip
|
||||
tests/integration/targets/helm/files/appversionless-chart-v2/templates/configmap.yaml yamllint!skip
|
||||
tests/integration/targets/helm/files/appversionless-chart/templates/configmap.yaml yamllint!skip
|
||||
tests/integration/targets/helm/files/test-chart-v2/templates/configmap.yaml yamllint!skip
|
||||
tests/integration/targets/helm/files/test-chart/templates/configmap.yaml yamllint!skip
|
||||
tests/integration/targets/helm_diff/files/test-chart/templates/configmap.yaml yamllint!skip
|
||||
tests/integration/targets/k8s_scale/files/deployment.yaml yamllint!skip
|
||||
plugins/modules/k8s.py validate-modules:return-syntax-error
|
||||
plugins/modules/k8s_scale.py validate-modules:return-syntax-error
|
||||
plugins/modules/k8s_service.py validate-modules:return-syntax-error
|
||||
plugins/modules/k8s_taint.py validate-modules:return-syntax-error
|
||||
tests/integration/targets/helm_diff/files/test-chart-reuse-values/templates/configmap.yaml yamllint!skip
|
||||
tests/integration/targets/helm_diff/files/test-chart-deployment-time/templates/configmap.yaml yamllint!skip
|
||||
@@ -1,105 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright: (c) 2022, 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
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from ansible_collections.kubernetes.core.plugins.action.k8s_info import RemoveOmit
|
||||
|
||||
|
||||
def get_omit_token():
|
||||
return "__omit_place_holder__%s" % datetime.now().strftime("%Y%m%d%H%M%S")
|
||||
|
||||
|
||||
def test_remove_omit_from_str():
|
||||
omit_token = get_omit_token()
|
||||
src = """
|
||||
project: ansible
|
||||
collection: {omit}
|
||||
""".format(
|
||||
omit=omit_token
|
||||
)
|
||||
result = RemoveOmit(src, omit_value=omit_token).output()
|
||||
assert len(result) == 1
|
||||
assert result[0] == dict(project="ansible")
|
||||
|
||||
|
||||
def test_remove_omit_from_list():
|
||||
omit_token = get_omit_token()
|
||||
src = """
|
||||
items:
|
||||
- {omit}
|
||||
""".format(
|
||||
omit=omit_token
|
||||
)
|
||||
result = RemoveOmit(src, omit_value=omit_token).output()
|
||||
assert len(result) == 1
|
||||
assert result[0] == dict(items=[])
|
||||
|
||||
|
||||
def test_remove_omit_from_list_of_dict():
|
||||
omit_token = get_omit_token()
|
||||
src = """
|
||||
items:
|
||||
- owner: ansible
|
||||
team: {omit}
|
||||
- simple_list_item
|
||||
""".format(
|
||||
omit=omit_token
|
||||
)
|
||||
result = RemoveOmit(src, omit_value=omit_token).output()
|
||||
assert len(result) == 1
|
||||
assert result[0] == dict(items=[dict(owner="ansible"), "simple_list_item"])
|
||||
|
||||
|
||||
def test_remove_omit_combined():
|
||||
omit_token = get_omit_token()
|
||||
src = """
|
||||
items:
|
||||
- {omit}
|
||||
- list_item_a
|
||||
- list_item_b
|
||||
parent:
|
||||
child:
|
||||
subchilda: {omit}
|
||||
subchildb:
|
||||
name: {omit}
|
||||
age: 3
|
||||
""".format(
|
||||
omit=omit_token
|
||||
)
|
||||
result = RemoveOmit(src, omit_value=omit_token).output()
|
||||
assert len(result) == 1
|
||||
assert result[0] == dict(
|
||||
items=["list_item_a", "list_item_b"],
|
||||
parent=dict(child=dict(subchildb=dict(age=3))),
|
||||
)
|
||||
|
||||
|
||||
def test_remove_omit_mutiple_documents():
|
||||
omit_token = get_omit_token()
|
||||
src = [
|
||||
"""
|
||||
project: ansible
|
||||
collection: {omit}
|
||||
""".format(
|
||||
omit=omit_token
|
||||
),
|
||||
"---",
|
||||
"""
|
||||
project: kubernetes
|
||||
environment: production
|
||||
collection: {omit}""".format(
|
||||
omit=omit_token
|
||||
),
|
||||
]
|
||||
src = "\n".join(src)
|
||||
print(src)
|
||||
result = RemoveOmit(src, omit_value=omit_token).output()
|
||||
assert len(result) == 2
|
||||
assert result[0] == dict(project="ansible")
|
||||
assert result[1] == dict(project="kubernetes", environment="production")
|
||||
@@ -44,8 +44,8 @@ def test_warn_on_k8s_version(monkeypatch, stdin, capfd):
|
||||
assert return_value.get("warnings") is not None
|
||||
warnings = return_value["warnings"]
|
||||
assert len(warnings) == 1
|
||||
assert "kubernetes" in warnings[0]
|
||||
assert MINIMAL_K8S_VERSION in warnings[0]
|
||||
assert "kubernetes" in str(warnings[0])
|
||||
assert MINIMAL_K8S_VERSION in str(warnings[0])
|
||||
|
||||
|
||||
dependencies = [
|
||||
|
||||
@@ -200,6 +200,10 @@ def test_module_get_values(_ansible_helm_module, no_values, get_all):
|
||||
'version.BuildInfo{Version:"v3.10.3", GitCommit:7870ab3ed4135f136eec, GoVersion:"go1.18.9"}',
|
||||
"3.10.3",
|
||||
),
|
||||
(
|
||||
'version.BuildInfo{Version:"v3.15.0-rc.1", GitCommit:"d7afa3b6b432c09a02cd07342e908ba5bed34940", GitTreeState:"clean", GoVersion:"go1.22.4"}',
|
||||
"3.15.0-rc.1",
|
||||
),
|
||||
('Client: &version.Version{SemVer:"v3.12.3", ', "3.12.3"),
|
||||
('Client: &version.Version{SemVer:"v3.12.3"', None),
|
||||
],
|
||||
|
||||
@@ -31,7 +31,7 @@ modified_def["metadata"]["labels"]["environment"] = "testing"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"action, params, existing, instance_warnings, expected",
|
||||
"action, params, existing, instance, expected",
|
||||
[
|
||||
(
|
||||
"delete",
|
||||
@@ -51,26 +51,14 @@ modified_def["metadata"]["labels"]["environment"] = "testing"
|
||||
"apply",
|
||||
{"apply": "yes"},
|
||||
{},
|
||||
(definition, []),
|
||||
definition,
|
||||
{"changed": True, "method": "apply", "result": definition},
|
||||
),
|
||||
(
|
||||
"apply",
|
||||
{"apply": "yes"},
|
||||
{},
|
||||
(definition, ["test warning"]),
|
||||
{
|
||||
"changed": True,
|
||||
"method": "apply",
|
||||
"result": definition,
|
||||
"warnings": ["test warning"],
|
||||
},
|
||||
),
|
||||
(
|
||||
"create",
|
||||
{"state": "patched"},
|
||||
{},
|
||||
({}, []),
|
||||
{},
|
||||
{
|
||||
"changed": False,
|
||||
"result": {},
|
||||
@@ -83,78 +71,42 @@ modified_def["metadata"]["labels"]["environment"] = "testing"
|
||||
"create",
|
||||
{},
|
||||
{},
|
||||
(definition, []),
|
||||
definition,
|
||||
{"changed": True, "method": "create", "result": definition},
|
||||
),
|
||||
(
|
||||
"create",
|
||||
{},
|
||||
{},
|
||||
(definition, ["test warning"]),
|
||||
{
|
||||
"changed": True,
|
||||
"method": "create",
|
||||
"result": definition,
|
||||
"warnings": ["test warning"],
|
||||
},
|
||||
),
|
||||
(
|
||||
"replace",
|
||||
{"force": "yes"},
|
||||
definition,
|
||||
(definition, []),
|
||||
definition,
|
||||
{"changed": False, "method": "replace", "result": definition},
|
||||
),
|
||||
(
|
||||
"replace",
|
||||
{"force": "yes"},
|
||||
definition,
|
||||
(modified_def, []),
|
||||
modified_def,
|
||||
{"changed": True, "method": "replace", "result": modified_def},
|
||||
),
|
||||
(
|
||||
"replace",
|
||||
{"force": "yes"},
|
||||
definition,
|
||||
(modified_def, ["test warning"]),
|
||||
{
|
||||
"changed": True,
|
||||
"method": "replace",
|
||||
"result": modified_def,
|
||||
"warnings": ["test warning"],
|
||||
},
|
||||
),
|
||||
(
|
||||
"update",
|
||||
{},
|
||||
definition,
|
||||
(definition, []),
|
||||
definition,
|
||||
{"changed": False, "method": "update", "result": definition},
|
||||
),
|
||||
(
|
||||
"update",
|
||||
{},
|
||||
definition,
|
||||
(modified_def, []),
|
||||
modified_def,
|
||||
{"changed": True, "method": "update", "result": modified_def},
|
||||
),
|
||||
(
|
||||
"update",
|
||||
{},
|
||||
definition,
|
||||
(modified_def, ["test warning"]),
|
||||
{
|
||||
"changed": True,
|
||||
"method": "update",
|
||||
"result": modified_def,
|
||||
"warnings": ["test warning"],
|
||||
},
|
||||
),
|
||||
(
|
||||
"create",
|
||||
{"label_selectors": ["app=foo"]},
|
||||
{},
|
||||
(definition, []),
|
||||
definition,
|
||||
{
|
||||
"changed": False,
|
||||
"msg": "resource 'kind=Pod,name=foo,namespace=foo' filtered by label_selectors.",
|
||||
@@ -164,18 +116,18 @@ modified_def["metadata"]["labels"]["environment"] = "testing"
|
||||
"create",
|
||||
{"label_selectors": ["app=nginx"]},
|
||||
{},
|
||||
(definition, []),
|
||||
definition,
|
||||
{"changed": True, "method": "create", "result": definition},
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_perform_action(action, params, existing, instance_warnings, expected):
|
||||
def test_perform_action(action, params, existing, instance, expected):
|
||||
svc = Mock()
|
||||
svc.find_resource.return_value = Mock(
|
||||
kind=definition["kind"], group_version=definition["apiVersion"]
|
||||
)
|
||||
svc.retrieve.return_value = ResourceInstance(None, existing) if existing else None
|
||||
spec = {action + ".return_value": instance_warnings}
|
||||
spec = {action + ".return_value": instance}
|
||||
svc.configure_mock(**spec)
|
||||
|
||||
result = perform_action(svc, definition, params)
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
from json import dumps
|
||||
from unittest.mock import Mock
|
||||
|
||||
import pytest
|
||||
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.service import (
|
||||
K8sService,
|
||||
diff_objects,
|
||||
parse_quoted_string,
|
||||
)
|
||||
from kubernetes.dynamic.exceptions import NotFoundError
|
||||
from kubernetes.dynamic.resource import Resource, ResourceInstance
|
||||
@@ -59,22 +57,6 @@ def mock_pod_updated_resource_instance():
|
||||
return ResourceInstance(None, pod_definition_updated)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def mock_pod_response():
|
||||
resp = Mock()
|
||||
resp.data.decode.return_value = dumps(pod_definition)
|
||||
resp.headers = {}
|
||||
return resp
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def mock_pod_warnings_response():
|
||||
resp = Mock()
|
||||
resp.data.decode.return_value = dumps(pod_definition)
|
||||
resp.headers = {"warning": '299 - "test warning 1", 299 - "test warning 2"'}
|
||||
return resp
|
||||
|
||||
|
||||
def test_diff_objects_no_diff():
|
||||
match, diff = diff_objects(pod_definition, pod_definition)
|
||||
|
||||
@@ -177,33 +159,16 @@ def test_service_delete_existing_resource_check_mode(mock_pod_resource_instance)
|
||||
client.delete.assert_not_called()
|
||||
|
||||
|
||||
def test_service_create_resource(mock_pod_response, mock_pod_resource_instance):
|
||||
spec = {"create.side_effect": [mock_pod_response]}
|
||||
def test_service_create_resource(mock_pod_resource_instance):
|
||||
spec = {"create.side_effect": [mock_pod_resource_instance]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
result, warnings = svc.create(Mock(), pod_definition)
|
||||
result = svc.create(Mock(), pod_definition)
|
||||
|
||||
assert result == mock_pod_resource_instance.to_dict()
|
||||
assert not warnings
|
||||
|
||||
|
||||
def test_service_create_resource_warnings(
|
||||
mock_pod_warnings_response, mock_pod_resource_instance
|
||||
):
|
||||
spec = {"create.side_effect": [mock_pod_warnings_response]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
result, warnings = svc.create(Mock(), pod_definition)
|
||||
|
||||
assert result == mock_pod_resource_instance.to_dict()
|
||||
assert warnings[0] == "test warning 1"
|
||||
assert warnings[1] == "test warning 2"
|
||||
|
||||
|
||||
def test_service_create_resource_check_mode():
|
||||
@@ -211,10 +176,9 @@ def test_service_create_resource_check_mode():
|
||||
client.create.return_value = mock_pod_resource_instance
|
||||
module = Mock(params={}, check_mode=True)
|
||||
svc = K8sService(client, module)
|
||||
result, warnings = svc.create(Mock(), pod_definition)
|
||||
result = svc.create(Mock(), pod_definition)
|
||||
|
||||
assert result == pod_definition
|
||||
assert not warnings
|
||||
client.create.assert_not_called()
|
||||
|
||||
|
||||
@@ -260,99 +224,40 @@ def test_create_project_request():
|
||||
assert results["result"] == project_definition
|
||||
|
||||
|
||||
def test_service_apply_existing_resource(mock_pod_response, mock_pod_resource_instance):
|
||||
spec = {"apply.side_effect": [mock_pod_response]}
|
||||
def test_service_apply_existing_resource(mock_pod_resource_instance):
|
||||
spec = {"apply.side_effect": [mock_pod_resource_instance]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {"apply": True}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
result, warnings = svc.apply(
|
||||
Mock(), pod_definition_updated, mock_pod_resource_instance
|
||||
)
|
||||
result = svc.apply(Mock(), pod_definition_updated, mock_pod_resource_instance)
|
||||
|
||||
assert result == mock_pod_resource_instance.to_dict()
|
||||
assert not warnings
|
||||
|
||||
|
||||
def test_service_apply_existing_resource_warnings(
|
||||
mock_pod_warnings_response, mock_pod_resource_instance
|
||||
):
|
||||
spec = {"apply.side_effect": [mock_pod_warnings_response]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {"apply": True}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
result, warnings = svc.apply(
|
||||
Mock(), pod_definition_updated, mock_pod_resource_instance
|
||||
)
|
||||
|
||||
assert result == mock_pod_resource_instance.to_dict()
|
||||
assert warnings[0] == "test warning 1"
|
||||
assert warnings[1] == "test warning 2"
|
||||
|
||||
|
||||
def test_service_replace_existing_resource(
|
||||
mock_pod_response, mock_pod_resource_instance
|
||||
):
|
||||
spec = {"replace.side_effect": [mock_pod_response]}
|
||||
def test_service_replace_existing_resource(mock_pod_resource_instance):
|
||||
spec = {"replace.side_effect": [mock_pod_resource_instance]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
result, warnings = svc.replace(Mock(), pod_definition, mock_pod_resource_instance)
|
||||
result = svc.replace(Mock(), pod_definition, mock_pod_resource_instance)
|
||||
|
||||
assert result == mock_pod_resource_instance.to_dict()
|
||||
assert not warnings
|
||||
|
||||
|
||||
def test_service_replace_existing_resource_warnings(
|
||||
mock_pod_warnings_response, mock_pod_resource_instance
|
||||
):
|
||||
spec = {"replace.side_effect": [mock_pod_warnings_response]}
|
||||
def test_service_update_existing_resource(mock_pod_resource_instance):
|
||||
spec = {"replace.side_effect": [mock_pod_resource_instance]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
result, warnings = svc.replace(Mock(), pod_definition, mock_pod_resource_instance)
|
||||
result = svc.replace(Mock(), pod_definition, mock_pod_resource_instance)
|
||||
|
||||
assert result == mock_pod_resource_instance.to_dict()
|
||||
assert warnings[0] == "test warning 1"
|
||||
assert warnings[1] == "test warning 2"
|
||||
|
||||
|
||||
def test_service_update_existing_resource(
|
||||
mock_pod_response, mock_pod_resource_instance
|
||||
):
|
||||
spec = {"replace.side_effect": [mock_pod_response]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
result, warnings = svc.replace(Mock(), pod_definition, mock_pod_resource_instance)
|
||||
|
||||
assert result == mock_pod_resource_instance.to_dict()
|
||||
assert not warnings
|
||||
|
||||
|
||||
def test_service_update_existing_resource_warnings(
|
||||
mock_pod_warnings_response, mock_pod_resource_instance
|
||||
):
|
||||
spec = {"replace.side_effect": [mock_pod_warnings_response]}
|
||||
client = Mock(**spec)
|
||||
module = Mock()
|
||||
module.params = {}
|
||||
module.check_mode = False
|
||||
svc = K8sService(client, module)
|
||||
result, warnings = svc.replace(Mock(), pod_definition, mock_pod_resource_instance)
|
||||
|
||||
assert result == mock_pod_resource_instance.to_dict()
|
||||
assert warnings[0] == "test warning 1"
|
||||
assert warnings[1] == "test warning 2"
|
||||
|
||||
|
||||
def test_service_find(mock_pod_resource_instance):
|
||||
@@ -383,24 +288,3 @@ def test_service_find_error():
|
||||
assert isinstance(results, dict)
|
||||
assert results["api_found"] is True
|
||||
assert results["resources"] == []
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"quoted_string,expected_val,expected_remainder",
|
||||
[
|
||||
(
|
||||
'"Response is stale" Tue, 15 Nov 1994 12:45:26 GMT',
|
||||
"Response is stale",
|
||||
"Tue, 15 Nov 1994 12:45:26 GMT",
|
||||
),
|
||||
(
|
||||
'"unknown field \\"spec.template.spec.disk\\""',
|
||||
'unknown field "spec.template.spec.disk"',
|
||||
"",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_parse_quoted_string(quoted_string, expected_val, expected_remainder):
|
||||
val, remainder = parse_quoted_string(quoted_string)
|
||||
assert val == expected_val
|
||||
assert remainder == expected_remainder
|
||||
|
||||
Reference in New Issue
Block a user