mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-05-11 20:12:18 +00:00
Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8538ffed3 | ||
|
|
bc168a5727 | ||
|
|
dc5a1e6dd1 | ||
|
|
72536fe286 | ||
|
|
f2d899b939 | ||
|
|
bc391218a4 | ||
|
|
83b3a1aa39 | ||
|
|
aa41055503 | ||
|
|
256fa58ca8 | ||
|
|
70db517265 | ||
|
|
a27c701afe | ||
|
|
a48a68ecfd | ||
|
|
db11675622 | ||
|
|
07ac24e42e | ||
|
|
63b84d7f54 | ||
|
|
b397439972 | ||
|
|
8bb455afb9 | ||
|
|
ddbc161121 | ||
|
|
1da4ef1d53 | ||
|
|
d78b64d792 | ||
|
|
e21ad0212d | ||
|
|
47d149f774 | ||
|
|
77775f25a7 | ||
|
|
688cff4ea8 | ||
|
|
a4701a6806 | ||
|
|
b875531c8a | ||
|
|
76a77aff1f | ||
|
|
25590804cb | ||
|
|
7fbfc985ab | ||
|
|
4b682666f1 | ||
|
|
abd2abb33e | ||
|
|
f5a81941ff | ||
|
|
fa819d3f11 | ||
|
|
f98469e5ef | ||
|
|
c330c7ec65 | ||
|
|
2f59c3db77 | ||
|
|
2076da7dc0 | ||
|
|
3c36b6fa0f | ||
|
|
e9be88f212 | ||
|
|
a0a6d7121f | ||
|
|
2e98493010 | ||
|
|
5fb3ecbb50 | ||
|
|
eab3aa29bf | ||
|
|
04f227e9b9 | ||
|
|
25100e7f5e | ||
|
|
ccc2b61719 | ||
|
|
8c7b302916 | ||
|
|
abcc3e884c | ||
|
|
15799b2dd5 | ||
|
|
35af8a48ad | ||
|
|
8280bb78c0 | ||
|
|
2eca446f09 | ||
|
|
cd72b6d7df | ||
|
|
b50f1f2fc9 | ||
|
|
2594ac654b | ||
|
|
c11a255026 | ||
|
|
46494a18bd | ||
|
|
4ccb15d4ad | ||
|
|
58dba6bf22 | ||
|
|
b7345696cc | ||
|
|
98cb88a701 |
140
.github/workflows/ci.yml
vendored
140
.github/workflows/ci.yml
vendored
@@ -1,140 +0,0 @@
|
|||||||
---
|
|
||||||
name: CI
|
|
||||||
'on':
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
pull_request:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 6 * * *'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
|
|
||||||
sanity:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
python_version: ['3.7']
|
|
||||||
ansible_version: ['stable-2.11', 'stable-2.10', 'stable-2.9', 'devel']
|
|
||||||
steps:
|
|
||||||
- name: Check out code
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
path: ansible_collections/kubernetes/core
|
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python_version }}
|
|
||||||
uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: ${{ matrix.python_version }}
|
|
||||||
|
|
||||||
- name: Check ansible version
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
repository: ansible/ansible
|
|
||||||
ref: ${{ matrix.ansible_version }}
|
|
||||||
path: ansible_collections/kubernetes/core/ansible
|
|
||||||
|
|
||||||
- name: Run sanity tests on Python ${{ matrix.python_version }}
|
|
||||||
run: source ./ansible/hacking/env-setup && make test-sanity PYTHON_VERSION=${{ matrix.python_version }}
|
|
||||||
working-directory: ./ansible_collections/kubernetes/core
|
|
||||||
|
|
||||||
integration:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
# Our old integration tests fail under newer Python versions.
|
|
||||||
python_version: ['3.6']
|
|
||||||
steps:
|
|
||||||
- name: Check out code
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
path: ansible_collections/kubernetes/core
|
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python_version }}
|
|
||||||
uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: ${{ matrix.python_version }}
|
|
||||||
|
|
||||||
- name: Install ansible base (devel branch)
|
|
||||||
run: pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
|
|
||||||
|
|
||||||
- name: Run integration tests on Python ${{ matrix.python_version }}
|
|
||||||
run: make test-integration PYTHON_VERSION=${{ matrix.python_version }}
|
|
||||||
working-directory: ./ansible_collections/kubernetes/core
|
|
||||||
|
|
||||||
- name: Generate coverage report.
|
|
||||||
run: ansible-test coverage xml -v --requirements --group-by command --group-by version
|
|
||||||
working-directory: ./ansible_collections/kubernetes/core
|
|
||||||
|
|
||||||
- uses: codecov/codecov-action@v1
|
|
||||||
with:
|
|
||||||
fail_ci_if_error: false
|
|
||||||
|
|
||||||
molecule:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
python_version: ['3.7']
|
|
||||||
steps:
|
|
||||||
- name: Check out code
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
path: ansible_collections/kubernetes/core
|
|
||||||
|
|
||||||
- name: Set up KinD cluster
|
|
||||||
uses: engineerd/setup-kind@v0.5.0
|
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python_version }}
|
|
||||||
uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: ${{ matrix.python_version }}
|
|
||||||
|
|
||||||
# The 3.3.0 release of molecule introduced a breaking change. See
|
|
||||||
# https://github.com/ansible-community/molecule/issues/3083
|
|
||||||
- name: Install molecule and kubernetes dependencies
|
|
||||||
run: pip install ansible "molecule<3.3.0" yamllint kubernetes flake8 jsonpatch
|
|
||||||
|
|
||||||
# The latest release doesn't work with Molecule currently.
|
|
||||||
# See: https://github.com/ansible-community/molecule/issues/2757
|
|
||||||
# - name: Install ansible base, latest release.
|
|
||||||
# run: |
|
|
||||||
# pip uninstall -y ansible
|
|
||||||
# pip install --pre ansible-base
|
|
||||||
|
|
||||||
# The devel branch doesn't work with Molecule currently.
|
|
||||||
# See: https://github.com/ansible-community/molecule/issues/2757
|
|
||||||
# - name: Install ansible base (devel branch)
|
|
||||||
# run: |
|
|
||||||
# pip uninstall -y ansible
|
|
||||||
# pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
|
|
||||||
- name: Create default collection path symlink
|
|
||||||
run: |
|
|
||||||
mkdir -p /home/runner/.ansible
|
|
||||||
ln -s /home/runner/work/kubernetes/kubernetes /home/runner/.ansible/collections
|
|
||||||
|
|
||||||
- name: Run molecule default test scenario
|
|
||||||
run: make test-molecule
|
|
||||||
working-directory: ./ansible_collections/kubernetes/core
|
|
||||||
|
|
||||||
unit:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
python_version: ['3.7']
|
|
||||||
steps:
|
|
||||||
- name: Check out code
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
with:
|
|
||||||
path: ansible_collections/kubernetes/core
|
|
||||||
|
|
||||||
- name: Set up Python ${{ matrix.python_version }}
|
|
||||||
uses: actions/setup-python@v1
|
|
||||||
with:
|
|
||||||
python-version: ${{ matrix.python_version }}
|
|
||||||
|
|
||||||
- name: Install ansible base (devel branch)
|
|
||||||
run: pip install https://github.com/ansible/ansible/archive/devel.tar.gz --disable-pip-version-check
|
|
||||||
|
|
||||||
- name: Run unit tests on Python ${{ matrix.python_version }}
|
|
||||||
run: make test-unit PYTHON_VERSION=${{ matrix.python_version }}
|
|
||||||
working-directory: ./ansible_collections/kubernetes/core
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -13,3 +13,6 @@ changelogs/.plugin-cache.yaml
|
|||||||
tests/output
|
tests/output
|
||||||
tests/integration/cloud-config-*
|
tests/integration/cloud-config-*
|
||||||
.cache
|
.cache
|
||||||
|
|
||||||
|
# Helm charts
|
||||||
|
molecule/default/*-chart-*.tgz
|
||||||
|
|||||||
@@ -16,3 +16,5 @@ rules:
|
|||||||
indent-sequences: consistent
|
indent-sequences: consistent
|
||||||
ignore: |
|
ignore: |
|
||||||
.cache
|
.cache
|
||||||
|
.tox
|
||||||
|
tests/output
|
||||||
|
|||||||
10
.zuul.d/network-ee-sanity-tests_non-voting.yaml
Normal file
10
.zuul.d/network-ee-sanity-tests_non-voting.yaml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
- project:
|
||||||
|
name: github.com/ansible-collections/kubernetes.core
|
||||||
|
check:
|
||||||
|
jobs:
|
||||||
|
- network-ee-sanity-tests:
|
||||||
|
voting: false
|
||||||
|
gate:
|
||||||
|
jobs:
|
||||||
|
- network-ee-sanity-tests:
|
||||||
|
voting: false
|
||||||
@@ -5,6 +5,97 @@ Kubernetes Collection Release Notes
|
|||||||
.. contents:: Topics
|
.. contents:: Topics
|
||||||
|
|
||||||
|
|
||||||
|
v2.2.2
|
||||||
|
======
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- remove binary file from k8s_cp test suite (https://github.com/ansible-collections/kubernetes.core/pull/298).
|
||||||
|
|
||||||
|
v2.2.1
|
||||||
|
======
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- common - Ensure the label_selectors parameter of _wait_for method is optional.
|
||||||
|
|
||||||
|
v2.2.0
|
||||||
|
======
|
||||||
|
|
||||||
|
Minor Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- add support for in-memory kubeconfig in addition to file for k8s modules. (https://github.com/ansible-collections/kubernetes.core/pull/212).
|
||||||
|
- helm - add support for history_max cli parameter (https://github.com/ansible-collections/kubernetes.core/pull/164).
|
||||||
|
- k8s - add support for label_selectors options (https://github.com/ansible-collections/kubernetes.core/issues/43).
|
||||||
|
- k8s - add support for waiting on statefulsets (https://github.com/ansible-collections/kubernetes.core/pull/195).
|
||||||
|
- k8s_log - Add since-seconds parameter to the k8s_log module (https://github.com/ansible-collections/kubernetes.core/pull/142).
|
||||||
|
- new lookup plugin to support kubernetes kustomize feature. (https://github.com/ansible-collections/kubernetes.core/issues/39).
|
||||||
|
- re-enable turbo mode for collection. The default is initially set to off (https://github.com/ansible-collections/kubernetes.core/pull/169).
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- common - import k8sdynamicclient directly to workaround Ansible upstream bug (https://github.com/ansible-collections/kubernetes.core/issues/162).
|
||||||
|
- connection plugin - add arguments information into censored command (https://github.com/ansible-collections/kubernetes.core/pull/196).
|
||||||
|
- fix resource cache not being used (https://github.com/ansible-collections/kubernetes.core/pull/228).
|
||||||
|
- k8s - Fixes a bug where diff was always returned when using apply or modifying an existing object, even when diff=no was specified. The module no longer returns diff unless requested and will now honor diff=no (https://github.com/ansible-collections/kubernetes.core/pull/146).
|
||||||
|
- k8s_cp - fix k8s_cp uploading when target container's WORKDIR is not '/' (https://github.com/ansible-collections/kubernetes.core/issues/222).
|
||||||
|
- k8s_exec - add missing deprecation notice to return_code for k8s_exec (https://github.com/ansible-collections/kubernetes.core/pull/233).
|
||||||
|
- k8s_exec - fix k8s_exec returning rc attribute, to follow ansible's common return values (https://github.com/ansible-collections/kubernetes.core/pull/230).
|
||||||
|
- lookup - recommend query instead of lookup (https://github.com/ansible-collections/kubernetes.core/issues/147).
|
||||||
|
- support the ``template`` param in all collections depending on kubernetes.core (https://github.com/ansible-collections/kubernetes.core/pull/154).
|
||||||
|
|
||||||
|
New Plugins
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Lookup
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
|
- kustomize - Build a set of kubernetes resources using a 'kustomization.yaml' file.
|
||||||
|
|
||||||
|
New Modules
|
||||||
|
-----------
|
||||||
|
|
||||||
|
- k8s_cp - Copy files and directories to and from pod.
|
||||||
|
- k8s_drain - Drain, Cordon, or Uncordon node in k8s cluster
|
||||||
|
|
||||||
|
v2.1.1
|
||||||
|
======
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- check auth params for existence, not whether they are true (https://github.com/ansible-collections/kubernetes.core/pull/151).
|
||||||
|
|
||||||
|
v2.1.0
|
||||||
|
======
|
||||||
|
|
||||||
|
Minor Changes
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- remove cloud.common as default dependency (https://github.com/ansible-collections/kubernetes.core/pull/148).
|
||||||
|
- temporarily disable turbo mode (https://github.com/ansible-collections/kubernetes.core/pull/149).
|
||||||
|
|
||||||
|
v2.0.2
|
||||||
|
======
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- Fix apply for k8s module when an array attribute from definition contains empty dict (https://github.com/ansible-collections/kubernetes.core/issues/113).
|
||||||
|
- rename the apply function to fix broken imports in Ansible 2.9 (https://github.com/ansible-collections/kubernetes.core/pull/135).
|
||||||
|
|
||||||
|
v2.0.1
|
||||||
|
======
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- inventory - add community.kubernetes to list of plugin choices in k8s inventory (https://github.com/ansible-collections/kubernetes.core/pull/128).
|
||||||
|
|
||||||
v2.0.0
|
v2.0.0
|
||||||
======
|
======
|
||||||
|
|
||||||
|
|||||||
4
Makefile
4
Makefile
@@ -1,8 +1,8 @@
|
|||||||
# Also needs to be updated in galaxy.yml
|
# Also needs to be updated in galaxy.yml
|
||||||
VERSION = 2.0.0
|
VERSION = 2.2.2
|
||||||
|
|
||||||
TEST_ARGS ?= ""
|
TEST_ARGS ?= ""
|
||||||
PYTHON_VERSION ?= `python -c 'import platform; print("{0}.{1}".format(platform.python_version_tuple()[0], platform.python_version_tuple()[1]))'`
|
PYTHON_VERSION ?= `python -c 'import platform; print(".".join(platform.python_version_tuple()[0:2]))'`
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f kubernetes-core-${VERSION}.tar.gz
|
rm -f kubernetes-core-${VERSION}.tar.gz
|
||||||
|
|||||||
22
README.md
22
README.md
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
[](https://github.com/ansible-collections/kubernetes.core/actions) [](https://codecov.io/gh/ansible-collections/kubernetes.core)
|
[](https://github.com/ansible-collections/kubernetes.core/actions) [](https://codecov.io/gh/ansible-collections/kubernetes.core)
|
||||||
|
|
||||||
This repo hosts the `kubernetes.core` (formerly known as `community.kubernetes`) Ansible Collection.
|
This repository hosts the `kubernetes.core` (formerly known as `community.kubernetes`) Ansible Collection.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
@@ -46,6 +46,7 @@ Name | Description
|
|||||||
Name | Description
|
Name | Description
|
||||||
--- | ---
|
--- | ---
|
||||||
[kubernetes.core.k8s](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_lookup.rst)|Query the K8s API
|
[kubernetes.core.k8s](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_lookup.rst)|Query the K8s API
|
||||||
|
[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
|
Name | Description
|
||||||
@@ -58,6 +59,8 @@ Name | Description
|
|||||||
[kubernetes.core.helm_template](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_template_module.rst)|Render chart templates
|
[kubernetes.core.helm_template](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.helm_template_module.rst)|Render chart templates
|
||||||
[kubernetes.core.k8s](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_module.rst)|Manage Kubernetes (K8s) objects
|
[kubernetes.core.k8s](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_module.rst)|Manage Kubernetes (K8s) objects
|
||||||
[kubernetes.core.k8s_cluster_info](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_cluster_info_module.rst)|Describe Kubernetes (K8s) cluster, APIs available and their respective versions
|
[kubernetes.core.k8s_cluster_info](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_cluster_info_module.rst)|Describe Kubernetes (K8s) cluster, APIs available and their respective versions
|
||||||
|
[kubernetes.core.k8s_cp](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_cp_module.rst)|Copy files and directories to and from pod.
|
||||||
|
[kubernetes.core.k8s_drain](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_drain_module.rst)|Drain, Cordon, or Uncordon node in k8s cluster
|
||||||
[kubernetes.core.k8s_exec](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_exec_module.rst)|Execute command in Pod
|
[kubernetes.core.k8s_exec](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_exec_module.rst)|Execute command in Pod
|
||||||
[kubernetes.core.k8s_info](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_info_module.rst)|Describe Kubernetes (K8s) objects
|
[kubernetes.core.k8s_info](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_info_module.rst)|Describe Kubernetes (K8s) objects
|
||||||
[kubernetes.core.k8s_json_patch](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_json_patch_module.rst)|Apply JSON patch operations to existing objects
|
[kubernetes.core.k8s_json_patch](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/kubernetes.core.k8s_json_patch_module.rst)|Apply JSON patch operations to existing objects
|
||||||
@@ -82,7 +85,7 @@ You can also include it in a `requirements.yml` file and install it via `ansible
|
|||||||
---
|
---
|
||||||
collections:
|
collections:
|
||||||
- name: kubernetes.core
|
- name: kubernetes.core
|
||||||
version: 2.0.0
|
version: 2.2.2
|
||||||
```
|
```
|
||||||
|
|
||||||
### Installing the Kubernetes Python Library
|
### Installing the Kubernetes Python Library
|
||||||
@@ -159,10 +162,21 @@ If upgrading older playbooks which were built prior to Ansible 2.10 and this col
|
|||||||
|
|
||||||
For documentation on how to use individual modules and other content included in this collection, please see the links in the 'Included content' section earlier in this README.
|
For documentation on how to use individual modules and other content included in this collection, please see the links in the 'Included content' section earlier in this README.
|
||||||
|
|
||||||
## Ansible Turbo mode
|
## Ansible Turbo mode Tech Preview
|
||||||
|
|
||||||
The ``kubernetes.core`` collection supports Ansible Turbo mode via ``cloud.common`` collection. Please read more about Ansible Turbo mode - [here](https://github.com/ansible-collections/kubernetes.core/blob/main/docs/ansible_turbo_mode.rst).
|
|
||||||
|
|
||||||
|
The ``kubernetes.core`` collection supports Ansible Turbo mode as a tech preview via the ``cloud.common`` collection. By default, this feature is disabled. To enable Turbo mode, set the environment variable `ENABLE_TURBO_MODE=1` on the managed node. For example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- hosts: remote
|
||||||
|
environment:
|
||||||
|
ENABLE_TURBO_MODE: 1
|
||||||
|
tasks:
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
## Testing and Development
|
||||||
|
|
||||||
|
|||||||
@@ -395,3 +395,109 @@ releases:
|
|||||||
name: k8s_json_patch
|
name: k8s_json_patch
|
||||||
namespace: ''
|
namespace: ''
|
||||||
release_date: '2021-06-09'
|
release_date: '2021-06-09'
|
||||||
|
2.0.1:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- inventory - add community.kubernetes to list of plugin choices in k8s inventory
|
||||||
|
(https://github.com/ansible-collections/kubernetes.core/pull/128).
|
||||||
|
fragments:
|
||||||
|
- 128-update-inventory-plugin-param.yaml
|
||||||
|
release_date: '2021-06-11'
|
||||||
|
2.0.2:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- Fix apply for k8s module when an array attribute from definition contains
|
||||||
|
empty dict (https://github.com/ansible-collections/kubernetes.core/issues/113).
|
||||||
|
- rename the apply function to fix broken imports in Ansible 2.9 (https://github.com/ansible-collections/kubernetes.core/pull/135).
|
||||||
|
fragments:
|
||||||
|
- 129-k8s-fix-apply-array-with-empty-dict.yml
|
||||||
|
- 135-rename-apply-function.yml
|
||||||
|
release_date: '2021-06-16'
|
||||||
|
2.1.0:
|
||||||
|
changes:
|
||||||
|
minor_changes:
|
||||||
|
- remove cloud.common as default dependency (https://github.com/ansible-collections/kubernetes.core/pull/148).
|
||||||
|
- temporarily disable turbo mode (https://github.com/ansible-collections/kubernetes.core/pull/149).
|
||||||
|
fragments:
|
||||||
|
- 148-remove-cloud-common-dependency.yaml
|
||||||
|
- 149-disable-turbo-mode.yaml
|
||||||
|
release_date: '2021-06-23'
|
||||||
|
2.1.1:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- check auth params for existence, not whether they are true (https://github.com/ansible-collections/kubernetes.core/pull/151).
|
||||||
|
fragments:
|
||||||
|
- 151-check-auth-params-for-existence.yaml
|
||||||
|
release_date: '2021-06-24'
|
||||||
|
2.2.0:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- common - import k8sdynamicclient directly to workaround Ansible upstream bug
|
||||||
|
(https://github.com/ansible-collections/kubernetes.core/issues/162).
|
||||||
|
- connection plugin - add arguments information into censored command (https://github.com/ansible-collections/kubernetes.core/pull/196).
|
||||||
|
- fix resource cache not being used (https://github.com/ansible-collections/kubernetes.core/pull/228).
|
||||||
|
- k8s - Fixes a bug where diff was always returned when using apply or modifying
|
||||||
|
an existing object, even when diff=no was specified. The module no longer
|
||||||
|
returns diff unless requested and will now honor diff=no (https://github.com/ansible-collections/kubernetes.core/pull/146).
|
||||||
|
- k8s_cp - fix k8s_cp uploading when target container's WORKDIR is not '/' (https://github.com/ansible-collections/kubernetes.core/issues/222).
|
||||||
|
- k8s_exec - add missing deprecation notice to return_code for k8s_exec (https://github.com/ansible-collections/kubernetes.core/pull/233).
|
||||||
|
- k8s_exec - fix k8s_exec returning rc attribute, to follow ansible's common
|
||||||
|
return values (https://github.com/ansible-collections/kubernetes.core/pull/230).
|
||||||
|
- lookup - recommend query instead of lookup (https://github.com/ansible-collections/kubernetes.core/issues/147).
|
||||||
|
- support the ``template`` param in all collections depending on kubernetes.core
|
||||||
|
(https://github.com/ansible-collections/kubernetes.core/pull/154).
|
||||||
|
minor_changes:
|
||||||
|
- add support for in-memory kubeconfig in addition to file for k8s modules.
|
||||||
|
(https://github.com/ansible-collections/kubernetes.core/pull/212).
|
||||||
|
- helm - add support for history_max cli parameter (https://github.com/ansible-collections/kubernetes.core/pull/164).
|
||||||
|
- k8s - add support for label_selectors options (https://github.com/ansible-collections/kubernetes.core/issues/43).
|
||||||
|
- k8s - add support for waiting on statefulsets (https://github.com/ansible-collections/kubernetes.core/pull/195).
|
||||||
|
- k8s_log - Add since-seconds parameter to the k8s_log module (https://github.com/ansible-collections/kubernetes.core/pull/142).
|
||||||
|
- new lookup plugin to support kubernetes kustomize feature. (https://github.com/ansible-collections/kubernetes.core/issues/39).
|
||||||
|
- re-enable turbo mode for collection. The default is initially set to off (https://github.com/ansible-collections/kubernetes.core/pull/169).
|
||||||
|
fragments:
|
||||||
|
- 142-add-sinceseconds-param-for-logs.yaml
|
||||||
|
- 146-k8s-add-support-diff-mode.yml
|
||||||
|
- 147_lookup.yml
|
||||||
|
- 154-template-param-support.yaml
|
||||||
|
- 158-k8s-add-support-label_selectors.yml
|
||||||
|
- 162_import_error.yml
|
||||||
|
- 164-add-history-max.yaml
|
||||||
|
- 169-reenable-turbo-mode.yaml
|
||||||
|
- 195-k8s-add-wait-statefulsets.yml
|
||||||
|
- 196_kubectl.yaml
|
||||||
|
- 212-in-memory-kubeconfig.yml
|
||||||
|
- 223-add-deprecation-notice.yaml
|
||||||
|
- 223-k8s-cp-uploading.yaml
|
||||||
|
- 225-kustomize-lookup-plugin.yml
|
||||||
|
- 228-fix-resource-cache.yml
|
||||||
|
- 230-k8sexec-has-new-returnvalue.yml
|
||||||
|
modules:
|
||||||
|
- description: Copy files and directories to and from pod.
|
||||||
|
name: k8s_cp
|
||||||
|
namespace: ''
|
||||||
|
- description: Drain, Cordon, or Uncordon node in k8s cluster
|
||||||
|
name: k8s_drain
|
||||||
|
namespace: ''
|
||||||
|
plugins:
|
||||||
|
lookup:
|
||||||
|
- description: Build a set of kubernetes resources using a 'kustomization.yaml'
|
||||||
|
file.
|
||||||
|
name: kustomize
|
||||||
|
namespace: null
|
||||||
|
release_date: '2021-09-15'
|
||||||
|
2.2.1:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- common - Ensure the label_selectors parameter of _wait_for method is optional.
|
||||||
|
fragments:
|
||||||
|
- 0-copy_ignore_txt.yml
|
||||||
|
- _wait_for_label_selector_optional.yaml
|
||||||
|
release_date: '2021-10-18'
|
||||||
|
2.2.2:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- remove binary file from k8s_cp test suite (https://github.com/ansible-collections/kubernetes.core/pull/298).
|
||||||
|
fragments:
|
||||||
|
- 298-remove-binary-file.yaml
|
||||||
|
release_date: '2021-12-07'
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Following document provides overview of Ansible Turbo mode in ``kubernetes.core`
|
|||||||
Synopsis
|
Synopsis
|
||||||
--------
|
--------
|
||||||
- A brief introduction about Ansible Turbo mode in ``kuberentes.core`` collection.
|
- A brief introduction about Ansible Turbo mode in ``kuberentes.core`` collection.
|
||||||
- Ansible Turbo mode is an optional performance optimization. It can be enabled by simply installing the cloud.common collection.
|
- Ansible Turbo mode is an optional performance optimization. It can be enabled by installing the cloud.common collection and setting the ``ENABLE_TURBO_MODE`` environment variable.
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
@@ -24,6 +24,15 @@ The following requirement is needed on the host that executes this module.
|
|||||||
|
|
||||||
- The ``cloud.common`` collection (https://github.com/ansible-collections/cloud.common)
|
- The ``cloud.common`` collection (https://github.com/ansible-collections/cloud.common)
|
||||||
|
|
||||||
|
You will also need to set the environment variable ``ENABLE_TURBO_MODE=1`` on the managed host. This can be done in the same ways you would usually do so, for example::
|
||||||
|
|
||||||
|
---
|
||||||
|
- hosts: remote
|
||||||
|
environment:
|
||||||
|
ENABLE_TURBO_MODE: 1
|
||||||
|
tasks:
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
@@ -90,7 +99,7 @@ The background service
|
|||||||
The daemon kills itself after 15s, and communication are done
|
The daemon kills itself after 15s, and communication are done
|
||||||
through an Unix socket.
|
through an Unix socket.
|
||||||
It runs in one single process and uses ``asyncio`` internally.
|
It runs in one single process and uses ``asyncio`` internally.
|
||||||
Consequently you can use the ``sync`` keyword in your Ansible module.
|
Consequently you can use the ``async`` keyword in your Ansible module.
|
||||||
This will be handy if you interact with a lot of remote systems
|
This will be handy if you interact with a lot of remote systems
|
||||||
at the same time.
|
at the same time.
|
||||||
|
|
||||||
|
|||||||
5
docs/docsite/extra-docs.yml
Normal file
5
docs/docsite/extra-docs.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
sections:
|
||||||
|
- title: Scenario Guide
|
||||||
|
toctree:
|
||||||
|
- scenario_guide
|
||||||
51
docs/docsite/rst/kubernetes_scenarios/k8s_intro.rst
Normal file
51
docs/docsite/rst/kubernetes_scenarios/k8s_intro.rst
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
.. _ansible_collections.kubernetes.core.docsite.k8s_ansible_intro:
|
||||||
|
|
||||||
|
**************************************
|
||||||
|
Introduction to Ansible for Kubernetes
|
||||||
|
**************************************
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
============
|
||||||
|
|
||||||
|
The `kubernetes.core collection <https://galaxy.ansible.com/kubernetes/core>`_ offers several modules and plugins for orchestrating Kubernetes.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
============
|
||||||
|
|
||||||
|
To use the modules, you'll need the following:
|
||||||
|
|
||||||
|
- Ansible 2.9.17 or latest installed
|
||||||
|
- `Kubernetes Python client <https://pypi.org/project/kubernetes/>`_ installed on the host that will execute the modules.
|
||||||
|
|
||||||
|
|
||||||
|
Installation
|
||||||
|
============
|
||||||
|
|
||||||
|
The Kubernetes modules are part of the Ansible Kubernetes collection.
|
||||||
|
|
||||||
|
To install the collection, run the following:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ ansible-galaxy collection install kubernetes.core
|
||||||
|
|
||||||
|
|
||||||
|
Authenticating with the API
|
||||||
|
===========================
|
||||||
|
|
||||||
|
By default the Kubernetes Rest Client will look for ``~/.kube/config``, and if found, connect using the active context. You can override the location of the file using the ``kubeconfig`` parameter, and the context, using the ``context`` parameter.
|
||||||
|
|
||||||
|
Basic authentication is also supported using the ``username`` and ``password`` options. You can override the URL using the ``host`` parameter. Certificate authentication works through the ``ssl_ca_cert``, ``cert_file``, and ``key_file`` parameters, and for token authentication, use the ``api_key`` parameter.
|
||||||
|
|
||||||
|
To disable SSL certificate verification, set ``verify_ssl`` to false.
|
||||||
|
|
||||||
|
Reporting an issue
|
||||||
|
==================
|
||||||
|
|
||||||
|
- If you find a bug or have a suggestion regarding modules or plugins, please file issues at `Ansible Kubernetes collection <https://github.com/ansible-collections/kubernetes.core/issues>`_.
|
||||||
|
- If you find a bug regarding Kubernetes Python client, please file issues at `Kubernetes Client issues <https://github.com/kubernetes-client/python/issues>`_.
|
||||||
|
- If you find a bug regarding Kubectl binary, please file issues at `Kubectl issue tracker <https://github.com/kubernetes/kubectl/issues>`_
|
||||||
|
- If you find a bug regarding Helm binary, please file issues at `Helm issue tracker <https://github.com/helm/helm/issues>`_.
|
||||||
88
docs/docsite/rst/kubernetes_scenarios/k8s_inventory.rst
Normal file
88
docs/docsite/rst/kubernetes_scenarios/k8s_inventory.rst
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
.. _ansible_collections.kubernetes.core.docsite.k8s_ansible_inventory:
|
||||||
|
|
||||||
|
*****************************************
|
||||||
|
Using Kubernetes dynamic inventory plugin
|
||||||
|
*****************************************
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
|
||||||
|
Kubernetes dynamic inventory plugin
|
||||||
|
===================================
|
||||||
|
|
||||||
|
|
||||||
|
The best way to interact with your Pods is to use the Kubernetes dynamic inventory plugin, which queries Kubernetes APIs using ``kubectl`` command line available on controller node and tells Ansible what Pods can be managed.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
|
||||||
|
To use the Kubernetes dynamic inventory plugins, you must install `Kubernetes Python client <https://github.com/kubernetes-client/python>`_, `kubectl <https://github.com/kubernetes/kubectl>`_ on your control node (the host running Ansible).
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ pip install kubernetes
|
||||||
|
|
||||||
|
Please refer to Kubernetes official documentation for `installing kubectl <https://kubernetes.io/docs/tasks/tools/install-kubectl/>`_ on the given operating systems.
|
||||||
|
|
||||||
|
To use this Kubernetes dynamic inventory plugin, you need to enable it first by specifying the following in the ``ansible.cfg`` file:
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[inventory]
|
||||||
|
enable_plugins = kubernetes.core.k8s
|
||||||
|
|
||||||
|
Then, create a file that ends in ``.k8s.yml`` or ``.k8s.yaml`` in your working directory.
|
||||||
|
|
||||||
|
The ``kubernetes.core.k8s`` inventory plugin takes in the same authentication information as any other Kubernetes modules.
|
||||||
|
|
||||||
|
Here's an example of a valid inventory file:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
plugin: kubernetes.core.k8s
|
||||||
|
|
||||||
|
Executing ``ansible-inventory --list -i <filename>.k8s.yml`` will create a list of Pods that are ready to be configured using Ansible.
|
||||||
|
|
||||||
|
You can also provide the namespace to gather information about specific pods from the given namespace. For example, to gather information about Pods under the ``test`` namespace you will specify the ``namespaces`` parameter:
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
plugin: kubernetes.core.k8s
|
||||||
|
connections:
|
||||||
|
- namespaces:
|
||||||
|
- test
|
||||||
|
|
||||||
|
Using vaulted configuration files
|
||||||
|
=================================
|
||||||
|
|
||||||
|
Since the inventory configuration file contains Kubernetes related sensitive information in plain text, a security risk, you may want to
|
||||||
|
encrypt your entire inventory configuration file.
|
||||||
|
|
||||||
|
You can encrypt a valid inventory configuration file as follows:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ ansible-vault encrypt <filename>.k8s.yml
|
||||||
|
New Vault password:
|
||||||
|
Confirm New Vault password:
|
||||||
|
Encryption successful
|
||||||
|
|
||||||
|
$ echo "MySuperSecretPassw0rd!" > /path/to/vault_password_file
|
||||||
|
|
||||||
|
And you can use this vaulted inventory configuration file using:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ ansible-inventory -i <filename>.k8s.yml --list --vault-password-file=/path/to/vault_password_file
|
||||||
|
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
|
||||||
|
`Kubernetes Python client - Issue Tracker <https://github.com/kubernetes-client/python/issues>`_
|
||||||
|
The issue tracker for Kubernetes Python client
|
||||||
|
`Kubectl installation <https://kubernetes.io/docs/tasks/tools/install-kubectl/>`_
|
||||||
|
Installation guide for installing Kubectl
|
||||||
|
:ref:`working_with_playbooks`
|
||||||
|
An introduction to playbooks
|
||||||
|
:ref:`playbooks_vault`
|
||||||
|
Using Vault in playbooks
|
||||||
12
docs/docsite/rst/kubernetes_scenarios/k8s_scenarios.rst
Normal file
12
docs/docsite/rst/kubernetes_scenarios/k8s_scenarios.rst
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
.. _ansible_collections.kubernetes.core.docsite.k8s_scenarios:
|
||||||
|
|
||||||
|
********************************
|
||||||
|
Ansible for Kubernetes Scenarios
|
||||||
|
********************************
|
||||||
|
|
||||||
|
These scenarios teach you how to accomplish common Kubernetes tasks using Ansible. To get started, please select the task you want to accomplish.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
scenario_k8s_object
|
||||||
175
docs/docsite/rst/kubernetes_scenarios/scenario_k8s_object.rst
Normal file
175
docs/docsite/rst/kubernetes_scenarios/scenario_k8s_object.rst
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
.. _ansible_collections.kubernetes.core.docsite.k8s_object_template:
|
||||||
|
|
||||||
|
*******************
|
||||||
|
Creating K8S object
|
||||||
|
*******************
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
============
|
||||||
|
|
||||||
|
This guide will show you how to utilize Ansible to create Kubernetes objects such as Pods, Deployments, and Secrets.
|
||||||
|
|
||||||
|
Scenario Requirements
|
||||||
|
=====================
|
||||||
|
|
||||||
|
* Software
|
||||||
|
|
||||||
|
* Ansible 2.9.17 or later must be installed
|
||||||
|
|
||||||
|
* The Python module ``kubernetes`` must be installed on the Ansible controller (or Target host if not executing against localhost)
|
||||||
|
|
||||||
|
* Kubernetes Cluster
|
||||||
|
|
||||||
|
* Kubectl binary installed on the Ansible controller
|
||||||
|
|
||||||
|
|
||||||
|
* Access / Credentials
|
||||||
|
|
||||||
|
* Kubeconfig configured with the given Kubernetes cluster
|
||||||
|
|
||||||
|
|
||||||
|
Assumptions
|
||||||
|
===========
|
||||||
|
|
||||||
|
- User has required level of authorization to create, delete and update resources on the given Kubernetes cluster.
|
||||||
|
|
||||||
|
Caveats
|
||||||
|
=======
|
||||||
|
|
||||||
|
- community.kubernetes 2.0.0 has been renamed to `kubernetes.core <https://github.com/ansible-collections/kubernetes.core>`_
|
||||||
|
|
||||||
|
Example Description
|
||||||
|
===================
|
||||||
|
|
||||||
|
In this use case / example, we will create a Pod in the given Kubernetes Cluster. The following Ansible playbook showcases the basic parameters that are needed for this.
|
||||||
|
|
||||||
|
.. code:: yaml
|
||||||
|
|
||||||
|
---
|
||||||
|
- hosts: localhost
|
||||||
|
collections:
|
||||||
|
- kubernetes.core
|
||||||
|
tasks:
|
||||||
|
- name: Create a pod
|
||||||
|
k8s:
|
||||||
|
state: present
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: "utilitypod-1"
|
||||||
|
namespace: default
|
||||||
|
labels:
|
||||||
|
app: galaxy
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: utilitypod
|
||||||
|
image: busybox
|
||||||
|
|
||||||
|
Since Ansible utilizes the Kubernetes API to perform actions, in this use case we will be connecting directly to the Kubernetes cluster.
|
||||||
|
|
||||||
|
To begin, there are a few bits of information we will need. Here you are using Kubeconfig which is pre-configured in your machine. The Kubeconfig is generally located at ``~/.kube/config``. It is highly recommended to store sensitive information such as password, user certificates in a more secure fashion using :ref:`ansible-vault` or using `Ansible Tower credentials <https://docs.ansible.com/ansible-tower/latest/html/userguide/credentials.html>`_.
|
||||||
|
|
||||||
|
Now you need to supply the information about the Pod which will be created. Using ``definition`` parameter of the ``kubernetes.core.k8s`` module, you specify `PodTemplate <https://kubernetes.io/docs/concepts/workloads/pods/#pod-templates>`_. This PodTemplate is identical to what you provide to the ``kubectl`` command.
|
||||||
|
|
||||||
|
What to expect
|
||||||
|
--------------
|
||||||
|
|
||||||
|
- You will see a bit of JSON output after this playbook completes. This output shows various parameters that are returned from the module and from cluster about the newly created Pod.
|
||||||
|
|
||||||
|
.. code:: json
|
||||||
|
|
||||||
|
{
|
||||||
|
"changed": true,
|
||||||
|
"method": "create",
|
||||||
|
"result": {
|
||||||
|
"apiVersion": "v1",
|
||||||
|
"kind": "Pod",
|
||||||
|
"metadata": {
|
||||||
|
"creationTimestamp": "2020-10-03T15:36:25Z",
|
||||||
|
"labels": {
|
||||||
|
"app": "galaxy"
|
||||||
|
},
|
||||||
|
"name": "utilitypod-1",
|
||||||
|
"namespace": "default",
|
||||||
|
"resourceVersion": "4511073",
|
||||||
|
"selfLink": "/api/v1/namespaces/default/pods/utilitypod-1",
|
||||||
|
"uid": "c7dec819-09df-4efd-9d78-67cf010b4f4e"
|
||||||
|
},
|
||||||
|
"spec": {
|
||||||
|
"containers": [{
|
||||||
|
"image": "busybox",
|
||||||
|
"imagePullPolicy": "Always",
|
||||||
|
"name": "utilitypod",
|
||||||
|
"resources": {},
|
||||||
|
"terminationMessagePath": "/dev/termination-log",
|
||||||
|
"terminationMessagePolicy": "File",
|
||||||
|
"volumeMounts": [{
|
||||||
|
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
|
||||||
|
"name": "default-token-6j842",
|
||||||
|
"readOnly": true
|
||||||
|
}]
|
||||||
|
}],
|
||||||
|
"dnsPolicy": "ClusterFirst",
|
||||||
|
"enableServiceLinks": true,
|
||||||
|
"priority": 0,
|
||||||
|
"restartPolicy": "Always",
|
||||||
|
"schedulerName": "default-scheduler",
|
||||||
|
"securityContext": {},
|
||||||
|
"serviceAccount": "default",
|
||||||
|
"serviceAccountName": "default",
|
||||||
|
"terminationGracePeriodSeconds": 30,
|
||||||
|
"tolerations": [{
|
||||||
|
"effect": "NoExecute",
|
||||||
|
"key": "node.kubernetes.io/not-ready",
|
||||||
|
"operator": "Exists",
|
||||||
|
"tolerationSeconds": 300
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"effect": "NoExecute",
|
||||||
|
"key": "node.kubernetes.io/unreachable",
|
||||||
|
"operator": "Exists",
|
||||||
|
"tolerationSeconds": 300
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"volumes": [{
|
||||||
|
"name": "default-token-6j842",
|
||||||
|
"secret": {
|
||||||
|
"defaultMode": 420,
|
||||||
|
"secretName": "default-token-6j842"
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"phase": "Pending",
|
||||||
|
"qosClass": "BestEffort"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- In the above example, 'changed' is ``True`` which notifies that the Pod creation started on the given cluster. This can take some time depending on your environment.
|
||||||
|
|
||||||
|
|
||||||
|
Troubleshooting
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Things to inspect
|
||||||
|
|
||||||
|
- Check if the values provided for username and password are correct
|
||||||
|
- Check if the Kubeconfig is populated with correct values
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
|
||||||
|
`Kubernetes Python client <https://github.com/kubernetes-client/python>`_
|
||||||
|
The GitHub Page of Kubernetes Python client
|
||||||
|
`Kubernetes Python client - Issue Tracker <https://github.com/kubernetes-client/python/issues>`_
|
||||||
|
The issue tracker for Kubernetes Python client
|
||||||
|
`Kubectl installation <https://kubernetes.io/docs/tasks/tools/install-kubectl/>`_
|
||||||
|
Installation guide for installing Kubectl
|
||||||
|
:ref:`working_with_playbooks`
|
||||||
|
An introduction to playbooks
|
||||||
|
:ref:`playbooks_vault`
|
||||||
|
Using Vault in playbooks
|
||||||
18
docs/docsite/rst/scenario_guide.rst
Normal file
18
docs/docsite/rst/scenario_guide.rst
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
.. _ansible_collections.kubernetes.core.docsite.scenario_guide:
|
||||||
|
|
||||||
|
Kubernetes Guide
|
||||||
|
================
|
||||||
|
|
||||||
|
Welcome to the Ansible for Kubernetes Guide!
|
||||||
|
|
||||||
|
The purpose of this guide is to teach you everything you need to know about using Ansible with Kubernetes.
|
||||||
|
|
||||||
|
To get started, please select one of the following topics.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
kubernetes_scenarios/k8s_intro
|
||||||
|
kubernetes_scenarios/k8s_inventory
|
||||||
|
kubernetes_scenarios/k8s_scenarios
|
||||||
|
|
||||||
@@ -231,6 +231,23 @@ Parameters
|
|||||||
<div>Helm option to force reinstall, ignore on new install.</div>
|
<div>Helm option to force reinstall, ignore on new install.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>history_max</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">integer</span>
|
||||||
|
</div>
|
||||||
|
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.2.0</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Limit the maximum number of revisions saved per release.</div>
|
||||||
|
<div>mutually exclusive with with <code>replace</code>.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="1">
|
<td colspan="1">
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
@@ -373,6 +390,7 @@ Parameters
|
|||||||
<td>
|
<td>
|
||||||
<div>Reuse the given name, only if that name is a deleted release which remains in the history.</div>
|
<div>Reuse the given name, only if that name is a deleted release which remains in the history.</div>
|
||||||
<div>This is unsafe in production environment.</div>
|
<div>This is unsafe in production environment.</div>
|
||||||
|
<div>mutually exclusive with with <code>history_max</code>.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -161,13 +161,14 @@ Parameters
|
|||||||
<b>kubeconfig</b>
|
<b>kubeconfig</b>
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
<div style="font-size: small">
|
<div style="font-size: small">
|
||||||
<span style="color: purple">path</span>
|
<span style="color: purple">raw</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
||||||
|
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version >= 17.17.0. Added in version 2.2.0.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
554
docs/kubernetes.core.k8s_cp_module.rst
Normal file
554
docs/kubernetes.core.k8s_cp_module.rst
Normal file
@@ -0,0 +1,554 @@
|
|||||||
|
.. _kubernetes.core.k8s_cp_module:
|
||||||
|
|
||||||
|
|
||||||
|
**********************
|
||||||
|
kubernetes.core.k8s_cp
|
||||||
|
**********************
|
||||||
|
|
||||||
|
**Copy files and directories to and from pod.**
|
||||||
|
|
||||||
|
|
||||||
|
Version added: 2.2.0
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
:depth: 1
|
||||||
|
|
||||||
|
|
||||||
|
Synopsis
|
||||||
|
--------
|
||||||
|
- Use the Kubernetes Python client to copy files and directories to and from containers inside a pod.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
The below requirements are needed on the host that executes this module.
|
||||||
|
|
||||||
|
- python >= 3.6
|
||||||
|
- kubernetes >= 12.0.0
|
||||||
|
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
|
||||||
|
<table border=0 cellpadding=0 class="documentation-table">
|
||||||
|
<tr>
|
||||||
|
<th colspan="2">Parameter</th>
|
||||||
|
<th>Choices/<font color="blue">Defaults</font></th>
|
||||||
|
<th width="100%">Comments</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>api_key</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Token used to authenticate with the API. Can also be specified via K8S_AUTH_API_KEY environment variable.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>ca_cert</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">path</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Path to a CA certificate used to authenticate with the API. The full certificate chain must be provided to avoid certificate validation errors. Can also be specified via K8S_AUTH_SSL_CA_CERT environment variable.</div>
|
||||||
|
<div style="font-size: small; color: darkgreen"><br/>aliases: ssl_ca_cert</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>client_cert</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">path</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Path to a certificate used to authenticate with the API. Can also be specified via K8S_AUTH_CERT_FILE environment variable.</div>
|
||||||
|
<div style="font-size: small; color: darkgreen"><br/>aliases: cert_file</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>client_key</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">path</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Path to a key file used to authenticate with the API. Can also be specified via K8S_AUTH_KEY_FILE environment variable.</div>
|
||||||
|
<div style="font-size: small; color: darkgreen"><br/>aliases: key_file</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>container</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>The name of the container in the pod to copy files/directories from/to.</div>
|
||||||
|
<div>Defaults to the only container if there is only one container in the pod.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>content</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>When used instead of <em>local_path</em>, sets the contents of a local file directly to the specified value.</div>
|
||||||
|
<div>Works only when <em>remote_path</em> is a file. Creates the file if it does not exist.</div>
|
||||||
|
<div>For advanced formatting or if the content contains a variable, use the <span class='module'>ansible.builtin.template</span> module.</div>
|
||||||
|
<div>Mutually exclusive with <em>local_path</em>.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>context</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>The name of a context found in the config file. Can also be specified via K8S_AUTH_CONTEXT environment variable.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>host</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Provide a URL for accessing the API. Can also be specified via K8S_AUTH_HOST environment variable.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>kubeconfig</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">raw</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
||||||
|
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version >= 17.17.0. Added in version 2.2.0.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>local_path</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">path</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Path of the local file or directory.</div>
|
||||||
|
<div>Required when <em>state</em> is set to <code>from_pod</code>.</div>
|
||||||
|
<div>Mutually exclusive with <em>content</em>.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>namespace</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
/ <span style="color: red">required</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>The pod namespace name.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>no_preserve</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">boolean</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||||
|
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||||
|
<li>yes</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>The copied file/directory's ownership and permissions will not be preserved in the container.</div>
|
||||||
|
<div>This option is ignored when <em>content</em> is set or when <em>state</em> is set to <code>from_pod</code>.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>password</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Provide a password for authenticating with the API. Can also be specified via K8S_AUTH_PASSWORD environment variable.</div>
|
||||||
|
<div>Please read the description of the <code>username</code> option for a discussion of when this option is applicable.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>persist_config</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">boolean</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||||
|
<li>no</li>
|
||||||
|
<li>yes</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Whether or not to save the kube config refresh tokens. Can also be specified via K8S_AUTH_PERSIST_CONFIG environment variable.</div>
|
||||||
|
<div>When the k8s context is using a user credentials with refresh tokens (like oidc or gke/gcloud auth), the token is refreshed by the k8s python client library but not saved by default. So the old refresh token can expire and the next auth might fail. Setting this flag to true will tell the k8s python client to save the new refresh token to the kube config file.</div>
|
||||||
|
<div>Default to false.</div>
|
||||||
|
<div>Please note that the current version of the k8s python client library does not support setting this flag to True yet.</div>
|
||||||
|
<div>The fix for this k8s python library is here: https://github.com/kubernetes-client/python-base/pull/169</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>pod</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
/ <span style="color: red">required</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>The pod name.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>proxy</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>The URL of an HTTP proxy to use for the connection. Can also be specified via K8S_AUTH_PROXY environment variable.</div>
|
||||||
|
<div>Please note that this module does not pick up typical proxy settings from the environment (e.g. HTTP_PROXY).</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>proxy_headers</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">dictionary</span>
|
||||||
|
</div>
|
||||||
|
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.0.0</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>The Header used for the HTTP proxy.</div>
|
||||||
|
<div>Documentation can be found here <a href='https://urllib3.readthedocs.io/en/latest/reference/urllib3.util.html?highlight=proxy_headers#urllib3.util.make_headers'>https://urllib3.readthedocs.io/en/latest/reference/urllib3.util.html?highlight=proxy_headers#urllib3.util.make_headers</a>.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>basic_auth</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Colon-separated username:password for basic authentication header.</div>
|
||||||
|
<div>Can also be specified via K8S_AUTH_PROXY_HEADERS_BASIC_AUTH environment.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>proxy_basic_auth</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Colon-separated username:password for proxy basic authentication header.</div>
|
||||||
|
<div>Can also be specified via K8S_AUTH_PROXY_HEADERS_PROXY_BASIC_AUTH environment.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>user_agent</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>String representing the user-agent you want, such as foo/1.0.</div>
|
||||||
|
<div>Can also be specified via K8S_AUTH_PROXY_HEADERS_USER_AGENT environment.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>remote_path</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">path</span>
|
||||||
|
/ <span style="color: red">required</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Path of the file or directory to copy.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>state</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||||
|
<li><div style="color: blue"><b>to_pod</b> ←</div></li>
|
||||||
|
<li>from_pod</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>When set to <code>to_pod</code>, the local <em>local_path</em> file or directory will be copied to <em>remote_path</em> into the pod.</div>
|
||||||
|
<div>When set to <code>from_pod</code>, the remote file or directory <em>remote_path</em> from pod will be copied locally to <em>local_path</em>.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>username</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Provide a username for authenticating with the API. Can also be specified via K8S_AUTH_USERNAME environment variable.</div>
|
||||||
|
<div>Please note that this only works with clusters configured to use HTTP Basic Auth. If your cluster has a different form of authentication (e.g. OAuth2 in OpenShift), this option will not work as expected and you should look into the <span class='module'>community.okd.k8s_auth</span> module, as that might do what you need.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>validate_certs</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">boolean</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||||
|
<li>no</li>
|
||||||
|
<li>yes</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Whether or not to verify the API server's SSL certificates. Can also be specified via K8S_AUTH_VERIFY_SSL environment variable.</div>
|
||||||
|
<div style="font-size: small; color: darkgreen"><br/>aliases: verify_ssl</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
|
||||||
|
Notes
|
||||||
|
-----
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
- the tar binary is required on the container when copying from local filesystem to pod.
|
||||||
|
- To avoid SSL certificate validation errors when ``validate_certs`` is *True*, the full certificate chain for the API server must be provided via ``ca_cert`` or in the kubeconfig file.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
# kubectl cp /tmp/foo some-namespace/some-pod:/tmp/bar
|
||||||
|
- name: Copy /tmp/foo local file to /tmp/bar in a remote pod
|
||||||
|
kubernetes.core.k8s_cp:
|
||||||
|
namespace: some-namespace
|
||||||
|
pod: some-pod
|
||||||
|
remote_path: /tmp/bar
|
||||||
|
local_path: /tmp/foo
|
||||||
|
|
||||||
|
# kubectl cp /tmp/foo_dir some-namespace/some-pod:/tmp/bar_dir
|
||||||
|
- name: Copy /tmp/foo_dir local directory to /tmp/bar_dir in a remote pod
|
||||||
|
kubernetes.core.k8s_cp:
|
||||||
|
namespace: some-namespace
|
||||||
|
pod: some-pod
|
||||||
|
remote_path: /tmp/bar_dir
|
||||||
|
local_path: /tmp/foo_dir
|
||||||
|
|
||||||
|
# kubectl cp /tmp/foo some-namespace/some-pod:/tmp/bar -c some-container
|
||||||
|
- name: Copy /tmp/foo local file to /tmp/bar in a remote pod in a specific container
|
||||||
|
kubernetes.core.k8s_cp:
|
||||||
|
namespace: some-namespace
|
||||||
|
pod: some-pod
|
||||||
|
container: some-container
|
||||||
|
remote_path: /tmp/bar
|
||||||
|
local_path: /tmp/foo
|
||||||
|
no_preserve: True
|
||||||
|
state: to_pod
|
||||||
|
|
||||||
|
# kubectl cp some-namespace/some-pod:/tmp/foo /tmp/bar
|
||||||
|
- name: Copy /tmp/foo from a remote pod to /tmp/bar locally
|
||||||
|
kubernetes.core.k8s_cp:
|
||||||
|
namespace: some-namespace
|
||||||
|
pod: some-pod
|
||||||
|
remote_path: /tmp/foo
|
||||||
|
local_path: /tmp/bar
|
||||||
|
state: from_pod
|
||||||
|
|
||||||
|
# copy content into a file in the remote pod
|
||||||
|
- name: Copy /tmp/foo from a remote pod to /tmp/bar locally
|
||||||
|
kubernetes.core.k8s_cp:
|
||||||
|
state: to_pod
|
||||||
|
namespace: some-namespace
|
||||||
|
pod: some-pod
|
||||||
|
remote_path: /tmp/foo.txt
|
||||||
|
content: "This content will be copied into remote file"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Return Values
|
||||||
|
-------------
|
||||||
|
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
|
||||||
|
<table border=0 cellpadding=0 class="documentation-table">
|
||||||
|
<tr>
|
||||||
|
<th colspan="1">Key</th>
|
||||||
|
<th>Returned</th>
|
||||||
|
<th width="100%">Description</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||||
|
<b>result</b>
|
||||||
|
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>success</td>
|
||||||
|
<td>
|
||||||
|
<div>message describing the copy operation successfully done.</div>
|
||||||
|
<br/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<br/><br/>
|
||||||
|
|
||||||
|
|
||||||
|
Status
|
||||||
|
------
|
||||||
|
|
||||||
|
|
||||||
|
Authors
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
- Aubin Bikouo (@abikouo)
|
||||||
561
docs/kubernetes.core.k8s_drain_module.rst
Normal file
561
docs/kubernetes.core.k8s_drain_module.rst
Normal file
@@ -0,0 +1,561 @@
|
|||||||
|
.. _kubernetes.core.k8s_drain_module:
|
||||||
|
|
||||||
|
|
||||||
|
*************************
|
||||||
|
kubernetes.core.k8s_drain
|
||||||
|
*************************
|
||||||
|
|
||||||
|
**Drain, Cordon, or Uncordon node in k8s cluster**
|
||||||
|
|
||||||
|
|
||||||
|
Version added: 2.2.0
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
:depth: 1
|
||||||
|
|
||||||
|
|
||||||
|
Synopsis
|
||||||
|
--------
|
||||||
|
- Drain node in preparation for maintenance same as kubectl drain.
|
||||||
|
- Cordon will mark the node as unschedulable.
|
||||||
|
- Uncordon will mark the node as schedulable.
|
||||||
|
- The given node will be marked unschedulable to prevent new pods from arriving.
|
||||||
|
- Then drain deletes all pods except mirror pods (which cannot be deleted through the API server).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
The below requirements are needed on the host that executes this module.
|
||||||
|
|
||||||
|
- python >= 3.6
|
||||||
|
- kubernetes >= 12.0.0
|
||||||
|
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
|
||||||
|
<table border=0 cellpadding=0 class="documentation-table">
|
||||||
|
<tr>
|
||||||
|
<th colspan="2">Parameter</th>
|
||||||
|
<th>Choices/<font color="blue">Defaults</font></th>
|
||||||
|
<th width="100%">Comments</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>api_key</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Token used to authenticate with the API. Can also be specified via K8S_AUTH_API_KEY environment variable.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>ca_cert</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">path</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Path to a CA certificate used to authenticate with the API. The full certificate chain must be provided to avoid certificate validation errors. Can also be specified via K8S_AUTH_SSL_CA_CERT environment variable.</div>
|
||||||
|
<div style="font-size: small; color: darkgreen"><br/>aliases: ssl_ca_cert</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>client_cert</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">path</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Path to a certificate used to authenticate with the API. Can also be specified via K8S_AUTH_CERT_FILE environment variable.</div>
|
||||||
|
<div style="font-size: small; color: darkgreen"><br/>aliases: cert_file</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>client_key</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">path</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Path to a key file used to authenticate with the API. Can also be specified via K8S_AUTH_KEY_FILE environment variable.</div>
|
||||||
|
<div style="font-size: small; color: darkgreen"><br/>aliases: key_file</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>context</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>The name of a context found in the config file. Can also be specified via K8S_AUTH_CONTEXT environment variable.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>delete_options</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">dictionary</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Specify options to delete pods.</div>
|
||||||
|
<div>This option has effect only when <code>state</code> is set to <em>drain</em>.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>disable_eviction</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">boolean</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||||
|
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||||
|
<li>yes</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Forces drain to use delete rather than evict.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>force</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">boolean</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||||
|
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||||
|
<li>yes</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Continue even if there are pods not managed by a ReplicationController, Job, or DaemonSet.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>ignore_daemonsets</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">boolean</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||||
|
<li><div style="color: blue"><b>no</b> ←</div></li>
|
||||||
|
<li>yes</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Ignore DaemonSet-managed pods.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>terminate_grace_period</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">integer</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Specify how many seconds to wait before forcefully terminating.</div>
|
||||||
|
<div>If not specified, the default grace period for the object type will be used.</div>
|
||||||
|
<div>The value zero indicates delete immediately.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>wait_sleep</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">integer</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<b>Default:</b><br/><div style="color: blue">5</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Number of seconds to sleep between checks.</div>
|
||||||
|
<div>Ignored if <code>wait_timeout</code> is not set.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>wait_timeout</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">integer</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>The length of time to wait in seconds for pod to be deleted before giving up, zero means infinite.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>host</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Provide a URL for accessing the API. Can also be specified via K8S_AUTH_HOST environment variable.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>kubeconfig</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">raw</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
||||||
|
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version >= 17.17.0. Added in version 2.2.0.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>name</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
/ <span style="color: red">required</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>The name of the node.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>password</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Provide a password for authenticating with the API. Can also be specified via K8S_AUTH_PASSWORD environment variable.</div>
|
||||||
|
<div>Please read the description of the <code>username</code> option for a discussion of when this option is applicable.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>persist_config</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">boolean</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||||
|
<li>no</li>
|
||||||
|
<li>yes</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Whether or not to save the kube config refresh tokens. Can also be specified via K8S_AUTH_PERSIST_CONFIG environment variable.</div>
|
||||||
|
<div>When the k8s context is using a user credentials with refresh tokens (like oidc or gke/gcloud auth), the token is refreshed by the k8s python client library but not saved by default. So the old refresh token can expire and the next auth might fail. Setting this flag to true will tell the k8s python client to save the new refresh token to the kube config file.</div>
|
||||||
|
<div>Default to false.</div>
|
||||||
|
<div>Please note that the current version of the k8s python client library does not support setting this flag to True yet.</div>
|
||||||
|
<div>The fix for this k8s python library is here: https://github.com/kubernetes-client/python-base/pull/169</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>proxy</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>The URL of an HTTP proxy to use for the connection. Can also be specified via K8S_AUTH_PROXY environment variable.</div>
|
||||||
|
<div>Please note that this module does not pick up typical proxy settings from the environment (e.g. HTTP_PROXY).</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>proxy_headers</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">dictionary</span>
|
||||||
|
</div>
|
||||||
|
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.0.0</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>The Header used for the HTTP proxy.</div>
|
||||||
|
<div>Documentation can be found here <a href='https://urllib3.readthedocs.io/en/latest/reference/urllib3.util.html?highlight=proxy_headers#urllib3.util.make_headers'>https://urllib3.readthedocs.io/en/latest/reference/urllib3.util.html?highlight=proxy_headers#urllib3.util.make_headers</a>.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>basic_auth</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Colon-separated username:password for basic authentication header.</div>
|
||||||
|
<div>Can also be specified via K8S_AUTH_PROXY_HEADERS_BASIC_AUTH environment.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>proxy_basic_auth</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Colon-separated username:password for proxy basic authentication header.</div>
|
||||||
|
<div>Can also be specified via K8S_AUTH_PROXY_HEADERS_PROXY_BASIC_AUTH environment.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"></td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>user_agent</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>String representing the user-agent you want, such as foo/1.0.</div>
|
||||||
|
<div>Can also be specified via K8S_AUTH_PROXY_HEADERS_USER_AGENT environment.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>state</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||||
|
<li>cordon</li>
|
||||||
|
<li><div style="color: blue"><b>drain</b> ←</div></li>
|
||||||
|
<li>uncordon</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Determines whether to drain, cordon, or uncordon node.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>username</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Provide a username for authenticating with the API. Can also be specified via K8S_AUTH_USERNAME environment variable.</div>
|
||||||
|
<div>Please note that this only works with clusters configured to use HTTP Basic Auth. If your cluster has a different form of authentication (e.g. OAuth2 in OpenShift), this option will not work as expected and you should look into the <span class='module'>community.okd.k8s_auth</span> module, as that might do what you need.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>validate_certs</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">boolean</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||||
|
<li>no</li>
|
||||||
|
<li>yes</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Whether or not to verify the API server's SSL certificates. Can also be specified via K8S_AUTH_VERIFY_SSL environment variable.</div>
|
||||||
|
<div style="font-size: small; color: darkgreen"><br/>aliases: verify_ssl</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
|
||||||
|
Notes
|
||||||
|
-----
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
- To avoid SSL certificate validation errors when ``validate_certs`` is *True*, the full certificate chain for the API server must be provided via ``ca_cert`` or in the kubeconfig file.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
- name: Drain node "foo", even if there are pods not managed by a ReplicationController, Job, or DaemonSet on it.
|
||||||
|
kubernetes.core.k8s_drain:
|
||||||
|
state: drain
|
||||||
|
name: foo
|
||||||
|
force: yes
|
||||||
|
|
||||||
|
- name: Drain node "foo", but abort if there are pods not managed by a ReplicationController, Job, or DaemonSet, and use a grace period of 15 minutes.
|
||||||
|
kubernetes.core.k8s_drain:
|
||||||
|
state: drain
|
||||||
|
name: foo
|
||||||
|
delete_options:
|
||||||
|
terminate_grace_period: 900
|
||||||
|
|
||||||
|
- name: Mark node "foo" as schedulable.
|
||||||
|
kubernetes.core.k8s_drain:
|
||||||
|
state: uncordon
|
||||||
|
name: foo
|
||||||
|
|
||||||
|
- name: Mark node "foo" as unschedulable.
|
||||||
|
kubernetes.core.k8s_drain:
|
||||||
|
state: cordon
|
||||||
|
name: foo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Return Values
|
||||||
|
-------------
|
||||||
|
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this module:
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
|
||||||
|
<table border=0 cellpadding=0 class="documentation-table">
|
||||||
|
<tr>
|
||||||
|
<th colspan="1">Key</th>
|
||||||
|
<th>Returned</th>
|
||||||
|
<th width="100%">Description</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||||
|
<b>result</b>
|
||||||
|
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>success</td>
|
||||||
|
<td>
|
||||||
|
<div>The node status and the number of pods deleted.</div>
|
||||||
|
<br/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<br/><br/>
|
||||||
|
|
||||||
|
|
||||||
|
Status
|
||||||
|
------
|
||||||
|
|
||||||
|
|
||||||
|
Authors
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
- Aubin Bikouo (@abikouo)
|
||||||
@@ -172,13 +172,14 @@ Parameters
|
|||||||
<b>kubeconfig</b>
|
<b>kubeconfig</b>
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
<div style="font-size: small">
|
<div style="font-size: small">
|
||||||
<span style="color: purple">path</span>
|
<span style="color: purple">raw</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
||||||
|
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version >= 17.17.0. Added in version 2.2.0.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -382,6 +383,7 @@ Notes
|
|||||||
-----
|
-----
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
- Return code ``rc`` for the command executed is added in output in version 2.2.0, and deprecates return code ``return_code``.
|
||||||
- Return code ``return_code`` for the command executed is added in output in version 1.0.0.
|
- Return code ``return_code`` for the command executed is added in output in version 1.0.0.
|
||||||
- The authenticated user must have at least read access to the pods resource and write access to the pods/exec resource.
|
- The authenticated user must have at least read access to the pods resource and write access to the pods/exec resource.
|
||||||
- To avoid SSL certificate validation errors when ``validate_certs`` is *True*, the full certificate chain for the API server must be provided via ``ca_cert`` or in the kubeconfig file.
|
- To avoid SSL certificate validation errors when ``validate_certs`` is *True*, the full certificate chain for the API server must be provided via ``ca_cert`` or in the kubeconfig file.
|
||||||
@@ -410,7 +412,7 @@ Examples
|
|||||||
- name: Check last command status
|
- name: Check last command status
|
||||||
debug:
|
debug:
|
||||||
msg: "cmd failed"
|
msg: "cmd failed"
|
||||||
when: command_status.return_code != 0
|
when: command_status.rc != 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -440,6 +442,23 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late
|
|||||||
<div>The command object</div>
|
<div>The command object</div>
|
||||||
<br/>
|
<br/>
|
||||||
</td>
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"> </td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||||
|
<b>rc</b>
|
||||||
|
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">integer</span>
|
||||||
|
</div>
|
||||||
|
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.2.0</div>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<div>The command status code</div>
|
||||||
|
<br/>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="elbow-placeholder"> </td>
|
<td class="elbow-placeholder"> </td>
|
||||||
@@ -453,7 +472,7 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late
|
|||||||
</td>
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>
|
<td>
|
||||||
<div>The command status code</div>
|
<div>The command status code. This attribute is deprecated and will be removed in a future release. Please use rc instead.</div>
|
||||||
<br/>
|
<br/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -198,13 +198,14 @@ Parameters
|
|||||||
<b>kubeconfig</b>
|
<b>kubeconfig</b>
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
<div style="font-size: small">
|
<div style="font-size: small">
|
||||||
<span style="color: purple">path</span>
|
<span style="color: purple">raw</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
||||||
|
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version >= 17.17.0. Added in version 2.2.0.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -300,6 +300,7 @@ Parameters
|
|||||||
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
<ul style="margin: 0; padding: 0"><b>Choices:</b>
|
||||||
<li>kubernetes.core.k8s</li>
|
<li>kubernetes.core.k8s</li>
|
||||||
<li>k8s</li>
|
<li>k8s</li>
|
||||||
|
<li>community.kubernetes.k8s</li>
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Version added: 2.0.0
|
|||||||
Synopsis
|
Synopsis
|
||||||
--------
|
--------
|
||||||
- This module is used to apply RFC 6902 JSON patch operations only.
|
- This module is used to apply RFC 6902 JSON patch operations only.
|
||||||
- Use the :ref:`k8s <k8s_module>` module for strategic merge or JSON merge operations.
|
- Use the :ref:`kubernetes.core.k8s <kubernetes.core.k8s_module>` module for strategic merge or JSON merge operations.
|
||||||
- The jsonpatch library is required for check mode.
|
- The jsonpatch library is required for check mode.
|
||||||
|
|
||||||
|
|
||||||
@@ -178,13 +178,14 @@ Parameters
|
|||||||
<b>kubeconfig</b>
|
<b>kubeconfig</b>
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
<div style="font-size: small">
|
<div style="font-size: small">
|
||||||
<span style="color: purple">path</span>
|
<span style="color: purple">raw</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
||||||
|
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version >= 17.17.0. Added in version 2.2.0.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -198,13 +198,14 @@ Parameters
|
|||||||
<b>kubeconfig</b>
|
<b>kubeconfig</b>
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
<div style="font-size: small">
|
<div style="font-size: small">
|
||||||
<span style="color: purple">path</span>
|
<span style="color: purple">raw</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
||||||
|
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version >= 17.17.0. Added in version 2.2.0.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -383,6 +384,22 @@ Parameters
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>since_seconds</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.2.0</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>A relative time in seconds before the current time from which to show logs.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
@@ -457,6 +474,7 @@ Examples
|
|||||||
kind: Deployment
|
kind: Deployment
|
||||||
namespace: testing
|
namespace: testing
|
||||||
name: example
|
name: example
|
||||||
|
since_seconds: "4000"
|
||||||
register: log
|
register: log
|
||||||
|
|
||||||
# This will get the log from a single Pod managed by this DeploymentConfig
|
# This will get the log from a single Pod managed by this DeploymentConfig
|
||||||
|
|||||||
@@ -381,6 +381,12 @@ Parameters
|
|||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
|
||||||
|
Notes
|
||||||
|
-----
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
- While querying, please use ``query`` or ``lookup`` format with ``wantlist=True`` to provide an easier and more consistent interface. For more details, see https://docs.ansible.com/ansible/latest/plugins/lookup.html#forcing-lookups-to-return-lists-query-and-wantlist-true.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Examples
|
Examples
|
||||||
@@ -390,23 +396,23 @@ Examples
|
|||||||
|
|
||||||
- name: Fetch a list of namespaces
|
- name: Fetch a list of namespaces
|
||||||
set_fact:
|
set_fact:
|
||||||
projects: "{{ lookup('kubernetes.core.k8s', api_version='v1', kind='Namespace') }}"
|
projects: "{{ query('kubernetes.core.k8s', api_version='v1', kind='Namespace') }}"
|
||||||
|
|
||||||
- name: Fetch all deployments
|
- name: Fetch all deployments
|
||||||
set_fact:
|
set_fact:
|
||||||
deployments: "{{ lookup('kubernetes.core.k8s', kind='Deployment') }}"
|
deployments: "{{ query('kubernetes.core.k8s', kind='Deployment') }}"
|
||||||
|
|
||||||
- name: Fetch all deployments in a namespace
|
- name: Fetch all deployments in a namespace
|
||||||
set_fact:
|
set_fact:
|
||||||
deployments: "{{ lookup('kubernetes.core.k8s', kind='Deployment', namespace='testing') }}"
|
deployments: "{{ query('kubernetes.core.k8s', kind='Deployment', namespace='testing') }}"
|
||||||
|
|
||||||
- name: Fetch a specific deployment by name
|
- name: Fetch a specific deployment by name
|
||||||
set_fact:
|
set_fact:
|
||||||
deployments: "{{ lookup('kubernetes.core.k8s', kind='Deployment', namespace='testing', resource_name='elastic') }}"
|
deployments: "{{ query('kubernetes.core.k8s', kind='Deployment', namespace='testing', resource_name='elastic') }}"
|
||||||
|
|
||||||
- name: Fetch with label selector
|
- name: Fetch with label selector
|
||||||
set_fact:
|
set_fact:
|
||||||
service: "{{ lookup('kubernetes.core.k8s', kind='Service', label_selector='app=galaxy') }}"
|
service: "{{ query('kubernetes.core.k8s', kind='Service', label_selector='app=galaxy') }}"
|
||||||
|
|
||||||
# Use parameters from a YAML config
|
# Use parameters from a YAML config
|
||||||
|
|
||||||
@@ -416,11 +422,11 @@ Examples
|
|||||||
|
|
||||||
- name: Using the config (loaded from a file in prior task), fetch the latest version of the object
|
- name: Using the config (loaded from a file in prior task), fetch the latest version of the object
|
||||||
set_fact:
|
set_fact:
|
||||||
service: "{{ lookup('kubernetes.core.k8s', resource_definition=config) }}"
|
service: "{{ query('kubernetes.core.k8s', resource_definition=config) }}"
|
||||||
|
|
||||||
- name: Use a config from the local filesystem
|
- name: Use a config from the local filesystem
|
||||||
set_fact:
|
set_fact:
|
||||||
service: "{{ lookup('kubernetes.core.k8s', src='service.yml') }}"
|
service: "{{ query('kubernetes.core.k8s', src='service.yml') }}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -375,13 +375,31 @@ Parameters
|
|||||||
<b>kubeconfig</b>
|
<b>kubeconfig</b>
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
<div style="font-size: small">
|
<div style="font-size: small">
|
||||||
<span style="color: purple">path</span>
|
<span style="color: purple">raw</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
||||||
|
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version >= 17.17.0. Added in version 2.2.0.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="3">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>label_selectors</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">list</span>
|
||||||
|
/ <span style="color: purple">elements=string</span>
|
||||||
|
</div>
|
||||||
|
<div style="font-style: italic; font-size: small; color: darkgreen">added in 2.2.0</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>Selector (label query) to filter on.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -639,6 +657,7 @@ Parameters
|
|||||||
<td>
|
<td>
|
||||||
<div>Provide a valid YAML template definition file for an object when creating or updating.</div>
|
<div>Provide a valid YAML template definition file for an object when creating or updating.</div>
|
||||||
<div>Value can be provided as string or dictionary.</div>
|
<div>Value can be provided as string or dictionary.</div>
|
||||||
|
<div>The parameter accepts multiple template files. Added in version 2.0.0.</div>
|
||||||
<div>Mutually exclusive with <code>src</code> and <code>resource_definition</code>.</div>
|
<div>Mutually exclusive with <code>src</code> and <code>resource_definition</code>.</div>
|
||||||
<div>Template files needs to be present on the Ansible Controller's file system.</div>
|
<div>Template files needs to be present on the Ansible Controller's file system.</div>
|
||||||
<div>Additional parameters can be specified using dictionary.</div>
|
<div>Additional parameters can be specified using dictionary.</div>
|
||||||
@@ -975,6 +994,15 @@ Examples
|
|||||||
variable_start_string: '[['
|
variable_start_string: '[['
|
||||||
variable_end_string: ']]'
|
variable_end_string: ']]'
|
||||||
|
|
||||||
|
- name: Read multiple definition template file from the Ansible controller file system
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
state: present
|
||||||
|
template:
|
||||||
|
- path: '/testing/deployment_one.j2'
|
||||||
|
- path: '/testing/deployment_two.j2'
|
||||||
|
variable_start_string: '[['
|
||||||
|
variable_end_string: ']]'
|
||||||
|
|
||||||
- name: fail on validation errors
|
- name: fail on validation errors
|
||||||
kubernetes.core.k8s:
|
kubernetes.core.k8s:
|
||||||
state: present
|
state: present
|
||||||
|
|||||||
@@ -196,13 +196,14 @@ Parameters
|
|||||||
<b>kubeconfig</b>
|
<b>kubeconfig</b>
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
<div style="font-size: small">
|
<div style="font-size: small">
|
||||||
<span style="color: purple">path</span>
|
<span style="color: purple">raw</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
||||||
|
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version >= 17.17.0. Added in version 2.2.0.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -213,13 +213,14 @@ Parameters
|
|||||||
<b>kubeconfig</b>
|
<b>kubeconfig</b>
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
<div style="font-size: small">
|
<div style="font-size: small">
|
||||||
<span style="color: purple">path</span>
|
<span style="color: purple">raw</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
||||||
|
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version >= 17.17.0. Added in version 2.2.0.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -178,13 +178,14 @@ Parameters
|
|||||||
<b>kubeconfig</b>
|
<b>kubeconfig</b>
|
||||||
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
<div style="font-size: small">
|
<div style="font-size: small">
|
||||||
<span style="color: purple">path</span>
|
<span style="color: purple">raw</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
<div>Path to an existing Kubernetes config file. If not provided, and no other connection options are provided, the Kubernetes client will attempt to load the default configuration file from <em>~/.kube/config</em>. Can also be specified via K8S_AUTH_KUBECONFIG environment variable.</div>
|
||||||
|
<div>The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version >= 17.17.0. Added in version 2.2.0.</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
251
docs/kubernetes.core.kustomize_lookup.rst
Normal file
251
docs/kubernetes.core.kustomize_lookup.rst
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
.. _kubernetes.core.kustomize_lookup:
|
||||||
|
|
||||||
|
|
||||||
|
*************************
|
||||||
|
kubernetes.core.kustomize
|
||||||
|
*************************
|
||||||
|
|
||||||
|
**Build a set of kubernetes resources using a 'kustomization.yaml' file.**
|
||||||
|
|
||||||
|
|
||||||
|
Version added: 2.2.0
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:local:
|
||||||
|
:depth: 1
|
||||||
|
|
||||||
|
|
||||||
|
Synopsis
|
||||||
|
--------
|
||||||
|
- Uses the kustomize or the kubectl tool.
|
||||||
|
- Return the result of ``kustomize build`` or ``kubectl kustomize``.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
------------
|
||||||
|
The below requirements are needed on the local Ansible controller node that executes this lookup.
|
||||||
|
|
||||||
|
- python >= 3.6
|
||||||
|
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
|
||||||
|
<table border=0 cellpadding=0 class="documentation-table">
|
||||||
|
<tr>
|
||||||
|
<th colspan="1">Parameter</th>
|
||||||
|
<th>Choices/<font color="blue">Defaults</font></th>
|
||||||
|
<th>Configuration</th>
|
||||||
|
<th width="100%">Comments</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>binary_path</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">-</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>The path of a kustomize or kubectl binary to use.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>dir</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">-</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<b>Default:</b><br/><div style="color: blue">"."</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>The directory path containing 'kustomization.yaml', or a git repository URL with a path suffix specifying same with respect to the repository root.</div>
|
||||||
|
<div>If omitted, '.' is assumed.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="parameter-"></div>
|
||||||
|
<b>opt_dirs</b>
|
||||||
|
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">-</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div>An optional list of directories to search for the executable in addition to PATH.</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
|
||||||
|
Notes
|
||||||
|
-----
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
- If both kustomize and kubectl are part of the PATH, kustomize will be used by the plugin.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Examples
|
||||||
|
--------
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
- name: Run lookup using kustomize
|
||||||
|
set_fact:
|
||||||
|
resources: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kustomize') }}"
|
||||||
|
|
||||||
|
- name: Run lookup using kubectl kustomize
|
||||||
|
set_fact:
|
||||||
|
resources: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kubectl') }}"
|
||||||
|
|
||||||
|
- name: Create kubernetes resources for lookup output
|
||||||
|
k8s:
|
||||||
|
definition: "{{ lookup('kubernetes.core.kustomize', dir='/path/to/kustomization') }}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Return Values
|
||||||
|
-------------
|
||||||
|
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this lookup:
|
||||||
|
|
||||||
|
.. raw:: html
|
||||||
|
|
||||||
|
<table border=0 cellpadding=0 class="documentation-table">
|
||||||
|
<tr>
|
||||||
|
<th colspan="2">Key</th>
|
||||||
|
<th>Returned</th>
|
||||||
|
<th width="100%">Description</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||||
|
<b>_list</b>
|
||||||
|
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">complex</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<div>One ore more object definitions returned from the tool execution.</div>
|
||||||
|
<br/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"> </td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||||
|
<b>api_version</b>
|
||||||
|
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>success</td>
|
||||||
|
<td>
|
||||||
|
<div>The versioned schema of this representation of an object.</div>
|
||||||
|
<br/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"> </td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||||
|
<b>kind</b>
|
||||||
|
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">string</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>success</td>
|
||||||
|
<td>
|
||||||
|
<div>Represents the REST resource this object represents.</div>
|
||||||
|
<br/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"> </td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||||
|
<b>metadata</b>
|
||||||
|
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">complex</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>success</td>
|
||||||
|
<td>
|
||||||
|
<div>Standard object metadata. Includes name, namespace, annotations, labels, etc.</div>
|
||||||
|
<br/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"> </td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||||
|
<b>spec</b>
|
||||||
|
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">complex</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>success</td>
|
||||||
|
<td>
|
||||||
|
<div>Specific attributes of the object. Will vary based on the <em>api_version</em> and <em>kind</em>.</div>
|
||||||
|
<br/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="elbow-placeholder"> </td>
|
||||||
|
<td colspan="1">
|
||||||
|
<div class="ansibleOptionAnchor" id="return-"></div>
|
||||||
|
<b>status</b>
|
||||||
|
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
|
||||||
|
<div style="font-size: small">
|
||||||
|
<span style="color: purple">complex</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>success</td>
|
||||||
|
<td>
|
||||||
|
<div>Current status details for the object.</div>
|
||||||
|
<br/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
<br/><br/>
|
||||||
|
|
||||||
|
|
||||||
|
Status
|
||||||
|
------
|
||||||
|
|
||||||
|
|
||||||
|
Authors
|
||||||
|
~~~~~~~
|
||||||
|
|
||||||
|
- Aubin Bikouo <@abikouo>
|
||||||
|
|
||||||
|
|
||||||
|
.. hint::
|
||||||
|
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
|
||||||
@@ -8,8 +8,6 @@ authors:
|
|||||||
- willthames (https://github.com/willthames)
|
- willthames (https://github.com/willthames)
|
||||||
- mmazur (https://github.com/mmazur)
|
- mmazur (https://github.com/mmazur)
|
||||||
- jamescassell (https://github.com/jamescassell)
|
- jamescassell (https://github.com/jamescassell)
|
||||||
dependencies:
|
|
||||||
cloud.common: '>=2.0.1'
|
|
||||||
description: Kubernetes Collection for Ansible.
|
description: Kubernetes Collection for Ansible.
|
||||||
documentation: ''
|
documentation: ''
|
||||||
homepage: ''
|
homepage: ''
|
||||||
@@ -27,7 +25,7 @@ tags:
|
|||||||
- openshift
|
- openshift
|
||||||
- okd
|
- okd
|
||||||
- cluster
|
- cluster
|
||||||
version: 2.0.0
|
version: 2.2.2
|
||||||
build_ignore:
|
build_ignore:
|
||||||
- .DS_Store
|
- .DS_Store
|
||||||
- '*.tar.gz'
|
- '*.tar.gz'
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ action_groups:
|
|||||||
- k8s_log
|
- k8s_log
|
||||||
- k8s_scale
|
- k8s_scale
|
||||||
- k8s_service
|
- k8s_service
|
||||||
|
- k8s_cp
|
||||||
|
- k8s_drain
|
||||||
|
|
||||||
plugin_routing:
|
plugin_routing:
|
||||||
action:
|
action:
|
||||||
@@ -31,6 +33,10 @@ plugin_routing:
|
|||||||
redirect: kubernetes.core.k8s_info
|
redirect: kubernetes.core.k8s_info
|
||||||
k8s_cluster_info:
|
k8s_cluster_info:
|
||||||
redirect: kubernetes.core.k8s_info
|
redirect: kubernetes.core.k8s_info
|
||||||
|
k8s_cp:
|
||||||
|
redirect: kubernetes.core.k8s_info
|
||||||
|
k8s_drain:
|
||||||
|
redirect: kubernetes.core.k8s_info
|
||||||
k8s_event_info:
|
k8s_event_info:
|
||||||
redirect: kubernetes.core.k8s_info
|
redirect: kubernetes.core.k8s_info
|
||||||
k8s_exec:
|
k8s_exec:
|
||||||
|
|||||||
@@ -132,6 +132,15 @@
|
|||||||
tags: [ template, k8s ]
|
tags: [ template, k8s ]
|
||||||
tags:
|
tags:
|
||||||
- always
|
- always
|
||||||
|
|
||||||
|
- name: Include validate.yml
|
||||||
|
include_tasks:
|
||||||
|
file: tasks/validate.yml
|
||||||
|
apply:
|
||||||
|
tags: [ validate, k8s ]
|
||||||
|
tags:
|
||||||
|
- always
|
||||||
|
|
||||||
- name: Include waiter.yml
|
- name: Include waiter.yml
|
||||||
include_tasks:
|
include_tasks:
|
||||||
file: tasks/waiter.yml
|
file: tasks/waiter.yml
|
||||||
@@ -160,7 +169,31 @@
|
|||||||
include_tasks:
|
include_tasks:
|
||||||
file: tasks/lookup_k8s.yml
|
file: tasks/lookup_k8s.yml
|
||||||
apply:
|
apply:
|
||||||
tags: [ lookup, k8s ]
|
tags: [ lookup_k8s, k8s ]
|
||||||
|
tags:
|
||||||
|
- always
|
||||||
|
|
||||||
|
- name: Include label_selectors.yml
|
||||||
|
include_tasks:
|
||||||
|
file: tasks/label_selectors.yml
|
||||||
|
apply:
|
||||||
|
tags: [ label_selectors, k8s ]
|
||||||
|
tags:
|
||||||
|
- always
|
||||||
|
|
||||||
|
- name: Include diff.yml
|
||||||
|
include_tasks:
|
||||||
|
file: tasks/diff.yml
|
||||||
|
apply:
|
||||||
|
tags: [ diff, k8s ]
|
||||||
|
tags:
|
||||||
|
- always
|
||||||
|
|
||||||
|
- name: Include lookup_kustomize.yml
|
||||||
|
include_tasks:
|
||||||
|
file: tasks/lookup_kustomize.yml
|
||||||
|
apply:
|
||||||
|
tags: [ lookup_kustomize, k8s ]
|
||||||
tags:
|
tags:
|
||||||
- always
|
- always
|
||||||
|
|
||||||
@@ -169,6 +202,11 @@
|
|||||||
tags:
|
tags:
|
||||||
- helm
|
- helm
|
||||||
|
|
||||||
|
- role: k8scopy
|
||||||
|
tags:
|
||||||
|
- copy
|
||||||
|
- k8s
|
||||||
|
|
||||||
post_tasks:
|
post_tasks:
|
||||||
- name: Ensure namespace exists
|
- name: Ensure namespace exists
|
||||||
k8s:
|
k8s:
|
||||||
|
|||||||
@@ -6,10 +6,6 @@ driver:
|
|||||||
login_cmd_template: 'docker exec -ti {instance} bash'
|
login_cmd_template: 'docker exec -ti {instance} bash'
|
||||||
ansible_connection_options:
|
ansible_connection_options:
|
||||||
ansible_connection: docker
|
ansible_connection: docker
|
||||||
lint: |
|
|
||||||
set -e
|
|
||||||
yamllint .
|
|
||||||
flake8
|
|
||||||
platforms:
|
platforms:
|
||||||
- name: instance-kind
|
- name: instance-kind
|
||||||
provisioner:
|
provisioner:
|
||||||
@@ -17,7 +13,7 @@ provisioner:
|
|||||||
log: true
|
log: true
|
||||||
config_options:
|
config_options:
|
||||||
inventory:
|
inventory:
|
||||||
enable_plugins: kubernetes.core.k8s
|
enable_plugins: kubernetes.core.k8s,yaml
|
||||||
lint: {}
|
lint: {}
|
||||||
inventory:
|
inventory:
|
||||||
hosts:
|
hosts:
|
||||||
@@ -33,11 +29,7 @@ scenario:
|
|||||||
name: default
|
name: default
|
||||||
test_sequence:
|
test_sequence:
|
||||||
- dependency
|
- dependency
|
||||||
- lint
|
|
||||||
- syntax
|
- syntax
|
||||||
|
- prepare
|
||||||
- converge
|
- converge
|
||||||
- verify
|
- verify
|
||||||
dependency:
|
|
||||||
name: galaxy
|
|
||||||
options:
|
|
||||||
requirements-file: requirements.yml
|
|
||||||
|
|||||||
12
molecule/default/prepare.yml
Normal file
12
molecule/default/prepare.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
- name: Prepare
|
||||||
|
hosts: localhost
|
||||||
|
connection: local
|
||||||
|
|
||||||
|
collections:
|
||||||
|
- kubernetes.core
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Include drain.yml
|
||||||
|
include_tasks:
|
||||||
|
file: tasks/drain.yml
|
||||||
3
molecule/default/roles/helm/meta/main.yml
Normal file
3
molecule/default/roles/helm/meta/main.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
collections:
|
||||||
|
- kubernetes.core
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
- name: Install chart while skipping CRDs
|
- name: Install chart while skipping CRDs
|
||||||
helm:
|
helm:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
chart_ref: "/tmp/helm_test_crds/{{ test_chart }}"
|
chart_ref: "/tmp/helm_test_crds/{{ test_chart }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
name: test-crds
|
name: test-crds
|
||||||
@@ -46,12 +47,14 @@
|
|||||||
# Helm won't install CRDs into an existing release, so we need to delete this, first
|
# Helm won't install CRDs into an existing release, so we need to delete this, first
|
||||||
- name: Uninstall chart
|
- name: Uninstall chart
|
||||||
helm:
|
helm:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
name: test-crds
|
name: test-crds
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: Install chart with CRDs
|
- name: Install chart with CRDs
|
||||||
helm:
|
helm:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
chart_ref: "/tmp/helm_test_crds/{{ test_chart }}"
|
chart_ref: "/tmp/helm_test_crds/{{ test_chart }}"
|
||||||
namespace: "{{ helm_namespace }}"
|
namespace: "{{ helm_namespace }}"
|
||||||
name: test-crds
|
name: test-crds
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
- name: Add chart repo
|
- name: Add chart repo
|
||||||
helm_repository:
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
name: test_helm
|
name: test_helm
|
||||||
repo_url: "{{ chart_test_repo }}"
|
repo_url: "{{ chart_test_repo }}"
|
||||||
|
|
||||||
@@ -14,6 +15,7 @@
|
|||||||
|
|
||||||
- name: Add chart repo
|
- name: Add chart repo
|
||||||
helm_repository:
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
name: test_helm
|
name: test_helm
|
||||||
repo_url: "{{ chart_test_repo }}"
|
repo_url: "{{ chart_test_repo }}"
|
||||||
state: absent
|
state: absent
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
block:
|
block:
|
||||||
- name: Install helm diff
|
- name: Install helm diff
|
||||||
helm_plugin:
|
helm_plugin:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
state: present
|
state: present
|
||||||
plugin_path: https://github.com/databus23/helm-diff
|
plugin_path: https://github.com/databus23/helm-diff
|
||||||
|
|
||||||
@@ -136,6 +137,7 @@
|
|||||||
|
|
||||||
- name: Uninstall helm diff
|
- name: Uninstall helm diff
|
||||||
helm_plugin:
|
helm_plugin:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
state: absent
|
state: absent
|
||||||
plugin_name: diff
|
plugin_name: diff
|
||||||
ignore_errors: yes
|
ignore_errors: yes
|
||||||
|
|||||||
@@ -97,6 +97,7 @@
|
|||||||
|
|
||||||
- name: Gather Helm plugin info
|
- name: Gather Helm plugin info
|
||||||
helm_plugin_info:
|
helm_plugin_info:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
register: r
|
register: r
|
||||||
|
|
||||||
- name: Set sample_plugin version
|
- name: Set sample_plugin version
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
---
|
---
|
||||||
- name: "Ensure test_helm_repo doesn't exist"
|
- name: "Ensure test_helm_repo doesn't exist"
|
||||||
helm_repository:
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
name: test_helm_repo
|
name: test_helm_repo
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
- name: Add test_helm_repo chart repository
|
- name: Add test_helm_repo chart repository
|
||||||
helm_repository:
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
name: test_helm_repo
|
name: test_helm_repo
|
||||||
repo_url: "{{ chart_test_repo }}"
|
repo_url: "{{ chart_test_repo }}"
|
||||||
register: repository
|
register: repository
|
||||||
@@ -17,6 +19,7 @@
|
|||||||
|
|
||||||
- name: Check idempotency
|
- name: Check idempotency
|
||||||
helm_repository:
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
name: test_helm_repo
|
name: test_helm_repo
|
||||||
repo_url: "{{ chart_test_repo }}"
|
repo_url: "{{ chart_test_repo }}"
|
||||||
register: repository
|
register: repository
|
||||||
@@ -28,6 +31,7 @@
|
|||||||
|
|
||||||
- name: Failed to add repository with the same name
|
- name: Failed to add repository with the same name
|
||||||
helm_repository:
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
name: test_helm_repo
|
name: test_helm_repo
|
||||||
repo_url: "https://other-charts.url"
|
repo_url: "https://other-charts.url"
|
||||||
register: repository_errors
|
register: repository_errors
|
||||||
@@ -40,6 +44,7 @@
|
|||||||
|
|
||||||
- name: Remove test_helm_repo chart repository
|
- name: Remove test_helm_repo chart repository
|
||||||
helm_repository:
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
name: test_helm_repo
|
name: test_helm_repo
|
||||||
state: absent
|
state: absent
|
||||||
register: repository
|
register: repository
|
||||||
@@ -51,6 +56,7 @@
|
|||||||
|
|
||||||
- name: Check idempotency after remove
|
- name: Check idempotency after remove
|
||||||
helm_repository:
|
helm_repository:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
name: test_helm_repo
|
name: test_helm_repo
|
||||||
state: absent
|
state: absent
|
||||||
register: repository
|
register: repository
|
||||||
|
|||||||
15
molecule/default/roles/k8scopy/defaults/main.yml
Normal file
15
molecule/default/roles/k8scopy/defaults/main.yml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
# defaults file for k8copy
|
||||||
|
copy_namespace: copy
|
||||||
|
|
||||||
|
pod_with_one_container:
|
||||||
|
name: pod-copy-0
|
||||||
|
container: container-00
|
||||||
|
|
||||||
|
pod_with_two_container:
|
||||||
|
name: pod-copy-1
|
||||||
|
container:
|
||||||
|
- container-10
|
||||||
|
- container-11
|
||||||
|
|
||||||
|
kubectl_path: /tmp/kubectl
|
||||||
BIN
molecule/default/roles/k8scopy/files/archive.tar
Normal file
BIN
molecule/default/roles/k8scopy/files/archive.tar
Normal file
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
kubernetes.core
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
k8s_cp
|
||||||
1
molecule/default/roles/k8scopy/files/data/file.txt
Normal file
1
molecule/default/roles/k8scopy/files/data/file.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
This is a simple file used to test k8s_cp module on ansible.
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
cloud team
|
||||||
|
content team
|
||||||
1
molecule/default/roles/k8scopy/files/simple_file.txt
Normal file
1
molecule/default/roles/k8scopy/files/simple_file.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
This content will be copied into remote Pod.
|
||||||
BIN
molecule/default/roles/k8scopy/files/simple_zip_file.txt.gz
Normal file
BIN
molecule/default/roles/k8scopy/files/simple_zip_file.txt.gz
Normal file
Binary file not shown.
91
molecule/default/roles/k8scopy/library/k8s_create_file.py
Normal file
91
molecule/default/roles/k8scopy/library/k8s_create_file.py
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright: (c) 2021, Aubin Bikouo <@abikouo>
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
|
||||||
|
module: k8s_diff
|
||||||
|
|
||||||
|
short_description: Create large file with a defined size.
|
||||||
|
|
||||||
|
author:
|
||||||
|
- Aubin Bikouo (@abikouo)
|
||||||
|
|
||||||
|
description:
|
||||||
|
- This module is used to validate k8s_cp module.
|
||||||
|
|
||||||
|
options:
|
||||||
|
path:
|
||||||
|
description:
|
||||||
|
- The destination path for the file to create.
|
||||||
|
type: path
|
||||||
|
required: yes
|
||||||
|
size:
|
||||||
|
description:
|
||||||
|
- The size of the output file in MB.
|
||||||
|
type: int
|
||||||
|
default: 400
|
||||||
|
binary:
|
||||||
|
description:
|
||||||
|
- If this flag is set to yes, the generated file content binary data.
|
||||||
|
type: bool
|
||||||
|
default: False
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = r'''
|
||||||
|
- name: create 150MB file
|
||||||
|
k8s_diff:
|
||||||
|
path: large_file.txt
|
||||||
|
size: 150
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
RETURN = r'''
|
||||||
|
'''
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils._text import to_native
|
||||||
|
|
||||||
|
|
||||||
|
def execute_module(module):
|
||||||
|
try:
|
||||||
|
size = module.params.get('size') * 1024 * 1024
|
||||||
|
path = module.params.get('path')
|
||||||
|
write_mode = "w"
|
||||||
|
if module.params.get('binary'):
|
||||||
|
content = os.urandom(size)
|
||||||
|
write_mode = "wb"
|
||||||
|
else:
|
||||||
|
content = ""
|
||||||
|
count = 0
|
||||||
|
while len(content) < size:
|
||||||
|
content += "This file has been generated using ansible: {0}\n".format(count)
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
with open(path, write_mode) as f:
|
||||||
|
f.write(content)
|
||||||
|
module.exit_json(changed=True, size=len(content))
|
||||||
|
except Exception as e:
|
||||||
|
module.fail_json(msg="failed to create file due to: {0}".format(to_native(e)))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
argument_spec = {}
|
||||||
|
argument_spec['size'] = {'type': 'int', 'default': 400}
|
||||||
|
argument_spec['path'] = {'type': 'path', 'required': True}
|
||||||
|
argument_spec['binary'] = {'type': 'bool', 'default': False}
|
||||||
|
module = AnsibleModule(argument_spec=argument_spec)
|
||||||
|
|
||||||
|
execute_module(module)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
217
molecule/default/roles/k8scopy/library/kubectl_file_compare.py
Normal file
217
molecule/default/roles/k8scopy/library/kubectl_file_compare.py
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright: (c) 2021, Aubin Bikouo <@abikouo>
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
DOCUMENTATION = r'''
|
||||||
|
|
||||||
|
module: kubectl_file_compare
|
||||||
|
|
||||||
|
short_description: Compare file and directory using kubectl
|
||||||
|
|
||||||
|
author:
|
||||||
|
- Aubin Bikouo (@abikouo)
|
||||||
|
|
||||||
|
description:
|
||||||
|
- This module is used to validate k8s_cp module.
|
||||||
|
- Compare the local file/directory with the remote pod version
|
||||||
|
|
||||||
|
notes:
|
||||||
|
- This module authenticates on kubernetes cluster using default kubeconfig only.
|
||||||
|
|
||||||
|
options:
|
||||||
|
namespace:
|
||||||
|
description:
|
||||||
|
- The pod namespace name
|
||||||
|
type: str
|
||||||
|
required: yes
|
||||||
|
pod:
|
||||||
|
description:
|
||||||
|
- The pod name
|
||||||
|
type: str
|
||||||
|
required: yes
|
||||||
|
container:
|
||||||
|
description:
|
||||||
|
- The container to retrieve files from.
|
||||||
|
type: str
|
||||||
|
remote_path:
|
||||||
|
description:
|
||||||
|
- Path of the file or directory on Pod.
|
||||||
|
type: path
|
||||||
|
required: yes
|
||||||
|
local_path:
|
||||||
|
description:
|
||||||
|
- Path of the local file or directory.
|
||||||
|
type: path
|
||||||
|
content:
|
||||||
|
description:
|
||||||
|
- local content to compare with remote file from pod.
|
||||||
|
- mutually exclusive with option I(local_path).
|
||||||
|
type: path
|
||||||
|
required: yes
|
||||||
|
args:
|
||||||
|
description:
|
||||||
|
- The file is considered to be an executable.
|
||||||
|
- The tool will be run locally and on pod and compare result from output and stderr.
|
||||||
|
type: list
|
||||||
|
kubectl_path:
|
||||||
|
description:
|
||||||
|
- Path to the kubectl executable, if not specified it will be download.
|
||||||
|
type: path
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = r'''
|
||||||
|
- name: compare local /tmp/foo with /tmp/bar in a remote pod
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: some-namespace
|
||||||
|
pod: some-pod
|
||||||
|
remote_path: /tmp/bar
|
||||||
|
local_path: /tmp/foo
|
||||||
|
kubectl_path: /tmp/test/kubectl
|
||||||
|
|
||||||
|
- name: Compare executable running help command
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: some-namespace
|
||||||
|
pod: some-pod
|
||||||
|
remote_path: /tmp/test/kubectl
|
||||||
|
local_path: kubectl
|
||||||
|
kubectl_path: /tmp/test/kubectl
|
||||||
|
args:
|
||||||
|
- "--help"
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
RETURN = r'''
|
||||||
|
'''
|
||||||
|
|
||||||
|
import os
|
||||||
|
import filecmp
|
||||||
|
|
||||||
|
from tempfile import NamedTemporaryFile, TemporaryDirectory
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
|
||||||
|
|
||||||
|
def kubectl_get_content(module, dest_dir):
|
||||||
|
kubectl_path = module.params.get('kubectl_path')
|
||||||
|
if kubectl_path is None:
|
||||||
|
kubectl_path = module.get_bin_path('kubectl', required=True)
|
||||||
|
|
||||||
|
namespace = module.params.get('namespace')
|
||||||
|
pod = module.params.get('pod')
|
||||||
|
file = module.params.get('remote_path')
|
||||||
|
|
||||||
|
cmd = [
|
||||||
|
kubectl_path,
|
||||||
|
'cp',
|
||||||
|
"{0}/{1}:{2}".format(namespace, pod, file)
|
||||||
|
]
|
||||||
|
container = module.params.get('container')
|
||||||
|
if container:
|
||||||
|
cmd += ['-c', container]
|
||||||
|
local_file = os.path.join(dest_dir, os.path.basename(module.params.get('remote_path')))
|
||||||
|
cmd.append(local_file)
|
||||||
|
rc, out, err = module.run_command(cmd)
|
||||||
|
return local_file, err, rc, out
|
||||||
|
|
||||||
|
|
||||||
|
def kubectl_run_from_pod(module):
|
||||||
|
kubectl_path = module.params.get('kubectl_path')
|
||||||
|
if kubectl_path is None:
|
||||||
|
kubectl_path = module.get_bin_path('kubectl', required=True)
|
||||||
|
|
||||||
|
cmd = [
|
||||||
|
kubectl_path,
|
||||||
|
'exec',
|
||||||
|
module.params.get('pod'),
|
||||||
|
'-n',
|
||||||
|
module.params.get('namespace')
|
||||||
|
]
|
||||||
|
container = module.params.get('container')
|
||||||
|
if container:
|
||||||
|
cmd += ['-c', container]
|
||||||
|
cmd += ['--', module.params.get('remote_path')]
|
||||||
|
cmd += module.params.get('args')
|
||||||
|
return module.run_command(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
def compare_directories(dir1, dir2):
|
||||||
|
test = filecmp.dircmp(dir1, dir2)
|
||||||
|
if any([len(test.left_only) > 0, len(test.right_only) > 0, len(test.funny_files) > 0]):
|
||||||
|
return False
|
||||||
|
(t, mismatch, errors) = filecmp.cmpfiles(dir1, dir2, test.common_files, shallow=False)
|
||||||
|
if len(mismatch) > 0 or len(errors) > 0:
|
||||||
|
return False
|
||||||
|
for common_dir in test.common_dirs:
|
||||||
|
new_dir1 = os.path.join(dir1, common_dir)
|
||||||
|
new_dir2 = os.path.join(dir2, common_dir)
|
||||||
|
if not compare_directories(new_dir1, new_dir2):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def execute_module(module):
|
||||||
|
|
||||||
|
args = module.params.get('args')
|
||||||
|
local_path = module.params.get('local_path')
|
||||||
|
namespace = module.params.get('namespace')
|
||||||
|
pod = module.params.get('pod')
|
||||||
|
file = module.params.get('remote_path')
|
||||||
|
content = module.params.get('content')
|
||||||
|
if args:
|
||||||
|
pod_rc, pod_out, pod_err = kubectl_run_from_pod(module)
|
||||||
|
rc, out, err = module.run_command([module.params.get('local_path')] + args)
|
||||||
|
if rc == pod_rc and out == pod_out:
|
||||||
|
module.exit_json(msg="{0} and {1}/{2}:{3} are same.".format(
|
||||||
|
local_path, namespace, pod, file
|
||||||
|
), rc=rc, stderr=err, stdout=out)
|
||||||
|
result = dict(local=dict(rc=rc, out=out, err=err), remote=dict(rc=pod_rc, out=pod_out, err=pod_err))
|
||||||
|
module.fail_json(msg=f"{local_path} and {namespace}/{pod}:{file} are same.", **result)
|
||||||
|
else:
|
||||||
|
with TemporaryDirectory() as tmpdirname:
|
||||||
|
file_from_pod, err, rc, out = kubectl_get_content(module=module, dest_dir=tmpdirname)
|
||||||
|
if not os.path.exists(file_from_pod):
|
||||||
|
module.fail_json(msg="failed to copy content from pod", error=err, output=out)
|
||||||
|
|
||||||
|
if content is not None:
|
||||||
|
with NamedTemporaryFile(mode="w") as tmp_file:
|
||||||
|
tmp_file.write(content)
|
||||||
|
tmp_file.flush()
|
||||||
|
if filecmp.cmp(file_from_pod, tmp_file.name):
|
||||||
|
module.exit_json(msg=f"defined content and {namespace}/{pod}:{file} are same.")
|
||||||
|
module.fail_json(msg=f"defined content and {namespace}/{pod}:{file} are same.")
|
||||||
|
|
||||||
|
if os.path.isfile(local_path):
|
||||||
|
if filecmp.cmp(file_from_pod, local_path):
|
||||||
|
module.exit_json(msg=f"{local_path} and {namespace}/{pod}:{file} are same.")
|
||||||
|
module.fail_json(msg=f"{local_path} and {namespace}/{pod}:{file} are same.")
|
||||||
|
|
||||||
|
if os.path.isdir(local_path):
|
||||||
|
if compare_directories(file_from_pod, local_path):
|
||||||
|
module.exit_json(msg=f"{local_path} and {namespace}/{pod}:{file} are same.")
|
||||||
|
module.fail_json(msg=f"{local_path} and {namespace}/{pod}:{file} are same.")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
argument_spec = {}
|
||||||
|
argument_spec['namespace'] = {'type': 'str', 'required': True}
|
||||||
|
argument_spec['pod'] = {'type': 'str', 'required': True}
|
||||||
|
argument_spec['container'] = {}
|
||||||
|
argument_spec['remote_path'] = {'type': 'path', 'required': True}
|
||||||
|
argument_spec['local_path'] = {'type': 'path'}
|
||||||
|
argument_spec['content'] = {'type': 'str'}
|
||||||
|
argument_spec['kubectl_path'] = {'type': 'path'}
|
||||||
|
argument_spec['args'] = {'type': 'list'}
|
||||||
|
module = AnsibleModule(argument_spec=argument_spec,
|
||||||
|
mutually_exclusive=[('local_path', 'content')],
|
||||||
|
required_one_of=[['local_path', 'content']])
|
||||||
|
|
||||||
|
execute_module(module)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
3
molecule/default/roles/k8scopy/meta/main.yml
Normal file
3
molecule/default/roles/k8scopy/meta/main.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
collections:
|
||||||
|
- kubernetes.core
|
||||||
46
molecule/default/roles/k8scopy/tasks/main.yml
Normal file
46
molecule/default/roles/k8scopy/tasks/main.yml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
- block:
|
||||||
|
- name: Download kubeclt executable used to compare results
|
||||||
|
get_url:
|
||||||
|
url: https://dl.k8s.io/release/v1.21.3/bin/linux/amd64/kubectl
|
||||||
|
dest: "{{ kubectl_path }}"
|
||||||
|
|
||||||
|
- name: make kubectl executable
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ kubectl_path }}"
|
||||||
|
mode: "+x"
|
||||||
|
|
||||||
|
# Ensure namespace and create pod to perform tests on
|
||||||
|
- name: Ensure namespace exists
|
||||||
|
k8s:
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: "{{ copy_namespace }}"
|
||||||
|
|
||||||
|
- name: Create Pods
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
wait: yes
|
||||||
|
template: pods_definition.j2
|
||||||
|
|
||||||
|
- include_tasks: test_copy_errors.yml
|
||||||
|
- include_tasks: test_copy_file.yml
|
||||||
|
- include_tasks: test_multi_container_pod.yml
|
||||||
|
- include_tasks: test_copy_directory.yml
|
||||||
|
- include_tasks: test_copy_large_file.yml
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Remove kubectl executable
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ kubectl_path }}"
|
||||||
|
state: absent
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Remove namespace
|
||||||
|
k8s:
|
||||||
|
kind: Namespace
|
||||||
|
name: "{{ copy_namespace }}"
|
||||||
|
state: absent
|
||||||
|
ignore_errors: true
|
||||||
85
molecule/default/roles/k8scopy/tasks/test_copy_directory.yml
Normal file
85
molecule/default/roles/k8scopy/tasks/test_copy_directory.yml
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
---
|
||||||
|
- block:
|
||||||
|
- name: copy directory into remote Pod (create new directory)
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /dest_data
|
||||||
|
local_path: files/data
|
||||||
|
state: to_pod
|
||||||
|
|
||||||
|
- name: compare directories
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /dest_data
|
||||||
|
local_path: '{{ role_path }}/files/data'
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
|
||||||
|
- name: copy directory into remote Pod (existing directory)
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp
|
||||||
|
local_path: files/data
|
||||||
|
state: to_pod
|
||||||
|
|
||||||
|
- name: compare directories
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/data
|
||||||
|
local_path: '{{ role_path }}/files/data'
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
|
||||||
|
- name: copy directory from Pod into local filesystem (new directory to create)
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/data
|
||||||
|
local_path: /tmp/test
|
||||||
|
state: from_pod
|
||||||
|
|
||||||
|
- name: compare directories
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/data
|
||||||
|
local_path: /tmp/test
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
|
||||||
|
- name: copy directory from Pod into local filesystem (existing directory)
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/data
|
||||||
|
local_path: /tmp
|
||||||
|
state: from_pod
|
||||||
|
|
||||||
|
- name: compare directories
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/data
|
||||||
|
local_path: /tmp/data
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Remove directories created into remote Pod
|
||||||
|
k8s_exec:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
command: 'rm -rf {{ item }}'
|
||||||
|
ignore_errors: true
|
||||||
|
with_items:
|
||||||
|
- /dest_data
|
||||||
|
- /tmp/data
|
||||||
|
|
||||||
|
- name: Remove local directories
|
||||||
|
file:
|
||||||
|
path: '{{ item }}'
|
||||||
|
state: absent
|
||||||
|
ignore_errors: true
|
||||||
|
with_items:
|
||||||
|
- /tmp/data
|
||||||
|
- /tmp/test
|
||||||
69
molecule/default/roles/k8scopy/tasks/test_copy_errors.yml
Normal file
69
molecule/default/roles/k8scopy/tasks/test_copy_errors.yml
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
---
|
||||||
|
# copy non-existent local file should fail
|
||||||
|
- name: copy non-existent file into remote Pod
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp
|
||||||
|
local_path: this_file_does_not_exist
|
||||||
|
state: to_pod
|
||||||
|
ignore_errors: true
|
||||||
|
register: copy_non_existent
|
||||||
|
|
||||||
|
- name: check that error message is as expected
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- copy_non_existent is failed
|
||||||
|
- copy_non_existent.msg == "this_file_does_not_exist does not exist in local filesystem"
|
||||||
|
|
||||||
|
# copy non-existent pod file should fail
|
||||||
|
- name: copy of non-existent file from remote pod should fail
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /this_file_does_not_exist
|
||||||
|
local_path: /tmp
|
||||||
|
state: from_pod
|
||||||
|
ignore_errors: true
|
||||||
|
register: copy_non_existent
|
||||||
|
|
||||||
|
- name: check that error message is as expected
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- copy_non_existent is failed
|
||||||
|
- copy_non_existent.msg == "/this_file_does_not_exist does not exist in remote pod filesystem"
|
||||||
|
|
||||||
|
# copy file into multiple container pod without specifying the container should fail
|
||||||
|
- name: copy file into multiple container pod
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_two_container.name }}'
|
||||||
|
remote_path: /tmp
|
||||||
|
local_path: files/simple_file.txt
|
||||||
|
state: to_pod
|
||||||
|
ignore_errors: true
|
||||||
|
register: copy_multi_container
|
||||||
|
|
||||||
|
- name: check that error message is as expected
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- copy_multi_container is failed
|
||||||
|
- copy_multi_container.msg == "Pod contains more than 1 container, option 'container' should be set"
|
||||||
|
|
||||||
|
# copy using non-existent container from pod should failed
|
||||||
|
- name: copy file into multiple container pod
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_two_container.name }}'
|
||||||
|
remote_path: /tmp
|
||||||
|
local_path: files/simple_file.txt
|
||||||
|
state: to_pod
|
||||||
|
container: this_is_a_fake_container
|
||||||
|
ignore_errors: true
|
||||||
|
register: copy_fake_container
|
||||||
|
|
||||||
|
- name: check that error message is as expected
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- copy_fake_container is failed
|
||||||
|
- copy_fake_container.msg == "Pod has no container this_is_a_fake_container"
|
||||||
206
molecule/default/roles/k8scopy/tasks/test_copy_file.yml
Normal file
206
molecule/default/roles/k8scopy/tasks/test_copy_file.yml
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
---
|
||||||
|
- block:
|
||||||
|
# Text file
|
||||||
|
- name: copy text file into remote pod
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp
|
||||||
|
local_path: files/simple_file.txt
|
||||||
|
state: to_pod
|
||||||
|
|
||||||
|
- name: Compare files
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/simple_file.txt
|
||||||
|
content: "{{ lookup('file', 'simple_file.txt')}}"
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
|
||||||
|
- name: Copy simple text file from Pod
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/simple_file.txt
|
||||||
|
local_path: /tmp/copy_from_pod.txt
|
||||||
|
state: from_pod
|
||||||
|
|
||||||
|
- name: Compare files
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/simple_file.txt
|
||||||
|
local_path: /tmp/copy_from_pod.txt
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
|
||||||
|
# Binary file
|
||||||
|
|
||||||
|
- name: Create temp binary file
|
||||||
|
tempfile:
|
||||||
|
state: file
|
||||||
|
register: binfile
|
||||||
|
|
||||||
|
- name: Generate random binary content
|
||||||
|
command: dd if=/dev/urandom of={{ binfile.path }} bs=1M count=1
|
||||||
|
|
||||||
|
- name: Copy executable into Pod
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/hello.exe
|
||||||
|
local_path: "{{ binfile.path }}"
|
||||||
|
state: to_pod
|
||||||
|
|
||||||
|
- name: Get remote hash
|
||||||
|
kubernetes.core.k8s_exec:
|
||||||
|
namespace: "{{ copy_namespace }}"
|
||||||
|
pod: "{{ pod_with_one_container.name }}"
|
||||||
|
command: sha256sum -b /tmp/hello.exe
|
||||||
|
register: remote_hash
|
||||||
|
|
||||||
|
- name: Get local hash
|
||||||
|
command: sha256sum -b {{ binfile.path }}
|
||||||
|
register: local_hash
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- remote_hash.stdout.split()[0] == local_hash.stdout.split()[0]
|
||||||
|
|
||||||
|
- name: Generate tempfile
|
||||||
|
tempfile:
|
||||||
|
state: file
|
||||||
|
register: binfile
|
||||||
|
|
||||||
|
- name: Copy executable from Pod
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/hello.exe
|
||||||
|
local_path: "{{ binfile.path }}"
|
||||||
|
state: from_pod
|
||||||
|
|
||||||
|
- name: Get remote hash
|
||||||
|
kubernetes.core.k8s_exec:
|
||||||
|
namespace: "{{ copy_namespace }}"
|
||||||
|
pod: "{{ pod_with_one_container.name }}"
|
||||||
|
command: sha256sum -b /tmp/hello.exe
|
||||||
|
register: remote_hash
|
||||||
|
|
||||||
|
- name: Get local hash
|
||||||
|
command: sha256sum -b {{ binfile.path }}
|
||||||
|
register: local_hash
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- remote_hash.stdout.split()[0] == local_hash.stdout.split()[0]
|
||||||
|
|
||||||
|
# zip files
|
||||||
|
- name: copy zip file into remote pod
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp
|
||||||
|
local_path: files/simple_zip_file.txt.gz
|
||||||
|
state: to_pod
|
||||||
|
|
||||||
|
- name: compare zip files
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/simple_zip_file.txt.gz
|
||||||
|
local_path: '{{ role_path }}/files/simple_zip_file.txt.gz'
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
|
||||||
|
- name: copy zip file from pod into local filesystem
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/simple_zip_file.txt.gz
|
||||||
|
local_path: /tmp/copied_from_pod.txt.gz
|
||||||
|
state: from_pod
|
||||||
|
|
||||||
|
- name: compare zip files
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/simple_zip_file.txt.gz
|
||||||
|
local_path: /tmp/copied_from_pod.txt.gz
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
|
||||||
|
# tar files
|
||||||
|
- name: copy archive into remote pod
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp
|
||||||
|
local_path: files/archive.tar
|
||||||
|
state: to_pod
|
||||||
|
|
||||||
|
- name: compare archive
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/archive.tar
|
||||||
|
local_path: '{{ role_path }}/files/archive.tar'
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
|
||||||
|
- name: copy archive from remote pod into local filesystem
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/archive.tar
|
||||||
|
local_path: /tmp/local_archive.tar
|
||||||
|
state: from_pod
|
||||||
|
|
||||||
|
- name: compare archive
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /tmp/archive.tar
|
||||||
|
local_path: /tmp/local_archive.tar
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
|
||||||
|
# Copy into Pod using content option
|
||||||
|
- name: set content to be copied into Pod
|
||||||
|
set_fact:
|
||||||
|
pod_content: "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits,punctuation length=128') }}"
|
||||||
|
|
||||||
|
- name: copy archive into remote pod
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /this_content.txt
|
||||||
|
content: '{{ pod_content }}'
|
||||||
|
state: to_pod
|
||||||
|
|
||||||
|
- name: Assert that content is as expected into Pod
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /this_content.txt
|
||||||
|
content: '{{ pod_content }}'
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Delete file created on Pod
|
||||||
|
k8s_exec:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
command: 'rm {{ item }}'
|
||||||
|
ignore_errors: true
|
||||||
|
with_items:
|
||||||
|
- /tmp/simple_file.txt
|
||||||
|
- /tmp/hello.exe
|
||||||
|
- /tmp/simple_zip_file.txt.gz
|
||||||
|
- /tmp/archive.tar
|
||||||
|
- /this_content.txt
|
||||||
|
|
||||||
|
- name: Delete file created locally
|
||||||
|
file:
|
||||||
|
path: '{{ item }}'
|
||||||
|
state: absent
|
||||||
|
with_items:
|
||||||
|
- /tmp/copy_from_pod.txt
|
||||||
|
- /tmp/hello
|
||||||
|
- /tmp/copied_from_pod.txt.gz
|
||||||
|
- /tmp/local_archive.tar
|
||||||
103
molecule/default/roles/k8scopy/tasks/test_copy_large_file.yml
Normal file
103
molecule/default/roles/k8scopy/tasks/test_copy_large_file.yml
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
---
|
||||||
|
- name: test copy of large binary and text files
|
||||||
|
block:
|
||||||
|
- set_fact:
|
||||||
|
test_directory: "/tmp/test_k8scp_large_files"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: create temporary directory for local files
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ test_directory }}"
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: create large text file
|
||||||
|
k8s_create_file:
|
||||||
|
path: "{{ test_directory }}/large_text_file.txt"
|
||||||
|
size: 150
|
||||||
|
|
||||||
|
- name: create large binary file
|
||||||
|
k8s_create_file:
|
||||||
|
path: "{{ test_directory }}/large_bin_file.bin"
|
||||||
|
size: 200
|
||||||
|
binary: true
|
||||||
|
|
||||||
|
# Copy large text file from/to local filesystem to Pod
|
||||||
|
- name: copy large file into remote Pod
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /large_text_file.txt
|
||||||
|
local_path: "{{ test_directory }}/large_text_file.txt"
|
||||||
|
state: to_pod
|
||||||
|
|
||||||
|
- name: Compare files
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /large_text_file.txt
|
||||||
|
local_path: "{{ test_directory }}/large_text_file.txt"
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
|
||||||
|
- name: copy large file from Pod into local filesystem
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /large_text_file.txt
|
||||||
|
local_path: "{{ test_directory }}/large_text_file_from_pod.txt"
|
||||||
|
state: from_pod
|
||||||
|
|
||||||
|
- name: Compare files
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /large_text_file.txt
|
||||||
|
local_path: "{{ test_directory }}/large_text_file_from_pod.txt"
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
|
||||||
|
# Copy large binary file from/to local filesystem to Pod
|
||||||
|
- name: copy large file into remote Pod
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /large_bin_file.bin
|
||||||
|
local_path: "{{ test_directory }}/large_bin_file.bin"
|
||||||
|
state: to_pod
|
||||||
|
|
||||||
|
- name: Compare executable, local vs remote
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /large_bin_file.bin
|
||||||
|
local_path: "{{ test_directory }}/large_bin_file.bin"
|
||||||
|
|
||||||
|
- name: copy executable from pod into local filesystem
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /large_bin_file.bin
|
||||||
|
local_path: "{{ test_directory }}/large_bin_file_from_pod.bin"
|
||||||
|
state: from_pod
|
||||||
|
|
||||||
|
- name: Compare executable, local vs remote
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
remote_path: /large_bin_file.bin
|
||||||
|
local_path: "{{ test_directory }}/large_bin_file_from_pod.bin"
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Delete temporary directory created for the test
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ test_directory }}"
|
||||||
|
state: absent
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Delete file created on Pod
|
||||||
|
k8s_exec:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_one_container.name }}'
|
||||||
|
command: 'rm {{ item }}'
|
||||||
|
ignore_errors: true
|
||||||
|
with_items:
|
||||||
|
- /large_text_file.txt
|
||||||
|
- /large_bin_file.bin
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
---
|
||||||
|
- set_fact:
|
||||||
|
random_content: "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits,punctuation length=128') }}"
|
||||||
|
|
||||||
|
- name: Copy content into first pod's container
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_two_container.name }}'
|
||||||
|
remote_path: /file_from_localhost.txt
|
||||||
|
content: '{{ random_content }}'
|
||||||
|
container: '{{ pod_with_two_container.container[0] }}'
|
||||||
|
state: to_pod
|
||||||
|
|
||||||
|
- name: Assert that content has been copied into first container
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_two_container.name }}'
|
||||||
|
remote_path: /file_from_localhost.txt
|
||||||
|
container: '{{ pod_with_two_container.container[0] }}'
|
||||||
|
content: '{{ random_content }}'
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
|
||||||
|
- name: Assert that content has not been copied into second container
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_two_container.name }}'
|
||||||
|
remote_path: /file_from_localhost.txt
|
||||||
|
container: '{{ pod_with_two_container.container[1] }}'
|
||||||
|
content: '{{ random_content }}'
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
register: diff
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: check that diff failed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- diff is failed
|
||||||
|
|
||||||
|
- name: Copy content into second's pod container
|
||||||
|
k8s_cp:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_two_container.name }}'
|
||||||
|
remote_path: /file_from_localhost_01.txt
|
||||||
|
content: '{{ random_content }}-secondpod'
|
||||||
|
container: '{{ pod_with_two_container.container[1] }}'
|
||||||
|
state: to_pod
|
||||||
|
|
||||||
|
- name: Assert that content has not been copied into first container
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_two_container.name }}'
|
||||||
|
remote_path: /file_from_localhost_01.txt
|
||||||
|
container: '{{ pod_with_two_container.container[0] }}'
|
||||||
|
content: '{{ random_content }}-secondpod'
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
|
ignore_errors: true
|
||||||
|
register: diff_1
|
||||||
|
|
||||||
|
- name: check that diff failed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- diff_1 is failed
|
||||||
|
|
||||||
|
- name: Assert that content has been copied into second container
|
||||||
|
kubectl_file_compare:
|
||||||
|
namespace: '{{ copy_namespace }}'
|
||||||
|
pod: '{{ pod_with_two_container.name }}'
|
||||||
|
remote_path: /file_from_localhost_01.txt
|
||||||
|
container: '{{ pod_with_two_container.container[1] }}'
|
||||||
|
content: '{{ random_content }}-secondpod'
|
||||||
|
kubectl_path: "{{ kubectl_path }}"
|
||||||
33
molecule/default/roles/k8scopy/templates/pods_definition.j2
Normal file
33
molecule/default/roles/k8scopy/templates/pods_definition.j2
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ pod_with_one_container.name }}'
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: '{{ pod_with_one_container.container }}'
|
||||||
|
image: busybox
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ pod_with_two_container.name }}'
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: '{{ pod_with_two_container.container[0] }}'
|
||||||
|
image: busybox:1.32.0
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
- name: '{{ pod_with_two_container.container[1] }}'
|
||||||
|
image: busybox:1.33.0
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
|
||||||
@@ -836,6 +836,66 @@
|
|||||||
that:
|
that:
|
||||||
- k8s_secret is not changed
|
- k8s_secret is not changed
|
||||||
|
|
||||||
|
- name: Create network policy (egress array with empty dict)
|
||||||
|
k8s:
|
||||||
|
namespace: "{{ apply_namespace }}"
|
||||||
|
apply: true
|
||||||
|
definition:
|
||||||
|
kind: NetworkPolicy
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: apply-netpolicy
|
||||||
|
labels:
|
||||||
|
app: apply-netpolicy
|
||||||
|
annotations:
|
||||||
|
{}
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: apply-netpolicy
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- ports:
|
||||||
|
- port: 9093
|
||||||
|
protocol: TCP
|
||||||
|
egress:
|
||||||
|
- {}
|
||||||
|
|
||||||
|
- name: Apply network policy
|
||||||
|
k8s:
|
||||||
|
namespace: "{{ apply_namespace }}"
|
||||||
|
definition:
|
||||||
|
kind: NetworkPolicy
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: apply-netpolicy
|
||||||
|
labels:
|
||||||
|
app: apply-netpolicy
|
||||||
|
annotations:
|
||||||
|
{}
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: apply-netpolicy
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
- ports:
|
||||||
|
- port: 9093
|
||||||
|
protocol: TCP
|
||||||
|
egress:
|
||||||
|
- {}
|
||||||
|
apply: true
|
||||||
|
register: k8s_networkpolicy
|
||||||
|
|
||||||
|
- name: Check that nothing changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- k8s_networkpolicy is not changed
|
||||||
|
|
||||||
always:
|
always:
|
||||||
- name: Remove namespace
|
- name: Remove namespace
|
||||||
k8s:
|
k8s:
|
||||||
|
|||||||
153
molecule/default/tasks/diff.yml
Normal file
153
molecule/default/tasks/diff.yml
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
---
|
||||||
|
- set_fact:
|
||||||
|
diff_namespace: "diff"
|
||||||
|
diff_configmap: "diff-configmap"
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: Ensure namespace
|
||||||
|
k8s:
|
||||||
|
kind: Namespace
|
||||||
|
name: '{{ diff_namespace }}'
|
||||||
|
|
||||||
|
# Using option 'apply' set to 'yes'
|
||||||
|
- name: Create Pod using apply and diff set to yes
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ diff_namespace }}'
|
||||||
|
apply: yes
|
||||||
|
template: "pod_diff.j2"
|
||||||
|
diff: yes
|
||||||
|
vars:
|
||||||
|
pod_name: "pod-apply"
|
||||||
|
pod_image: "busybox:1.32.0"
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check that result has diff attribute
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
- result.diff is defined
|
||||||
|
|
||||||
|
- name: Update pod definition using apply and diff set to no
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ diff_namespace }}'
|
||||||
|
apply: yes
|
||||||
|
template: "pod_diff.j2"
|
||||||
|
diff: no
|
||||||
|
vars:
|
||||||
|
pod_name: "pod-apply"
|
||||||
|
pod_image: "busybox:1.33.0"
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check that output has no diff attribute
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
- result.diff is not defined
|
||||||
|
|
||||||
|
# Using option 'state=patched'
|
||||||
|
- name: Create Pod using state=present and diff set to yes
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ diff_namespace }}'
|
||||||
|
state: present
|
||||||
|
template: "pod_diff.j2"
|
||||||
|
vars:
|
||||||
|
pod_name: "pod-patch"
|
||||||
|
pod_image: "busybox:1.32.0"
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Update pod definition using state=patched
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ diff_namespace }}'
|
||||||
|
state: patched
|
||||||
|
template: "pod_diff.j2"
|
||||||
|
diff: no
|
||||||
|
vars:
|
||||||
|
pod_name: "pod-patch"
|
||||||
|
pod_image: "busybox:1.33.0"
|
||||||
|
pod_label: "patching"
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check that output has no diff attribute
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
- result.diff is not defined
|
||||||
|
|
||||||
|
- name: Update pod definition using state=patched and diff=yes
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ diff_namespace }}'
|
||||||
|
state: patched
|
||||||
|
template: "pod_diff.j2"
|
||||||
|
diff: yes
|
||||||
|
vars:
|
||||||
|
pod_name: "pod-patch"
|
||||||
|
pod_image: "busybox:1.33.0"
|
||||||
|
pod_label: "running"
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check that output has no diff attribute
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
- result.diff is defined
|
||||||
|
|
||||||
|
# check diff mode using force=yes
|
||||||
|
- name: Create a ConfigMap
|
||||||
|
k8s:
|
||||||
|
kind: ConfigMap
|
||||||
|
name: '{{ diff_configmap }}'
|
||||||
|
namespace: '{{ diff_namespace }}'
|
||||||
|
definition:
|
||||||
|
data:
|
||||||
|
key: "initial value"
|
||||||
|
diff: yes
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check that output has no diff attribute
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
- result.diff is not defined
|
||||||
|
|
||||||
|
- name: Update ConfigMap using force and diff=no
|
||||||
|
k8s:
|
||||||
|
kind: ConfigMap
|
||||||
|
name: '{{ diff_configmap }}'
|
||||||
|
namespace: '{{ diff_namespace }}'
|
||||||
|
force: yes
|
||||||
|
definition:
|
||||||
|
data:
|
||||||
|
key: "update value with diff=no"
|
||||||
|
diff: no
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check that output has no diff attribute
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
- result.diff is not defined
|
||||||
|
|
||||||
|
- name: Update ConfigMap using force and diff=yes
|
||||||
|
k8s:
|
||||||
|
kind: ConfigMap
|
||||||
|
name: '{{ diff_configmap }}'
|
||||||
|
namespace: '{{ diff_namespace }}'
|
||||||
|
force: yes
|
||||||
|
definition:
|
||||||
|
data:
|
||||||
|
key: "update value with diff=yes"
|
||||||
|
diff: yes
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check that output has diff attribute
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
- result.diff is defined
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Ensure namespace is deleted
|
||||||
|
k8s:
|
||||||
|
state: absent
|
||||||
|
kind: Namespace
|
||||||
|
name: '{{ diff_namespace }}'
|
||||||
238
molecule/default/tasks/drain.yml
Normal file
238
molecule/default/tasks/drain.yml
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
---
|
||||||
|
- block:
|
||||||
|
- name: Set common facts
|
||||||
|
set_fact:
|
||||||
|
drain_namespace: "drain"
|
||||||
|
drain_daemonset_name: "promotheus-dset"
|
||||||
|
drain_pod_name: "pod-drain"
|
||||||
|
|
||||||
|
- name: Create {{ drain_namespace }} namespace
|
||||||
|
k8s:
|
||||||
|
kind: Namespace
|
||||||
|
name: '{{ drain_namespace }}'
|
||||||
|
|
||||||
|
# It seems that the default ServiceAccount can take a bit to be created
|
||||||
|
# right after a cluster is brought up. This can lead to the ServiceAccount
|
||||||
|
# admission controller rejecting a Pod creation request because the
|
||||||
|
# ServiceAccount does not yet exist.
|
||||||
|
- name: Wait for default serviceaccount to be created
|
||||||
|
k8s_info:
|
||||||
|
kind: ServiceAccount
|
||||||
|
name: default
|
||||||
|
namespace: "{{ drain_namespace }}"
|
||||||
|
wait: yes
|
||||||
|
|
||||||
|
- name: list cluster nodes
|
||||||
|
k8s_info:
|
||||||
|
kind: node
|
||||||
|
register: nodes
|
||||||
|
|
||||||
|
- name: Select uncordoned nodes
|
||||||
|
set_fact:
|
||||||
|
uncordoned_nodes: "{{ nodes.resources | selectattr('spec.unschedulable', 'undefined') | map(attribute='metadata.name') | list}}"
|
||||||
|
|
||||||
|
- name: Assert that at least one node is schedulable
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- uncordoned_nodes | length > 0
|
||||||
|
|
||||||
|
- name: select node to drain
|
||||||
|
set_fact:
|
||||||
|
node_to_drain: '{{ uncordoned_nodes[0] }}'
|
||||||
|
|
||||||
|
- name: Deploy daemonset on cluster
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ drain_namespace }}'
|
||||||
|
definition:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: DaemonSet
|
||||||
|
metadata:
|
||||||
|
name: '{{ drain_daemonset_name }}'
|
||||||
|
spec:
|
||||||
|
affinity:
|
||||||
|
nodeAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
nodeSelectorTerms:
|
||||||
|
- matchFields:
|
||||||
|
- key: metadata.name
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- '{{ node_to_drain }}'
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
name: prometheus-exporter
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
name: prometheus-exporter
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: prometheus
|
||||||
|
image: prom/node-exporter
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
|
||||||
|
- name: Create Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet.
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ drain_namespace }}'
|
||||||
|
wait: yes
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ drain_pod_name }}'
|
||||||
|
spec:
|
||||||
|
affinity:
|
||||||
|
nodeAffinity:
|
||||||
|
requiredDuringSchedulingIgnoredDuringExecution:
|
||||||
|
nodeSelectorTerms:
|
||||||
|
- matchFields:
|
||||||
|
- key: metadata.name
|
||||||
|
operator: In
|
||||||
|
values:
|
||||||
|
- '{{ node_to_drain }}'
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
|
||||||
|
- name: Cordon node
|
||||||
|
k8s_drain:
|
||||||
|
state: cordon
|
||||||
|
name: '{{ node_to_drain }}'
|
||||||
|
register: cordon
|
||||||
|
|
||||||
|
- name: assert that cordon is changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- cordon is changed
|
||||||
|
|
||||||
|
- name: Test cordon idempotency
|
||||||
|
k8s_drain:
|
||||||
|
state: cordon
|
||||||
|
name: '{{ node_to_drain }}'
|
||||||
|
register: cordon
|
||||||
|
|
||||||
|
- name: assert that cordon is not changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- cordon is not changed
|
||||||
|
|
||||||
|
- name: Get pods
|
||||||
|
k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
namespace: '{{ drain_namespace }}'
|
||||||
|
register: Pod
|
||||||
|
|
||||||
|
- 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 }}"
|
||||||
|
|
||||||
|
- name: Uncordon node
|
||||||
|
k8s_drain:
|
||||||
|
state: uncordon
|
||||||
|
name: '{{ node_to_drain }}'
|
||||||
|
register: uncordon
|
||||||
|
|
||||||
|
- name: assert that uncordon is changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- uncordon is changed
|
||||||
|
|
||||||
|
- name: Test uncordon idempotency
|
||||||
|
k8s_drain:
|
||||||
|
state: uncordon
|
||||||
|
name: '{{ node_to_drain }}'
|
||||||
|
register: uncordon
|
||||||
|
|
||||||
|
- name: assert that uncordon is not changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- uncordon is not changed
|
||||||
|
|
||||||
|
- name: Drain node
|
||||||
|
k8s_drain:
|
||||||
|
state: drain
|
||||||
|
name: '{{ node_to_drain }}'
|
||||||
|
ignore_errors: true
|
||||||
|
register: drain_result
|
||||||
|
|
||||||
|
- name: assert that drain failed due to DaemonSet managed Pods
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- drain_result is failed
|
||||||
|
- '"cannot delete DaemonSet-managed Pods" in drain_result.msg'
|
||||||
|
- '"cannot delete Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet" in drain_result.msg'
|
||||||
|
|
||||||
|
- name: Drain node using ignore_daemonsets and force options
|
||||||
|
k8s_drain:
|
||||||
|
state: drain
|
||||||
|
name: '{{ node_to_drain }}'
|
||||||
|
delete_options:
|
||||||
|
force: true
|
||||||
|
ignore_daemonsets: true
|
||||||
|
wait_timeout: 0
|
||||||
|
register: drain_result
|
||||||
|
|
||||||
|
- name: assert that node has been drained
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- drain_result is changed
|
||||||
|
- '"node {{ node_to_drain }} marked unschedulable." in drain_result.result'
|
||||||
|
|
||||||
|
- name: assert that unmanaged pod were deleted
|
||||||
|
k8s_info:
|
||||||
|
namespace: '{{ drain_namespace }}'
|
||||||
|
kind: Pod
|
||||||
|
name: '{{ drain_pod_name }}'
|
||||||
|
register: _result
|
||||||
|
failed_when: _result.resources
|
||||||
|
|
||||||
|
- name: Test drain idempotency
|
||||||
|
k8s_drain:
|
||||||
|
state: drain
|
||||||
|
name: '{{ node_to_drain }}'
|
||||||
|
delete_options:
|
||||||
|
force: true
|
||||||
|
ignore_daemonsets: true
|
||||||
|
register: drain_result
|
||||||
|
|
||||||
|
- name: Check idempotency
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- drain_result is not changed
|
||||||
|
|
||||||
|
- name: Get DaemonSet
|
||||||
|
k8s_info:
|
||||||
|
kind: DaemonSet
|
||||||
|
namespace: '{{ drain_namespace }}'
|
||||||
|
name: '{{ drain_daemonset_name }}'
|
||||||
|
register: dset_result
|
||||||
|
|
||||||
|
- name: assert that daemonset managed pods were not removed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- dset_result.resources | list | length > 0
|
||||||
|
|
||||||
|
- name: Uncordon node
|
||||||
|
k8s_drain:
|
||||||
|
state: uncordon
|
||||||
|
name: '{{ node_to_drain }}'
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Uncordon node
|
||||||
|
k8s_drain:
|
||||||
|
state: uncordon
|
||||||
|
name: '{{ node_to_drain }}'
|
||||||
|
when: node_to_drain is defined
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: delete namespace
|
||||||
|
k8s:
|
||||||
|
state: absent
|
||||||
|
kind: namespace
|
||||||
|
name: '{{ drain_namespace }}'
|
||||||
@@ -54,6 +54,7 @@
|
|||||||
- name: Check last command status
|
- name: Check last command status
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
|
- command_status.rc != 0
|
||||||
- command_status.return_code != 0
|
- command_status.return_code != 0
|
||||||
|
|
||||||
always:
|
always:
|
||||||
|
|||||||
@@ -36,12 +36,36 @@
|
|||||||
path: ~/.kube/config
|
path: ~/.kube/config
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
|
- name: Try to create namespace without default kube config
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
name: testing
|
||||||
|
kind: Namespace
|
||||||
|
ignore_errors: true
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: No default kube config should fail
|
||||||
|
assert:
|
||||||
|
that: result is not successful
|
||||||
|
|
||||||
- name: Using custom config location should succeed
|
- name: Using custom config location should succeed
|
||||||
kubernetes.core.k8s:
|
kubernetes.core.k8s:
|
||||||
name: testing
|
name: testing
|
||||||
kind: Namespace
|
kind: Namespace
|
||||||
kubeconfig: ~/.kube/customconfig
|
kubeconfig: ~/.kube/customconfig
|
||||||
|
|
||||||
|
- name: Using an env var to set config location should succeed
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
name: testing
|
||||||
|
kind: Namespace
|
||||||
|
environment:
|
||||||
|
K8S_AUTH_KUBECONFIG: ~/.kube/customconfig
|
||||||
|
|
||||||
|
- name: Using in-memory kubeconfig should succeed
|
||||||
|
kubernetes.core.k8s:
|
||||||
|
name: testing
|
||||||
|
kind: Namespace
|
||||||
|
kubeconfig: "{{ lookup('file', '~/.kube/customconfig') | from_yaml }}"
|
||||||
|
|
||||||
always:
|
always:
|
||||||
- name: Return kubeconfig
|
- name: Return kubeconfig
|
||||||
copy:
|
copy:
|
||||||
@@ -219,7 +243,7 @@
|
|||||||
|
|
||||||
### https://github.com/ansible-collections/community.kubernetes/issues/111
|
### https://github.com/ansible-collections/community.kubernetes/issues/111
|
||||||
- set_fact:
|
- set_fact:
|
||||||
api_groups: "{{ lookup('k8s', cluster_info='api_groups') }}"
|
api_groups: "{{ lookup('kubernetes.core.k8s', cluster_info='api_groups') }}"
|
||||||
|
|
||||||
- debug:
|
- debug:
|
||||||
var: api_groups
|
var: api_groups
|
||||||
@@ -365,6 +389,38 @@
|
|||||||
register: k8s_info_testing6
|
register: k8s_info_testing6
|
||||||
failed_when: not k8s_info_testing6.resources or k8s_info_testing6.resources[0].status.phase != "Active"
|
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 configmap with large value
|
||||||
|
k8s:
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: testmap
|
||||||
|
namespace: testing
|
||||||
|
data:
|
||||||
|
testkey: "{{ cmap_data.stdout | b64encode }}"
|
||||||
|
wait: true
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: Retrieve configmap
|
||||||
|
k8s_info:
|
||||||
|
kind: ConfigMap
|
||||||
|
namespace: testing
|
||||||
|
name: testmap
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result.resources[0].data.testkey == "{{ cmap_data.stdout | b64encode }}"
|
||||||
|
|
||||||
always:
|
always:
|
||||||
- name: Delete all namespaces
|
- name: Delete all namespaces
|
||||||
k8s:
|
k8s:
|
||||||
|
|||||||
@@ -37,14 +37,23 @@
|
|||||||
k8s:
|
k8s:
|
||||||
definition: "{{ job_definition }}"
|
definition: "{{ job_definition }}"
|
||||||
|
|
||||||
- name: Test that job's pod is running
|
- name: Wait Job's pod
|
||||||
k8s_info:
|
k8s_info:
|
||||||
kind: Pod
|
kind: Pod
|
||||||
namespace: "{{ gc_namespace }}"
|
namespace: "{{ gc_namespace }}"
|
||||||
label_selectors:
|
label_selectors:
|
||||||
- "job=gc"
|
- "job=gc"
|
||||||
|
register: wait_job
|
||||||
|
until: wait_job.resources
|
||||||
|
retries: 5
|
||||||
|
delay: 10
|
||||||
|
|
||||||
|
- name: Wait job's pod running
|
||||||
|
k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
namespace: "{{ gc_namespace }}"
|
||||||
|
name: "{{ wait_job.resources[0].metadata.name }}"
|
||||||
wait: yes
|
wait: yes
|
||||||
wait_timeout: 100
|
|
||||||
register: job
|
register: job
|
||||||
|
|
||||||
- name: Assert job's pod is running
|
- name: Assert job's pod is running
|
||||||
@@ -78,14 +87,23 @@
|
|||||||
k8s:
|
k8s:
|
||||||
definition: "{{ job_definition }}"
|
definition: "{{ job_definition }}"
|
||||||
|
|
||||||
- name: Test that job's pod is running
|
- name: Wait Job's pod
|
||||||
k8s_info:
|
k8s_info:
|
||||||
kind: Pod
|
kind: Pod
|
||||||
namespace: "{{ gc_namespace }}"
|
namespace: "{{ gc_namespace }}"
|
||||||
label_selectors:
|
label_selectors:
|
||||||
- "job=gc"
|
- "job=gc"
|
||||||
|
register: wait_job
|
||||||
|
until: wait_job.resources
|
||||||
|
retries: 5
|
||||||
|
delay: 10
|
||||||
|
|
||||||
|
- name: Wait job's pod running
|
||||||
|
k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
namespace: "{{ gc_namespace }}"
|
||||||
|
name: "{{ wait_job.resources[0].metadata.name }}"
|
||||||
wait: yes
|
wait: yes
|
||||||
wait_timeout: 100
|
|
||||||
register: job
|
register: job
|
||||||
|
|
||||||
- name: Assert job's pod is running
|
- name: Assert job's pod is running
|
||||||
@@ -120,14 +138,23 @@
|
|||||||
k8s:
|
k8s:
|
||||||
definition: "{{ job_definition }}"
|
definition: "{{ job_definition }}"
|
||||||
|
|
||||||
- name: Test that job's pod is running
|
- name: Wait Job's pod
|
||||||
k8s_info:
|
k8s_info:
|
||||||
kind: Pod
|
kind: Pod
|
||||||
namespace: "{{ gc_namespace }}"
|
namespace: "{{ gc_namespace }}"
|
||||||
label_selectors:
|
label_selectors:
|
||||||
- "job=gc"
|
- "job=gc"
|
||||||
|
register: wait_job
|
||||||
|
until: wait_job.resources
|
||||||
|
retries: 5
|
||||||
|
delay: 10
|
||||||
|
|
||||||
|
- name: Wait job's pod running
|
||||||
|
k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
namespace: "{{ gc_namespace }}"
|
||||||
|
name: "{{ wait_job.resources[0].metadata.name }}"
|
||||||
wait: yes
|
wait: yes
|
||||||
wait_timeout: 100
|
|
||||||
register: job
|
register: job
|
||||||
|
|
||||||
- name: Assert job's pod is running
|
- name: Assert job's pod is running
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
value: busybox:glibc
|
value: busybox:glibc
|
||||||
check_mode: yes
|
check_mode: yes
|
||||||
register: result
|
register: result
|
||||||
|
diff: yes
|
||||||
|
|
||||||
- name: Assert patch was made
|
- name: Assert patch was made
|
||||||
assert:
|
assert:
|
||||||
@@ -50,6 +51,7 @@
|
|||||||
- result.changed
|
- result.changed
|
||||||
- result.result.metadata.labels.label2 == "bar"
|
- result.result.metadata.labels.label2 == "bar"
|
||||||
- result.result.spec.containers[0].image == "busybox:glibc"
|
- result.result.spec.containers[0].image == "busybox:glibc"
|
||||||
|
- result.diff
|
||||||
|
|
||||||
- name: Describe pod
|
- name: Describe pod
|
||||||
kubernetes.core.k8s_info:
|
kubernetes.core.k8s_info:
|
||||||
@@ -82,6 +84,7 @@
|
|||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- result.changed
|
- result.changed
|
||||||
|
- result.diff is not defined
|
||||||
|
|
||||||
- name: Describe pod
|
- name: Describe pod
|
||||||
kubernetes.core.k8s_info:
|
kubernetes.core.k8s_info:
|
||||||
|
|||||||
657
molecule/default/tasks/label_selectors.yml
Normal file
657
molecule/default/tasks/label_selectors.yml
Normal file
@@ -0,0 +1,657 @@
|
|||||||
|
---
|
||||||
|
- block:
|
||||||
|
- set_fact:
|
||||||
|
selector_namespace: "selector"
|
||||||
|
selector_pod_delete: "pod-selector-delete"
|
||||||
|
selector_pod_apply: "pod-selector-apply"
|
||||||
|
selector_pod_create:
|
||||||
|
- "pod-selector-apply-00"
|
||||||
|
- "pod-selector-apply-01"
|
||||||
|
- "pod-selector-apply-02"
|
||||||
|
- "pod-selector-apply-03"
|
||||||
|
|
||||||
|
- name: Ensure namespace selector
|
||||||
|
k8s:
|
||||||
|
kind: namespace
|
||||||
|
name: '{{ selector_namespace }}'
|
||||||
|
|
||||||
|
# Resource deletion using label selector (equality-based requirement)
|
||||||
|
- name: Create simple pod
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_delete }}-00'
|
||||||
|
labels:
|
||||||
|
ansible.dev/team: "cloud"
|
||||||
|
ansible.release/version: upstream
|
||||||
|
ansible.dev/test: "true"
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
|
||||||
|
- name: Delete all resource using selector
|
||||||
|
k8s:
|
||||||
|
state: absent
|
||||||
|
kind: Pod
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- ansible.dev/team=cloud
|
||||||
|
wait: yes
|
||||||
|
wait_timeout: 180
|
||||||
|
|
||||||
|
- name: Ensure resources have been deleted
|
||||||
|
k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- ansible.dev/team=cloud
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result.resources == []
|
||||||
|
|
||||||
|
# Resource deletion using label selector (set-based requirement)
|
||||||
|
- name: Create simple pod
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_delete }}-01'
|
||||||
|
labels:
|
||||||
|
environment: production
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: alpine:3.14.0
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
|
||||||
|
- name: Delete all resource using selector
|
||||||
|
k8s:
|
||||||
|
state: absent
|
||||||
|
kind: Pod
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- environment in (test, qa)
|
||||||
|
wait: yes
|
||||||
|
wait_timeout: 180
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check that no resources were deleted
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is not changed
|
||||||
|
|
||||||
|
- name: Ensure resources have not been deleted
|
||||||
|
k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- environment in (production)
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result.resources | list | length > 0
|
||||||
|
|
||||||
|
- name: Delete all resource using selector
|
||||||
|
k8s:
|
||||||
|
state: absent
|
||||||
|
kind: Pod
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- environment in (production)
|
||||||
|
wait: yes
|
||||||
|
wait_timeout: 180
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check result is changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: Ensure resources have not been deleted
|
||||||
|
k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- environment in (production)
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result.resources | list | length == 0
|
||||||
|
|
||||||
|
# Resource creation using label selector
|
||||||
|
- name: Create simple pod using label_selectors option (equality-based requirement)
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- container.image=fedora
|
||||||
|
definition: |
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[0] }}'
|
||||||
|
labels:
|
||||||
|
container.image: busybox
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[1] }}'
|
||||||
|
labels:
|
||||||
|
container.image: alpine
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: alpine
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[2] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
release: dev
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[3] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
release: dev
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is not changed
|
||||||
|
|
||||||
|
- name: Create simple pod using label_selectors option
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- container.image==alpine
|
||||||
|
definition: |
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[0] }}'
|
||||||
|
labels:
|
||||||
|
container.image: busybox
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[1] }}'
|
||||||
|
labels:
|
||||||
|
container.image: alpine
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: alpine
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[2] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: test
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[3] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: production
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: list pod created
|
||||||
|
k8s_info:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
kind: Pod
|
||||||
|
label_selectors:
|
||||||
|
- container.image
|
||||||
|
register: pod_created
|
||||||
|
|
||||||
|
- name: Validate that pod with matching label was created
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- pods_created | length == 1
|
||||||
|
- selector_pod_create[1] in pods_created
|
||||||
|
vars:
|
||||||
|
pods_created: '{{ pod_created.resources | map(attribute="metadata.name") | list }}'
|
||||||
|
|
||||||
|
- name: Create simple pod using label_selectors option (set-based requirement)
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- "!environment"
|
||||||
|
definition: |
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[0] }}'
|
||||||
|
labels:
|
||||||
|
container.image: busybox
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[1] }}'
|
||||||
|
labels:
|
||||||
|
container.image: alpine
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: alpine
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[2] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: test
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[3] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: production
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: list pod created
|
||||||
|
k8s_info:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
kind: Pod
|
||||||
|
label_selectors:
|
||||||
|
- container.image
|
||||||
|
register: pod_created
|
||||||
|
|
||||||
|
- name: Validate that pod with matching label was created
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- pods_created | length == 2
|
||||||
|
- selector_pod_create[0] in pods_created
|
||||||
|
vars:
|
||||||
|
pods_created: '{{ pod_created.resources | map(attribute="metadata.name") | list }}'
|
||||||
|
|
||||||
|
- name: Create simple pod using label_selectors option (set-based requirement)
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- environment in (test)
|
||||||
|
definition: |
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[0] }}'
|
||||||
|
labels:
|
||||||
|
container.image: busybox
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[1] }}'
|
||||||
|
labels:
|
||||||
|
container.image: alpine
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: alpine
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[2] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: test
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[3] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: production
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: list pod created
|
||||||
|
k8s_info:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
kind: Pod
|
||||||
|
label_selectors:
|
||||||
|
- container.image
|
||||||
|
register: pod_created
|
||||||
|
|
||||||
|
- name: Validate that pod with matching label was created
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- pods_created | length == 3
|
||||||
|
- selector_pod_create[2] in pods_created
|
||||||
|
vars:
|
||||||
|
pods_created: '{{ pod_created.resources | map(attribute="metadata.name") | list }}'
|
||||||
|
|
||||||
|
- name: Create simple pod using label_selectors option (set-based requirement)
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- environment notin (test)
|
||||||
|
definition: |
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[0] }}'
|
||||||
|
labels:
|
||||||
|
container.image: busybox
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[1] }}'
|
||||||
|
labels:
|
||||||
|
container.image: alpine
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: alpine
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[2] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: test
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[3] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: production
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: list pod created
|
||||||
|
k8s_info:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
kind: Pod
|
||||||
|
label_selectors:
|
||||||
|
- container.image
|
||||||
|
register: pod_created
|
||||||
|
|
||||||
|
- name: Validate that pod with matching label was created
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- pods_created | length == 4
|
||||||
|
- selector_pod_create[3] in pods_created
|
||||||
|
vars:
|
||||||
|
pods_created: '{{ pod_created.resources | map(attribute="metadata.name") | list }}'
|
||||||
|
|
||||||
|
# Resource update using apply
|
||||||
|
- name: Create simple pod using apply
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
apply: yes
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_apply }}'
|
||||||
|
labels:
|
||||||
|
environment: test
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox:1.31.0
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
|
||||||
|
- name: Apply new pod definition using label_selectors (no match)
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
apply: yes
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_apply }}'
|
||||||
|
labels:
|
||||||
|
environment: test
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox:1.33.0
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
label_selectors:
|
||||||
|
- environment=qa
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check task output
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is not changed
|
||||||
|
- '"filtered by label_selectors" in result.msg'
|
||||||
|
|
||||||
|
- name: Apply new pod definition using label_selectors
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
apply: yes
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_apply }}'
|
||||||
|
labels:
|
||||||
|
environment: test
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox:1.33.0
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
label_selectors:
|
||||||
|
- environment!=qa
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check task output
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Ensure namespace is deleted
|
||||||
|
k8s:
|
||||||
|
kind: Namespace
|
||||||
|
name: '{{ selector_namespace }}'
|
||||||
|
state: absent
|
||||||
|
ignore_errors: true
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
---
|
---
|
||||||
- block:
|
- block:
|
||||||
# https://github.com/ansible-collections/kubernetes.core/issues/9
|
- set_fact:
|
||||||
|
pre_test1: "{{ lookup('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}"
|
||||||
|
pre_test2: "{{ lookup('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one') }}"
|
||||||
|
pre_test3: "{{ query('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}"
|
||||||
|
pre_test4: "{{ query('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one') }}"
|
||||||
|
|
||||||
|
# https://github.com/ansible-collections/kubernetes.core/issues/147
|
||||||
- name: Create a namespace with label
|
- name: Create a namespace with label
|
||||||
kubernetes.core.k8s:
|
kubernetes.core.k8s:
|
||||||
definition:
|
definition:
|
||||||
@@ -12,15 +18,45 @@
|
|||||||
namespace_label: "app_development"
|
namespace_label: "app_development"
|
||||||
|
|
||||||
- set_fact:
|
- set_fact:
|
||||||
namespace_info: "{{ lookup('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}"
|
test1: "{{ lookup('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development', wantlist=True) }}"
|
||||||
|
test2: "{{ query('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}"
|
||||||
|
test3: "{{ lookup('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one', wantlist=True) }}"
|
||||||
|
test4: "{{ query('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one') }}"
|
||||||
|
test5: "{{ lookup('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}"
|
||||||
|
test6: "{{ lookup('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one') }}"
|
||||||
|
test7: "{{ lookup('kubernetes.core.k8s', kind='Ingress', api_version='networking.k8s.io/vINVALID', errors='ignore') }}"
|
||||||
|
|
||||||
- name: Check if the returned value is list with a single element
|
- set_fact:
|
||||||
|
test8: "{{ lookup('kubernetes.core.k8s', kind='Ingress', api_version='networking.k8s.io/vINVALID') }}"
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Assert that every test is passed
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- namespace_info is iterable
|
# Before creating object
|
||||||
- not namespace_info is string
|
- pre_test1 is sequence and pre_test1 is not string
|
||||||
- not namespace_info is mapping
|
- pre_test1 | length == 0
|
||||||
- namespace_info | length == 1
|
- pre_test2 is sequence and pre_test2 is not string
|
||||||
|
- pre_test2 | length == 0
|
||||||
|
- pre_test3 is sequence and pre_test3 is not string
|
||||||
|
- pre_test3 | length == 0
|
||||||
|
- pre_test4 is sequence and pre_test4 is not string
|
||||||
|
- pre_test4 | length == 0
|
||||||
|
# After creating object
|
||||||
|
- test1 is sequence and test1 is not string
|
||||||
|
- test1 | length == 1
|
||||||
|
- test2 is sequence and test2 is not string
|
||||||
|
- test2 | length == 1
|
||||||
|
- test3 is sequence and test3 is not string
|
||||||
|
- test3 | length == 1
|
||||||
|
- test4 is sequence and test4 is not string
|
||||||
|
- test4 | length == 1
|
||||||
|
# Without wantlist=True lookup should return mapping
|
||||||
|
- test5 is mapping
|
||||||
|
- test6 is mapping
|
||||||
|
# errors='ignore'
|
||||||
|
- test7 is string
|
||||||
|
- test8 is not defined
|
||||||
|
|
||||||
- name: Create another namespace with label
|
- name: Create another namespace with label
|
||||||
kubernetes.core.k8s:
|
kubernetes.core.k8s:
|
||||||
@@ -33,22 +69,44 @@
|
|||||||
namespace_label: "app_development"
|
namespace_label: "app_development"
|
||||||
|
|
||||||
- set_fact:
|
- set_fact:
|
||||||
namespace_info: "{{ lookup('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}"
|
test1: "{{ lookup('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development', wantlist=True) }}"
|
||||||
|
test2: "{{ query('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}"
|
||||||
|
test3: "{{ lookup('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one', wantlist=True) }}"
|
||||||
|
test4: "{{ query('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one') }}"
|
||||||
|
test5: "{{ lookup('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-two', wantlist=True) }}"
|
||||||
|
test6: "{{ query('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-two') }}"
|
||||||
|
test7: "{{ lookup('kubernetes.core.k8s', kind='Namespace', label_selector='namespace_label=app_development') }}"
|
||||||
|
test8: "{{ lookup('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-one') }}"
|
||||||
|
test9: "{{ lookup('kubernetes.core.k8s', kind='Namespace', resource_name='app-development-two') }}"
|
||||||
|
|
||||||
- name: Check if the returned value is list with 2 elements
|
- name: Assert that every test is passed after creating second object
|
||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- namespace_info is iterable
|
# After creating second object
|
||||||
- not namespace_info is string
|
- test1 is sequence and test1 is not string
|
||||||
- not namespace_info is mapping
|
- test1 | length == 2
|
||||||
- namespace_info | length == 2
|
- test2 is sequence and test2 is not string
|
||||||
|
- test2 | length == 2
|
||||||
|
- test3 is sequence and test3 is not string
|
||||||
|
- test3 | length == 1
|
||||||
|
- test4 is sequence and test4 is not string
|
||||||
|
- test4 | length == 1
|
||||||
|
- test5 is sequence and test5 is not string
|
||||||
|
- test5 | length == 1
|
||||||
|
- test6 is sequence and test6 is not string
|
||||||
|
- test6 | length == 1
|
||||||
|
# When label_selector is used it returns list irrespective of wantlist=True
|
||||||
|
- test7 is sequence and test7 is not string
|
||||||
|
# Without wantlist=True lookup should return mapping
|
||||||
|
- test8 is mapping
|
||||||
|
- test9 is mapping
|
||||||
|
|
||||||
always:
|
always:
|
||||||
- name: Ensure that namespace is removed
|
- name: Ensure that namespace is removed
|
||||||
k8s:
|
k8s:
|
||||||
kind: Namespace
|
kind: Namespace
|
||||||
name: "{{ item }}"
|
name: "app-development-{{ item }}"
|
||||||
state: absent
|
state: absent
|
||||||
with_items:
|
with_items:
|
||||||
- app-development-one
|
- one
|
||||||
- app-development-two
|
- two
|
||||||
|
|||||||
103
molecule/default/tasks/lookup_kustomize.yml
Normal file
103
molecule/default/tasks/lookup_kustomize.yml
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
---
|
||||||
|
- block:
|
||||||
|
- set_fact:
|
||||||
|
kustomize_ns: "kustomize"
|
||||||
|
|
||||||
|
- name: create environment for test
|
||||||
|
block:
|
||||||
|
- name: Ensure namespace
|
||||||
|
k8s:
|
||||||
|
kind: Namespace
|
||||||
|
name: "{{ kustomize_ns }}"
|
||||||
|
|
||||||
|
- name: Create temp directory
|
||||||
|
tempfile:
|
||||||
|
state: directory
|
||||||
|
suffix: .test
|
||||||
|
register: _tmp_dir
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
tmp_dir_path: "{{ _tmp_dir.path }}"
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
kustomize_dir: "{{ tmp_dir_path }}/kustomization"
|
||||||
|
|
||||||
|
- name: create kustomize directory
|
||||||
|
file:
|
||||||
|
path: "{{ kustomize_dir }}"
|
||||||
|
state: directory
|
||||||
|
|
||||||
|
- name: create kustomization file
|
||||||
|
copy:
|
||||||
|
content: '{{ item.content }}'
|
||||||
|
dest: '{{ item.dest }}'
|
||||||
|
with_items:
|
||||||
|
- content: |
|
||||||
|
configMapGenerator:
|
||||||
|
- name: test-confmap-
|
||||||
|
files:
|
||||||
|
- data.properties
|
||||||
|
dest: "{{ kustomize_dir }}/kustomization.yaml"
|
||||||
|
- content: "project=ansible"
|
||||||
|
dest: "{{ kustomize_dir }}/data.properties"
|
||||||
|
|
||||||
|
- name: copy script to install kustomize
|
||||||
|
get_url:
|
||||||
|
url: https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh
|
||||||
|
dest: "{{ tmp_dir_path }}"
|
||||||
|
|
||||||
|
- name: make script as executable
|
||||||
|
file:
|
||||||
|
path: "{{ tmp_dir_path }}/install_kustomize.sh"
|
||||||
|
mode: 0755
|
||||||
|
|
||||||
|
- name: Install kustomize
|
||||||
|
command: "{{ tmp_dir_path }}/install_kustomize.sh"
|
||||||
|
args:
|
||||||
|
chdir: "{{ tmp_dir_path }}"
|
||||||
|
register: _install
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
kustomize_binary: "{{ _install.stdout | regex_search('kustomize installed to (.*)', '\\1') | list | join('') }}"
|
||||||
|
kubectl_binary: "{{ tmp_dir_path }}/kubectl"
|
||||||
|
|
||||||
|
- name: Download kubeclt executable used to compare results
|
||||||
|
get_url:
|
||||||
|
url: https://dl.k8s.io/release/v1.21.3/bin/linux/amd64/kubectl
|
||||||
|
dest: "{{ kubectl_binary }}"
|
||||||
|
|
||||||
|
- name: make kubectl executable
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ kubectl_binary }}"
|
||||||
|
mode: "+x"
|
||||||
|
|
||||||
|
- name: Run lookup using kustomize binary
|
||||||
|
set_fact:
|
||||||
|
resource_kustomize: "{{ lookup('kubernetes.core.kustomize', binary_path=kustomize_binary, dir=kustomize_dir) }}"
|
||||||
|
|
||||||
|
- name: Run lookup using kubectl binary
|
||||||
|
set_fact:
|
||||||
|
resource_kubectl: "{{ lookup('kubernetes.core.kustomize', binary_path=kubectl_binary, dir=kustomize_dir) }}"
|
||||||
|
|
||||||
|
- name: assert output are the same
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- resource_kubectl == resource_kustomize
|
||||||
|
|
||||||
|
- name: create kubernetes resource using lookup plugin
|
||||||
|
k8s:
|
||||||
|
namespace: "{{ kustomize_ns }}"
|
||||||
|
definition: "{{ lookup('kubernetes.core.kustomize', dir=kustomize_dir, opt_dirs=tmp_dir_path) }}"
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Delete namespace
|
||||||
|
k8s:
|
||||||
|
kind: Namespace
|
||||||
|
name: "{{ kustomize_ns }}"
|
||||||
|
state: absent
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Delete temporary directory
|
||||||
|
file:
|
||||||
|
state: absent
|
||||||
|
path: "{{ tmp_dir_path }}"
|
||||||
@@ -54,6 +54,7 @@
|
|||||||
replicas: 0
|
replicas: 0
|
||||||
wait: yes
|
wait: yes
|
||||||
register: scale_down
|
register: scale_down
|
||||||
|
diff: true
|
||||||
|
|
||||||
- name: Get pods in scale-deploy
|
- name: Get pods in scale-deploy
|
||||||
k8s_info:
|
k8s_info:
|
||||||
@@ -143,7 +144,7 @@
|
|||||||
that:
|
that:
|
||||||
- scale_up is changed
|
- scale_up is changed
|
||||||
- '"duration" in scale_up'
|
- '"duration" in scale_up'
|
||||||
- scale_up.diff
|
- scale_up.diff is not defined
|
||||||
- scale_up_further_deploy_pods.resources | length == 2
|
- scale_up_further_deploy_pods.resources | length == 2
|
||||||
|
|
||||||
- name: Don't scale the deployment up
|
- name: Don't scale the deployment up
|
||||||
@@ -170,7 +171,7 @@
|
|||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- scale_up_noop is not changed
|
- scale_up_noop is not changed
|
||||||
- not scale_up_noop.diff
|
- scale_up_noop.diff is not defined
|
||||||
- scale_up_noop_pods.resources | length == 2
|
- scale_up_noop_pods.resources | length == 2
|
||||||
- '"duration" in scale_up_noop'
|
- '"duration" in scale_up_noop'
|
||||||
|
|
||||||
@@ -183,6 +184,7 @@
|
|||||||
replicas: 1
|
replicas: 1
|
||||||
wait: no
|
wait: no
|
||||||
register: scale_down_no_wait
|
register: scale_down_no_wait
|
||||||
|
diff: true
|
||||||
|
|
||||||
- name: Ensure that scale down succeeds
|
- name: Ensure that scale down succeeds
|
||||||
k8s_info:
|
k8s_info:
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- r.failed
|
- r.failed
|
||||||
- "'is only supported parameter for' in r.msg"
|
- "'is only a supported parameter for' in r.msg"
|
||||||
|
|
||||||
- name: Specify both definition and template
|
- name: Specify both definition and template
|
||||||
kubernetes.core.k8s:
|
kubernetes.core.k8s:
|
||||||
@@ -236,8 +236,8 @@
|
|||||||
assert:
|
assert:
|
||||||
that:
|
that:
|
||||||
- resource is successful
|
- resource is successful
|
||||||
- resource.result.results | selectattr('changed') | length == 1
|
- resource.result.results | selectattr('changed') | list | length == 1
|
||||||
- resource.result.results | selectattr('error', 'defined') | length == 1
|
- resource.result.results | selectattr('error', 'defined') | list | length == 1
|
||||||
|
|
||||||
- name: Remove Pod (Cleanup)
|
- name: Remove Pod (Cleanup)
|
||||||
kubernetes.core.k8s:
|
kubernetes.core.k8s:
|
||||||
|
|||||||
240
molecule/default/tasks/validate.yml
Normal file
240
molecule/default/tasks/validate.yml
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
- block:
|
||||||
|
- name: Create namespace
|
||||||
|
k8s:
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: "{{ validate_namespace }}"
|
||||||
|
|
||||||
|
- name: Create temp directory
|
||||||
|
tempfile:
|
||||||
|
state: directory
|
||||||
|
suffix: .test
|
||||||
|
register: remote_tmp_dir
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
remote_tmp_dir: "{{ remote_tmp_dir.path }}"
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
virtualenv: "{{ remote_tmp_dir }}/virtualenv"
|
||||||
|
virtualenv_command: "virtualenv --python {{ ansible_python_interpreter }}"
|
||||||
|
|
||||||
|
- set_fact:
|
||||||
|
virtualenv_interpreter: "{{ virtualenv }}/bin/python"
|
||||||
|
|
||||||
|
- pip:
|
||||||
|
name:
|
||||||
|
- kubernetes
|
||||||
|
virtualenv: "{{ virtualenv }}"
|
||||||
|
virtualenv_command: "{{ virtualenv_command }}"
|
||||||
|
virtualenv_site_packages: false
|
||||||
|
|
||||||
|
- name: Validate should fail gracefully without kubernetes-validate
|
||||||
|
k8s:
|
||||||
|
definition: &cmap
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: testmap
|
||||||
|
namespace: "{{ validate_namespace }}"
|
||||||
|
data:
|
||||||
|
mykey: myval
|
||||||
|
validate:
|
||||||
|
fail_on_error: true
|
||||||
|
ignore_errors: true
|
||||||
|
register: k8s_no_validate
|
||||||
|
vars:
|
||||||
|
ansible_python_interpreter: "{{ virtualenv_interpreter }}"
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- k8s_no_validate is failed
|
||||||
|
- "k8s_no_validate.msg == 'kubernetes-validate python library is required to validate resources'"
|
||||||
|
|
||||||
|
- file:
|
||||||
|
path: "{{ virtualenv }}"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- pip:
|
||||||
|
name:
|
||||||
|
- kubernetes
|
||||||
|
- kubernetes-validate
|
||||||
|
virtualenv: "{{ virtualenv }}"
|
||||||
|
virtualenv_command: "{{ virtualenv_command }}"
|
||||||
|
virtualenv_site_packages: false
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: Simple ConfigMap should validate
|
||||||
|
k8s:
|
||||||
|
definition: *cmap
|
||||||
|
validate:
|
||||||
|
fail_on_error: true
|
||||||
|
|
||||||
|
- name: ConfigMap with extra properties should validate without strict
|
||||||
|
k8s:
|
||||||
|
definition:
|
||||||
|
<<: *cmap
|
||||||
|
extra: stuff
|
||||||
|
validate:
|
||||||
|
fail_on_error: true
|
||||||
|
strict: false
|
||||||
|
|
||||||
|
- name: ConfigMap with extra properties should not validate with strict
|
||||||
|
k8s:
|
||||||
|
definition:
|
||||||
|
<<: *cmap
|
||||||
|
extra: stuff
|
||||||
|
validate:
|
||||||
|
fail_on_error: true
|
||||||
|
strict: true
|
||||||
|
ignore_errors: true
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is failed
|
||||||
|
- "\"('extra' was unexpected)\" is in result.msg"
|
||||||
|
|
||||||
|
- name: Property with invalid type should fail with strict
|
||||||
|
k8s:
|
||||||
|
definition:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: testdeploy
|
||||||
|
namespace: "{{ validate_namespace }}"
|
||||||
|
labels:
|
||||||
|
app: foo
|
||||||
|
spec:
|
||||||
|
replicas: lots
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: foo
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: foo
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: busybox
|
||||||
|
image: busybox
|
||||||
|
validate:
|
||||||
|
fail_on_error: true
|
||||||
|
strict: false
|
||||||
|
ignore_errors: true
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is failed
|
||||||
|
- result.status is not defined
|
||||||
|
- "\"'lots' is not of type 'integer'\" in result.msg"
|
||||||
|
|
||||||
|
- name: Create CRD
|
||||||
|
k8s:
|
||||||
|
definition: &crd
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
name: foobars.example.com
|
||||||
|
spec:
|
||||||
|
group: example.com
|
||||||
|
versions:
|
||||||
|
- name: v1
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
foo:
|
||||||
|
type: string
|
||||||
|
scope: Namespaced
|
||||||
|
names:
|
||||||
|
plural: foobars
|
||||||
|
singular: foobar
|
||||||
|
kind: Foobar
|
||||||
|
|
||||||
|
- pause:
|
||||||
|
seconds: 5
|
||||||
|
|
||||||
|
- name: Adding CRD should succeed with warning
|
||||||
|
k8s:
|
||||||
|
definition:
|
||||||
|
apiVersion: example.com/v1
|
||||||
|
kind: Foobar
|
||||||
|
metadata:
|
||||||
|
name: foobar
|
||||||
|
namespace: "{{ validate_namespace }}"
|
||||||
|
foo: bar
|
||||||
|
validate:
|
||||||
|
fail_on_error: true
|
||||||
|
strict: true
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is successful
|
||||||
|
- "'warnings' in result"
|
||||||
|
vars:
|
||||||
|
ansible_python_interpreter: "{{ virtualenv_interpreter }}"
|
||||||
|
|
||||||
|
- name: stat default kube config
|
||||||
|
stat:
|
||||||
|
path: "~/.kube/config"
|
||||||
|
register: _stat
|
||||||
|
|
||||||
|
- name: validate that in-memory kubeconfig authentication failed for kubernetes < 17.17.0
|
||||||
|
block:
|
||||||
|
- set_fact:
|
||||||
|
virtualenv_kubeconfig: "{{ remote_tmp_dir }}/kubeconfig"
|
||||||
|
|
||||||
|
- pip:
|
||||||
|
name:
|
||||||
|
- "kubernetes<17.17.0"
|
||||||
|
virtualenv: "{{ virtualenv_kubeconfig }}"
|
||||||
|
virtualenv_command: "{{ virtualenv_command }}"
|
||||||
|
virtualenv_site_packages: false
|
||||||
|
|
||||||
|
- name: list namespace using in-memory kubeconfig
|
||||||
|
k8s_info:
|
||||||
|
kind: Namespace
|
||||||
|
kubeconfig: "{{ lookup('file', '~/.kube/config') | from_yaml }}"
|
||||||
|
register: _result
|
||||||
|
ignore_errors: true
|
||||||
|
vars:
|
||||||
|
ansible_python_interpreter: "{{ virtualenv_kubeconfig }}/bin/python"
|
||||||
|
|
||||||
|
- name: assert that task failed with proper message
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- '"kubernetes >= 17.17.0 is required" in _result.msg'
|
||||||
|
when:
|
||||||
|
- _stat.stat.exists
|
||||||
|
- _stat.stat.readable
|
||||||
|
- _stat.stat.isreg
|
||||||
|
always:
|
||||||
|
- name: Remove temp directory
|
||||||
|
file:
|
||||||
|
path: "{{ remote_tmp_dir }}"
|
||||||
|
state: absent
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Remove namespace
|
||||||
|
k8s:
|
||||||
|
kind: Namespace
|
||||||
|
name: "{{ validate_namespace }}"
|
||||||
|
state: absent
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Remove CRD
|
||||||
|
k8s:
|
||||||
|
definition: *crd
|
||||||
|
state: absent
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
vars:
|
||||||
|
validate_namespace: validate
|
||||||
|
environment:
|
||||||
|
ENABLE_TURBO_MODE: false
|
||||||
@@ -140,6 +140,111 @@
|
|||||||
- ds.result.status.currentNumberScheduled == ds.result.status.desiredNumberScheduled
|
- ds.result.status.currentNumberScheduled == ds.result.status.desiredNumberScheduled
|
||||||
- updated_ds_pods.resources[0].spec.containers[0].image.endswith(":3")
|
- updated_ds_pods.resources[0].spec.containers[0].image.endswith(":3")
|
||||||
|
|
||||||
|
- name: Add a statefulset
|
||||||
|
k8s:
|
||||||
|
definition:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: wait-statefulset
|
||||||
|
namespace: "{{ wait_namespace }}"
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: "{{ k8s_pod_name }}"
|
||||||
|
template: "{{ k8s_pod_template }}"
|
||||||
|
wait: yes
|
||||||
|
wait_sleep: 5
|
||||||
|
wait_timeout: 180
|
||||||
|
vars:
|
||||||
|
k8s_pod_name: wait-sts
|
||||||
|
k8s_pod_image: gcr.io/kuar-demo/kuard-amd64:1
|
||||||
|
k8s_pod_command:
|
||||||
|
- sleep
|
||||||
|
- "600"
|
||||||
|
register: sts
|
||||||
|
|
||||||
|
- name: Check that statefulset wait worked
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- sts.result.spec.replicas == sts.result.status.readyReplicas
|
||||||
|
|
||||||
|
- name: Update a statefulset in check_mode
|
||||||
|
k8s:
|
||||||
|
definition:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: wait-statefulset
|
||||||
|
namespace: "{{ wait_namespace }}"
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: "{{ k8s_pod_name }}"
|
||||||
|
updateStrategy:
|
||||||
|
type: RollingUpdate
|
||||||
|
template: "{{ k8s_pod_template }}"
|
||||||
|
wait: yes
|
||||||
|
wait_sleep: 3
|
||||||
|
wait_timeout: 180
|
||||||
|
vars:
|
||||||
|
k8s_pod_name: wait-sts
|
||||||
|
k8s_pod_image: gcr.io/kuar-demo/kuard-amd64:2
|
||||||
|
k8s_pod_command:
|
||||||
|
- sleep
|
||||||
|
- "600"
|
||||||
|
register: update_sts_check_mode
|
||||||
|
check_mode: yes
|
||||||
|
|
||||||
|
- name: Check that check_mode result contains the changes
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- update_sts_check_mode is changed
|
||||||
|
- "update_sts_check_mode.result.spec.template.spec.containers[0].image == 'gcr.io/kuar-demo/kuard-amd64:2'"
|
||||||
|
|
||||||
|
- name: Update a statefulset
|
||||||
|
k8s:
|
||||||
|
definition:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: wait-statefulset
|
||||||
|
namespace: "{{ wait_namespace }}"
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: "{{ k8s_pod_name }}"
|
||||||
|
updateStrategy:
|
||||||
|
type: RollingUpdate
|
||||||
|
template: "{{ k8s_pod_template }}"
|
||||||
|
wait: yes
|
||||||
|
wait_sleep: 3
|
||||||
|
wait_timeout: 180
|
||||||
|
vars:
|
||||||
|
k8s_pod_name: wait-sts
|
||||||
|
k8s_pod_image: gcr.io/kuar-demo/kuard-amd64:3
|
||||||
|
k8s_pod_command:
|
||||||
|
- sleep
|
||||||
|
- "600"
|
||||||
|
register: sts
|
||||||
|
|
||||||
|
- name: Get updated pods
|
||||||
|
k8s_info:
|
||||||
|
api_version: v1
|
||||||
|
kind: Pod
|
||||||
|
namespace: "{{ wait_namespace }}"
|
||||||
|
label_selectors:
|
||||||
|
- app=wait-sts
|
||||||
|
field_selectors:
|
||||||
|
- status.phase=Running
|
||||||
|
register: updated_sts_pods
|
||||||
|
|
||||||
|
- name: Check that statefulset wait worked
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- sts.result.spec.replicas == sts.result.status.readyReplicas
|
||||||
|
- updated_sts_pods.resources[0].spec.containers[0].image.endswith(":3")
|
||||||
|
|
||||||
- name: Add a crashing pod
|
- name: Add a crashing pod
|
||||||
k8s:
|
k8s:
|
||||||
definition:
|
definition:
|
||||||
|
|||||||
14
molecule/default/templates/pod_diff.j2
Normal file
14
molecule/default/templates/pod_diff.j2
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: {{ pod_name }}
|
||||||
|
labels:
|
||||||
|
ansible: {{ pod_label | default('demo') }}
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: {{ pod_image }}
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
1
plugins/action/helm.py
Symbolic link
1
plugins/action/helm.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
k8s_info.py
|
||||||
1
plugins/action/helm_info.py
Symbolic link
1
plugins/action/helm_info.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
k8s_info.py
|
||||||
1
plugins/action/helm_plugin.py
Symbolic link
1
plugins/action/helm_plugin.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
k8s_info.py
|
||||||
1
plugins/action/helm_plugin_info.py
Symbolic link
1
plugins/action/helm_plugin_info.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
k8s_info.py
|
||||||
1
plugins/action/helm_repository.py
Symbolic link
1
plugins/action/helm_repository.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
k8s_info.py
|
||||||
1
plugins/action/k8s.py
Symbolic link
1
plugins/action/k8s.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
k8s_info.py
|
||||||
1
plugins/action/k8s_cluster_info.py
Symbolic link
1
plugins/action/k8s_cluster_info.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
k8s_info.py
|
||||||
1
plugins/action/k8s_cp.py
Symbolic link
1
plugins/action/k8s_cp.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
k8s_info.py
|
||||||
1
plugins/action/k8s_drain.py
Symbolic link
1
plugins/action/k8s_drain.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
k8s_info.py
|
||||||
1
plugins/action/k8s_exec.py
Symbolic link
1
plugins/action/k8s_exec.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
k8s_info.py
|
||||||
@@ -8,6 +8,7 @@ __metaclass__ = type
|
|||||||
|
|
||||||
import copy
|
import copy
|
||||||
import traceback
|
import traceback
|
||||||
|
import os
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
|
||||||
@@ -113,7 +114,7 @@ class ActionModule(ActionBase):
|
|||||||
|
|
||||||
def import_jinja2_lstrip(self, templates):
|
def import_jinja2_lstrip(self, templates):
|
||||||
# Option `lstrip_blocks' was added in Jinja2 version 2.7.
|
# Option `lstrip_blocks' was added in Jinja2 version 2.7.
|
||||||
if any([tmp['lstrip_blocks'] for tmp in templates]):
|
if any(tmp['lstrip_blocks'] for tmp in templates):
|
||||||
try:
|
try:
|
||||||
import jinja2.defaults
|
import jinja2.defaults
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@@ -126,8 +127,8 @@ class ActionModule(ActionBase):
|
|||||||
|
|
||||||
def load_template(self, template, new_module_args, task_vars):
|
def load_template(self, template, new_module_args, task_vars):
|
||||||
# template is only supported by k8s module.
|
# template is only supported by k8s module.
|
||||||
if self._task.action not in ('k8s', 'kubernetes.core.k8s', 'community.okd.k8s'):
|
if self._task.action not in ('k8s', 'kubernetes.core.k8s', 'community.okd.k8s', 'redhat.openshift.k8s', 'community.kubernetes.k8s'):
|
||||||
raise AnsibleActionFail("'template' is only supported parameter for 'k8s' module.")
|
raise AnsibleActionFail("'template' is only a supported parameter for the 'k8s' module.")
|
||||||
|
|
||||||
template_params = []
|
template_params = []
|
||||||
if isinstance(template, string_types) or isinstance(template, dict):
|
if isinstance(template, string_types) or isinstance(template, dict):
|
||||||
@@ -179,6 +180,38 @@ class ActionModule(ActionBase):
|
|||||||
new_module_args.pop('template')
|
new_module_args.pop('template')
|
||||||
new_module_args['definition'] = result_template
|
new_module_args['definition'] = result_template
|
||||||
|
|
||||||
|
def get_file_realpath(self, local_path):
|
||||||
|
# local_path is only supported by k8s_cp module.
|
||||||
|
if self._task.action not in ('k8s_cp', 'kubernetes.core.k8s_cp', 'community.kubernetes.k8s_cp'):
|
||||||
|
raise AnsibleActionFail("'local_path' is only supported parameter for 'k8s_cp' module.")
|
||||||
|
|
||||||
|
if os.path.exists(local_path):
|
||||||
|
return local_path
|
||||||
|
|
||||||
|
try:
|
||||||
|
# find in expected paths
|
||||||
|
return self._find_needle('files', local_path)
|
||||||
|
except AnsibleError:
|
||||||
|
raise AnsibleActionFail("%s does not exist in local filesystem" % local_path)
|
||||||
|
|
||||||
|
def get_kubeconfig(self, kubeconfig, remote_transport, new_module_args):
|
||||||
|
if isinstance(kubeconfig, string_types):
|
||||||
|
# find the kubeconfig in the expected search path
|
||||||
|
if not remote_transport:
|
||||||
|
# kubeconfig is local
|
||||||
|
# find in expected paths
|
||||||
|
kubeconfig = self._find_needle('files', kubeconfig)
|
||||||
|
|
||||||
|
# decrypt kubeconfig found
|
||||||
|
actual_file = self._loader.get_real_file(kubeconfig, decrypt=True)
|
||||||
|
new_module_args['kubeconfig'] = actual_file
|
||||||
|
|
||||||
|
elif isinstance(kubeconfig, dict):
|
||||||
|
new_module_args['kubeconfig'] = kubeconfig
|
||||||
|
else:
|
||||||
|
raise AnsibleActionFail("Error while reading kubeconfig parameter - "
|
||||||
|
"a string or dict expected, but got %s instead" % type(kubeconfig))
|
||||||
|
|
||||||
def run(self, tmp=None, task_vars=None):
|
def run(self, tmp=None, task_vars=None):
|
||||||
''' handler for k8s options '''
|
''' handler for k8s options '''
|
||||||
if task_vars is None:
|
if task_vars is None:
|
||||||
@@ -196,22 +229,15 @@ class ActionModule(ActionBase):
|
|||||||
new_module_args = copy.deepcopy(self._task.args)
|
new_module_args = copy.deepcopy(self._task.args)
|
||||||
|
|
||||||
kubeconfig = self._task.args.get('kubeconfig', None)
|
kubeconfig = self._task.args.get('kubeconfig', None)
|
||||||
# find the kubeconfig in the expected search path
|
if kubeconfig:
|
||||||
if kubeconfig and not remote_transport:
|
|
||||||
# kubeconfig is local
|
|
||||||
try:
|
try:
|
||||||
# find in expected paths
|
self.get_kubeconfig(kubeconfig, remote_transport, new_module_args)
|
||||||
kubeconfig = self._find_needle('files', kubeconfig)
|
|
||||||
except AnsibleError as e:
|
except AnsibleError as e:
|
||||||
result['failed'] = True
|
result['failed'] = True
|
||||||
result['msg'] = to_text(e)
|
result['msg'] = to_text(e)
|
||||||
result['exception'] = traceback.format_exc()
|
result['exception'] = traceback.format_exc()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# decrypt kubeconfig found
|
|
||||||
actual_file = self._loader.get_real_file(kubeconfig, decrypt=True)
|
|
||||||
new_module_args['kubeconfig'] = actual_file
|
|
||||||
|
|
||||||
# find the file in the expected search path
|
# find the file in the expected search path
|
||||||
src = self._task.args.get('src', None)
|
src = self._task.args.get('src', None)
|
||||||
|
|
||||||
@@ -238,6 +264,11 @@ class ActionModule(ActionBase):
|
|||||||
if template:
|
if template:
|
||||||
self.load_template(template, new_module_args, task_vars)
|
self.load_template(template, new_module_args, task_vars)
|
||||||
|
|
||||||
|
local_path = self._task.args.get('local_path')
|
||||||
|
state = self._task.args.get('state', None)
|
||||||
|
if local_path and state == 'to_pod':
|
||||||
|
new_module_args['local_path'] = self.get_file_realpath(local_path)
|
||||||
|
|
||||||
# Execute the k8s_* module.
|
# Execute the k8s_* module.
|
||||||
module_return = self._execute_module(module_name=self._task.action, module_args=new_module_args, task_vars=task_vars)
|
module_return = self._execute_module(module_name=self._task.action, module_args=new_module_args, task_vars=task_vars)
|
||||||
|
|
||||||
|
|||||||
1
plugins/action/k8s_log.py
Symbolic link
1
plugins/action/k8s_log.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
k8s_info.py
|
||||||
1
plugins/action/k8s_rollback.py
Symbolic link
1
plugins/action/k8s_rollback.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
k8s_info.py
|
||||||
1
plugins/action/k8s_scale.py
Symbolic link
1
plugins/action/k8s_scale.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
k8s_info.py
|
||||||
1
plugins/action/k8s_service.py
Symbolic link
1
plugins/action/k8s_service.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
k8s_info.py
|
||||||
1
plugins/action/ks8_json_patch.py
Symbolic link
1
plugins/action/ks8_json_patch.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
k8s_info.py
|
||||||
@@ -245,6 +245,8 @@ class Connection(ConnectionBase):
|
|||||||
# Redact password and token from console log
|
# Redact password and token from console log
|
||||||
if key.endswith(('_token', '_password')):
|
if key.endswith(('_token', '_password')):
|
||||||
censored_local_cmd += [cmd_arg, '********']
|
censored_local_cmd += [cmd_arg, '********']
|
||||||
|
else:
|
||||||
|
censored_local_cmd += [cmd_arg, self.get_option(key)]
|
||||||
|
|
||||||
extra_args_name = u'{0}_extra_args'.format(self.transport)
|
extra_args_name = u'{0}_extra_args'.format(self.transport)
|
||||||
if self.get_option(extra_args_name):
|
if self.get_option(extra_args_name):
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ options:
|
|||||||
options are provided, the Kubernetes client will attempt to load the default
|
options are provided, the Kubernetes client will attempt to load the default
|
||||||
configuration file from I(~/.kube/config). Can also be specified via K8S_AUTH_KUBECONFIG environment
|
configuration file from I(~/.kube/config). Can also be specified via K8S_AUTH_KUBECONFIG environment
|
||||||
variable.
|
variable.
|
||||||
type: path
|
- The kubernetes configuration can be provided as dictionary. This feature requires a python kubernetes client version >= 17.17.0. Added in version 2.2.0.
|
||||||
|
type: raw
|
||||||
context:
|
context:
|
||||||
description:
|
description:
|
||||||
- The name of a context found in the config file. Can also be specified via K8S_AUTH_CONTEXT environment variable.
|
- The name of a context found in the config file. Can also be specified via K8S_AUTH_CONTEXT environment variable.
|
||||||
|
|||||||
@@ -28,6 +28,6 @@ options:
|
|||||||
- Reads from the local file system. To read from the Ansible controller's file system, including vaulted files, use the file lookup
|
- Reads from the local file system. To read from the Ansible controller's file system, including vaulted files, use the file lookup
|
||||||
plugin or template lookup plugin, combined with the from_yaml filter, and pass the result to
|
plugin or template lookup plugin, combined with the from_yaml filter, and pass the result to
|
||||||
I(resource_definition). See Examples below.
|
I(resource_definition). See Examples below.
|
||||||
- Mutually exclusive with I(template) in case of M(k8s) module.
|
- Mutually exclusive with I(template) in case of M(kubernetes.core.k8s) module.
|
||||||
type: path
|
type: path
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ DOCUMENTATION = '''
|
|||||||
plugin:
|
plugin:
|
||||||
description: token that ensures this is a source file for the 'k8s' plugin.
|
description: token that ensures this is a source file for the 'k8s' plugin.
|
||||||
required: True
|
required: True
|
||||||
choices: ['kubernetes.core.k8s', 'k8s']
|
choices: ['kubernetes.core.k8s', 'k8s', 'community.kubernetes.k8s']
|
||||||
connections:
|
connections:
|
||||||
description:
|
description:
|
||||||
- Optional list of cluster connection settings. If no connections are provided, the default
|
- Optional list of cluster connection settings. If no connections are provided, the default
|
||||||
|
|||||||
@@ -21,7 +21,10 @@ DOCUMENTATION = '''
|
|||||||
namespace, or all matching objects for all namespaces, as well as information about the cluster.
|
namespace, or all matching objects for all namespaces, as well as information about the cluster.
|
||||||
- Provides access the full range of K8s APIs.
|
- Provides access the full range of K8s APIs.
|
||||||
- Enables authentication via config file, certificates, password or token.
|
- Enables authentication via config file, certificates, password or token.
|
||||||
|
notes:
|
||||||
|
- While querying, please use C(query) or C(lookup) format with C(wantlist=True) to provide an easier and more
|
||||||
|
consistent interface. For more details, see
|
||||||
|
U(https://docs.ansible.com/ansible/latest/plugins/lookup.html#forcing-lookups-to-return-lists-query-and-wantlist-true).
|
||||||
options:
|
options:
|
||||||
cluster_info:
|
cluster_info:
|
||||||
description:
|
description:
|
||||||
@@ -119,23 +122,23 @@ DOCUMENTATION = '''
|
|||||||
EXAMPLES = """
|
EXAMPLES = """
|
||||||
- name: Fetch a list of namespaces
|
- name: Fetch a list of namespaces
|
||||||
set_fact:
|
set_fact:
|
||||||
projects: "{{ lookup('kubernetes.core.k8s', api_version='v1', kind='Namespace') }}"
|
projects: "{{ query('kubernetes.core.k8s', api_version='v1', kind='Namespace') }}"
|
||||||
|
|
||||||
- name: Fetch all deployments
|
- name: Fetch all deployments
|
||||||
set_fact:
|
set_fact:
|
||||||
deployments: "{{ lookup('kubernetes.core.k8s', kind='Deployment') }}"
|
deployments: "{{ query('kubernetes.core.k8s', kind='Deployment') }}"
|
||||||
|
|
||||||
- name: Fetch all deployments in a namespace
|
- name: Fetch all deployments in a namespace
|
||||||
set_fact:
|
set_fact:
|
||||||
deployments: "{{ lookup('kubernetes.core.k8s', kind='Deployment', namespace='testing') }}"
|
deployments: "{{ query('kubernetes.core.k8s', kind='Deployment', namespace='testing') }}"
|
||||||
|
|
||||||
- name: Fetch a specific deployment by name
|
- name: Fetch a specific deployment by name
|
||||||
set_fact:
|
set_fact:
|
||||||
deployments: "{{ lookup('kubernetes.core.k8s', kind='Deployment', namespace='testing', resource_name='elastic') }}"
|
deployments: "{{ query('kubernetes.core.k8s', kind='Deployment', namespace='testing', resource_name='elastic') }}"
|
||||||
|
|
||||||
- name: Fetch with label selector
|
- name: Fetch with label selector
|
||||||
set_fact:
|
set_fact:
|
||||||
service: "{{ lookup('kubernetes.core.k8s', kind='Service', label_selector='app=galaxy') }}"
|
service: "{{ query('kubernetes.core.k8s', kind='Service', label_selector='app=galaxy') }}"
|
||||||
|
|
||||||
# Use parameters from a YAML config
|
# Use parameters from a YAML config
|
||||||
|
|
||||||
@@ -145,11 +148,11 @@ EXAMPLES = """
|
|||||||
|
|
||||||
- name: Using the config (loaded from a file in prior task), fetch the latest version of the object
|
- name: Using the config (loaded from a file in prior task), fetch the latest version of the object
|
||||||
set_fact:
|
set_fact:
|
||||||
service: "{{ lookup('kubernetes.core.k8s', resource_definition=config) }}"
|
service: "{{ query('kubernetes.core.k8s', resource_definition=config) }}"
|
||||||
|
|
||||||
- name: Use a config from the local filesystem
|
- name: Use a config from the local filesystem
|
||||||
set_fact:
|
set_fact:
|
||||||
service: "{{ lookup('kubernetes.core.k8s', src='service.yml') }}"
|
service: "{{ query('kubernetes.core.k8s', src='service.yml') }}"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
RETURN = """
|
RETURN = """
|
||||||
@@ -264,7 +267,7 @@ class KubernetesLookup(K8sAnsibleMixin):
|
|||||||
if self.name:
|
if self.name:
|
||||||
return [k8s_obj.to_dict()]
|
return [k8s_obj.to_dict()]
|
||||||
|
|
||||||
return [k8s_obj.to_dict().get('items')]
|
return k8s_obj.to_dict().get('items')
|
||||||
|
|
||||||
|
|
||||||
class LookupModule(LookupBase):
|
class LookupModule(LookupBase):
|
||||||
|
|||||||
133
plugins/lookup/kustomize.py
Normal file
133
plugins/lookup/kustomize.py
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
#
|
||||||
|
# Copyright 2021 Red Hat | Ansible
|
||||||
|
#
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
lookup: kustomize
|
||||||
|
|
||||||
|
short_description: Build a set of kubernetes resources using a 'kustomization.yaml' file.
|
||||||
|
|
||||||
|
version_added: "2.2.0"
|
||||||
|
|
||||||
|
author:
|
||||||
|
- Aubin Bikouo <@abikouo>
|
||||||
|
notes:
|
||||||
|
- If both kustomize and kubectl are part of the PATH, kustomize will be used by the plugin.
|
||||||
|
description:
|
||||||
|
- Uses the kustomize or the kubectl tool.
|
||||||
|
- Return the result of C(kustomize build) or C(kubectl kustomize).
|
||||||
|
options:
|
||||||
|
dir:
|
||||||
|
description:
|
||||||
|
- The directory path containing 'kustomization.yaml',
|
||||||
|
or a git repository URL with a path suffix specifying same with respect to the repository root.
|
||||||
|
- If omitted, '.' is assumed.
|
||||||
|
default: "."
|
||||||
|
binary_path:
|
||||||
|
description:
|
||||||
|
- The path of a kustomize or kubectl binary to use.
|
||||||
|
opt_dirs:
|
||||||
|
description:
|
||||||
|
- An optional list of directories to search for the executable in addition to PATH.
|
||||||
|
|
||||||
|
requirements:
|
||||||
|
- "python >= 3.6"
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = """
|
||||||
|
- name: Run lookup using kustomize
|
||||||
|
set_fact:
|
||||||
|
resources: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kustomize') }}"
|
||||||
|
|
||||||
|
- name: Run lookup using kubectl kustomize
|
||||||
|
set_fact:
|
||||||
|
resources: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kubectl') }}"
|
||||||
|
|
||||||
|
- name: Create kubernetes resources for lookup output
|
||||||
|
k8s:
|
||||||
|
definition: "{{ lookup('kubernetes.core.kustomize', dir='/path/to/kustomization') }}"
|
||||||
|
"""
|
||||||
|
|
||||||
|
RETURN = """
|
||||||
|
_list:
|
||||||
|
description:
|
||||||
|
- One ore more object definitions returned from the tool execution.
|
||||||
|
type: complex
|
||||||
|
contains:
|
||||||
|
api_version:
|
||||||
|
description: The versioned schema of this representation of an object.
|
||||||
|
returned: success
|
||||||
|
type: str
|
||||||
|
kind:
|
||||||
|
description: Represents the REST resource this object represents.
|
||||||
|
returned: success
|
||||||
|
type: str
|
||||||
|
metadata:
|
||||||
|
description: Standard object metadata. Includes name, namespace, annotations, labels, etc.
|
||||||
|
returned: success
|
||||||
|
type: complex
|
||||||
|
spec:
|
||||||
|
description: Specific attributes of the object. Will vary based on the I(api_version) and I(kind).
|
||||||
|
returned: success
|
||||||
|
type: complex
|
||||||
|
status:
|
||||||
|
description: Current status details for the object.
|
||||||
|
returned: success
|
||||||
|
type: complex
|
||||||
|
"""
|
||||||
|
|
||||||
|
from ansible.errors import AnsibleLookupError
|
||||||
|
from ansible.plugins.lookup import LookupBase
|
||||||
|
from ansible.module_utils.common.process import get_bin_path
|
||||||
|
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
|
def get_binary_from_path(name, opt_dirs=None):
|
||||||
|
opt_arg = {}
|
||||||
|
try:
|
||||||
|
if opt_dirs is not None:
|
||||||
|
if not isinstance(opt_dirs, list):
|
||||||
|
opt_dirs = [opt_dirs]
|
||||||
|
opt_arg['opt_dirs'] = opt_dirs
|
||||||
|
bin_path = get_bin_path(name, **opt_arg)
|
||||||
|
return bin_path
|
||||||
|
except ValueError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def run_command(command):
|
||||||
|
cmd = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
return cmd.communicate()
|
||||||
|
|
||||||
|
|
||||||
|
class LookupModule(LookupBase):
|
||||||
|
|
||||||
|
def run(self, terms, variables=None, dir=".", binary_path=None, opt_dirs=None, **kwargs):
|
||||||
|
executable_path = binary_path
|
||||||
|
if executable_path is None:
|
||||||
|
executable_path = get_binary_from_path(name="kustomize", opt_dirs=opt_dirs)
|
||||||
|
if executable_path is None:
|
||||||
|
executable_path = get_binary_from_path(name="kubectl", opt_dirs=opt_dirs)
|
||||||
|
|
||||||
|
# validate that at least one tool was found
|
||||||
|
if executable_path is None:
|
||||||
|
raise AnsibleLookupError("Failed to find required executable 'kubectl' and 'kustomize' in paths")
|
||||||
|
|
||||||
|
# check input directory
|
||||||
|
kustomization_dir = dir
|
||||||
|
|
||||||
|
command = [executable_path]
|
||||||
|
if executable_path.endswith('kustomize'):
|
||||||
|
command += ['build', kustomization_dir]
|
||||||
|
elif executable_path.endswith('kubectl'):
|
||||||
|
command += ['kustomize', kustomization_dir]
|
||||||
|
else:
|
||||||
|
raise AnsibleLookupError("unexpected tool provided as parameter {0}, expected one of kustomize, kubectl.".format(executable_path))
|
||||||
|
|
||||||
|
(out, err) = run_command(command)
|
||||||
|
if err:
|
||||||
|
raise AnsibleLookupError("kustomize command failed with: {0}".format(err.decode("utf-8")))
|
||||||
|
return [out.decode('utf-8')]
|
||||||
@@ -3,6 +3,16 @@ from __future__ import (absolute_import, division, print_function)
|
|||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from ansible.module_utils.common.validation import check_type_bool
|
||||||
|
|
||||||
|
try:
|
||||||
|
enable_turbo_mode = check_type_bool(os.environ.get("ENABLE_TURBO_MODE"))
|
||||||
|
except TypeError:
|
||||||
|
enable_turbo_mode = False
|
||||||
|
|
||||||
|
if enable_turbo_mode:
|
||||||
try:
|
try:
|
||||||
from ansible_collections.cloud.common.plugins.module_utils.turbo.module import (
|
from ansible_collections.cloud.common.plugins.module_utils.turbo.module import (
|
||||||
AnsibleTurboModule as AnsibleModule,
|
AnsibleTurboModule as AnsibleModule,
|
||||||
@@ -10,3 +20,5 @@ try:
|
|||||||
AnsibleModule.collection_name = "kubernetes.core"
|
AnsibleModule.collection_name = "kubernetes.core"
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from ansible.module_utils.basic import AnsibleModule # noqa: F401
|
from ansible.module_utils.basic import AnsibleModule # noqa: F401
|
||||||
|
else:
|
||||||
|
from ansible.module_utils.basic import AnsibleModule # noqa: F401
|
||||||
|
|||||||
@@ -18,10 +18,8 @@ __metaclass__ = type
|
|||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import json
|
import json
|
||||||
import sys
|
|
||||||
|
|
||||||
from ansible.module_utils.common.dict_transformations import dict_merge
|
from ansible.module_utils.common.dict_transformations import dict_merge
|
||||||
from ansible.module_utils.six import PY3
|
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.exceptions import ApplyException
|
from ansible_collections.kubernetes.core.plugins.module_utils.exceptions import ApplyException
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -29,8 +27,6 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if PY3:
|
|
||||||
unicode = str
|
|
||||||
|
|
||||||
LAST_APPLIED_CONFIG_ANNOTATION = 'kubectl.kubernetes.io/last-applied-configuration'
|
LAST_APPLIED_CONFIG_ANNOTATION = 'kubectl.kubernetes.io/last-applied-configuration'
|
||||||
|
|
||||||
@@ -79,34 +75,6 @@ STRATEGIC_MERGE_PATCH_KEYS.update(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if sys.version_info.major >= 3:
|
|
||||||
json_loads_byteified = json.loads
|
|
||||||
else:
|
|
||||||
# https://stackoverflow.com/a/33571117
|
|
||||||
def json_loads_byteified(json_text):
|
|
||||||
return _byteify(
|
|
||||||
json.loads(json_text, object_hook=_byteify),
|
|
||||||
ignore_dicts=True
|
|
||||||
)
|
|
||||||
|
|
||||||
def _byteify(data, ignore_dicts=False):
|
|
||||||
# if this is a unicode string, return its string representation
|
|
||||||
if isinstance(data, unicode): # noqa: F821
|
|
||||||
return data.encode('utf-8')
|
|
||||||
# if this is a list of values, return list of byteified values
|
|
||||||
if isinstance(data, list):
|
|
||||||
return [_byteify(item, ignore_dicts=True) for item in data]
|
|
||||||
# if this is a dictionary, return dictionary of byteified keys and values
|
|
||||||
# but only if we haven't already byteified it
|
|
||||||
if isinstance(data, dict) and not ignore_dicts:
|
|
||||||
return {
|
|
||||||
_byteify(key, ignore_dicts=True): _byteify(value, ignore_dicts=True)
|
|
||||||
for key, value in data.items()
|
|
||||||
}
|
|
||||||
# if it's anything else, return it in its original form
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def annotate(desired):
|
def annotate(desired):
|
||||||
return dict(
|
return dict(
|
||||||
metadata=dict(
|
metadata=dict(
|
||||||
@@ -123,7 +91,7 @@ def apply_patch(actual, desired):
|
|||||||
if last_applied:
|
if last_applied:
|
||||||
# ensure that last_applied doesn't come back as a dict of unicode key/value pairs
|
# ensure that last_applied doesn't come back as a dict of unicode key/value pairs
|
||||||
# json.loads can be used if we stop supporting python 2
|
# json.loads can be used if we stop supporting python 2
|
||||||
last_applied = json_loads_byteified(last_applied)
|
last_applied = json.loads(last_applied)
|
||||||
patch = merge(dict_merge(last_applied, annotate(last_applied)),
|
patch = merge(dict_merge(last_applied, annotate(last_applied)),
|
||||||
dict_merge(desired, annotate(desired)), actual)
|
dict_merge(desired, annotate(desired)), actual)
|
||||||
if patch:
|
if patch:
|
||||||
@@ -142,7 +110,7 @@ def apply_object(resource, definition):
|
|||||||
return apply_patch(actual.to_dict(), definition)
|
return apply_patch(actual.to_dict(), definition)
|
||||||
|
|
||||||
|
|
||||||
def apply(resource, definition):
|
def k8s_apply(resource, definition):
|
||||||
existing, desired = apply_object(resource, definition)
|
existing, desired = apply_object(resource, definition)
|
||||||
if not existing:
|
if not existing:
|
||||||
return resource.create(body=desired, namespace=definition['metadata'].get('namespace'))
|
return resource.create(body=desired, namespace=definition['metadata'].get('namespace'))
|
||||||
@@ -284,7 +252,7 @@ def get_delta(last_applied, actual, desired, position=None):
|
|||||||
elif isinstance(desired_value, list):
|
elif isinstance(desired_value, list):
|
||||||
p = list_merge(last_applied.get(k, []), actual_value, desired_value, this_position)
|
p = list_merge(last_applied.get(k, []), actual_value, desired_value, this_position)
|
||||||
if p:
|
if p:
|
||||||
patch[k] = [item for item in p if item]
|
patch[k] = [item for item in p if item is not None]
|
||||||
elif actual_value != desired_value:
|
elif actual_value != desired_value:
|
||||||
patch[k] = desired_value
|
patch[k] = desired_value
|
||||||
return patch
|
return patch
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ AUTH_PROXY_HEADERS_SPEC = dict(
|
|||||||
|
|
||||||
AUTH_ARG_SPEC = {
|
AUTH_ARG_SPEC = {
|
||||||
'kubeconfig': {
|
'kubeconfig': {
|
||||||
'type': 'path',
|
'type': 'raw',
|
||||||
},
|
},
|
||||||
'context': {},
|
'context': {},
|
||||||
'host': {},
|
'host': {},
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import os
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import hashlib
|
import hashlib
|
||||||
import tempfile
|
import tempfile
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
import kubernetes.dynamic
|
import kubernetes.dynamic
|
||||||
import kubernetes.dynamic.discovery
|
import kubernetes.dynamic.discovery
|
||||||
@@ -74,7 +75,7 @@ class Discoverer(kubernetes.dynamic.discovery.Discoverer):
|
|||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
with open(self.__cache_file, 'r') as f:
|
with open(self.__cache_file, 'r') as f:
|
||||||
self._cache = json.load(f, cls=CacheDecoder(self.client))
|
self._cache = json.load(f, cls=partial(CacheDecoder, self.client))
|
||||||
if self._cache.get('library_version') != __version__:
|
if self._cache.get('library_version') != __version__:
|
||||||
# Version mismatch, need to refresh cache
|
# Version mismatch, need to refresh cache
|
||||||
self.invalidate_cache()
|
self.invalidate_cache()
|
||||||
@@ -143,7 +144,7 @@ class Discoverer(kubernetes.dynamic.discovery.Discoverer):
|
|||||||
result for result in results if result.group_version == kwargs['api_version']
|
result for result in results if result.group_version == kwargs['api_version']
|
||||||
]
|
]
|
||||||
# If there are multiple matches, prefer non-List kinds
|
# If there are multiple matches, prefer non-List kinds
|
||||||
if len(results) > 1 and not all([isinstance(x, ResourceList) for x in results]):
|
if len(results) > 1 and not all(isinstance(x, ResourceList) for x in results):
|
||||||
results = [result for result in results if not isinstance(result, ResourceList)]
|
results = [result for result in results if not isinstance(result, ResourceList)]
|
||||||
# if multiple resources are found that share a GVK, prefer the one with the most supported verbs
|
# if multiple resources are found that share a GVK, prefer the one with the most supported verbs
|
||||||
if len(results) > 1 and len(set((x.group_version, x.kind) for x in results)) == 1:
|
if len(results) > 1 and len(set((x.group_version, x.kind) for x in results)) == 1:
|
||||||
@@ -162,6 +163,10 @@ class LazyDiscoverer(Discoverer, kubernetes.dynamic.LazyDiscoverer):
|
|||||||
Discoverer.__init__(self, client, cache_file)
|
Discoverer.__init__(self, client, cache_file)
|
||||||
self.__update_cache = False
|
self.__update_cache = False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def update_cache(self):
|
||||||
|
self.__update_cache
|
||||||
|
|
||||||
|
|
||||||
class CacheDecoder(json.JSONDecoder):
|
class CacheDecoder(json.JSONDecoder):
|
||||||
def __init__(self, client, *args, **kwargs):
|
def __init__(self, client, *args, **kwargs):
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user