Compare commits

..

23 Commits

Author SHA1 Message Date
patchback[bot]
bd0a376451 kubevirt.core collection cross testing (#731) (#736)
* Initial

* update python version

* update python version

* checkout local version of collection

* add integration job

* indent

* Set workflow as non blocking

(cherry picked from commit c0666a5137)

Co-authored-by: Bikouo Aubin <79859644+abikouo@users.noreply.github.com>
2024-05-31 09:47:10 +02:00
Bikouo Aubin
f22ffcab18 Prepare release 4.0.0 (#727)
* Prepare release 4.0.0

* update documentation
2024-05-28 11:37:32 +02:00
Bikouo Aubin
072a08091b Remove deprecated function from module_utils/common.py (#726)
Remove deprecated function from module_utils/common.py

SUMMARY

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

ISSUE TYPE


Feature Pull Request

COMPONENT NAME

module_utils/common.py

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

SUMMARY

Defer removal of k8s inventory plugin to version 5.0.

ISSUE TYPE


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

COMPONENT NAME

inventory/k8s.py
ADDITIONAL INFORMATION

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

SUMMARY

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

ISSUE TYPE


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

COMPONENT NAME

k8s.py
ADDITIONAL INFORMATION

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

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

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

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

Docs Pull Request

COMPONENT NAME
k8s module

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

SUMMARY

This fixes a problem with unsafe text in an assertion.

ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

ADDITIONAL INFORMATION

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

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

Docs Pull Request

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

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

SUMMARY

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

ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME

k8s_json_patch
ADDITIONAL INFORMATION


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

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

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

Feature Pull Request

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

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

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

SUMMARY

Add tests/sanity/ignore-2.18.txt

ISSUE TYPE


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

COMPONENT NAME

ADDITIONAL INFORMATION

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

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

Feature Pull Request

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

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

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

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

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

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

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

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

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

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

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

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

root@ubuntu-shell:/#

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

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


Feature Pull Request

COMPONENT NAME


k8s module
K8sService

ADDITIONAL INFORMATION



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

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

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

SUMMARY

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

ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

helm
ADDITIONAL INFORMATION



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

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

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

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

SUMMARY

closes #680

ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

helm

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

* fix(add changelog fragment)

* update node image

* Create discovery.yml

* Update main.yml

---------

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

SUMMARY
Align helmdiff_check behavior with the deploy function

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

ISSUE TYPE

Bugfix Pull Request

COMPONENT NAME
kubernetes.core.helm

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

SUMMARY

Remove ignore files and entries which are not useful anymore

ISSUE TYPE


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

COMPONENT NAME

ADDITIONAL INFORMATION

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

SUMMARY


ISSUE TYPE


Bugfix Pull Request

COMPONENT NAME

integration tests

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

SUMMARY


ISSUE TYPE


Docs Pull Request

COMPONENT NAME

ADDITIONAL INFORMATION

Reviewed-by: Bikouo Aubin
2023-11-21 17:23:25 +00:00
54 changed files with 878 additions and 1717 deletions

View File

@@ -0,0 +1,127 @@
name: Integration tests Kubevirt
on:
pull_request:
types:
- opened
- reopened
- synchronize
branches:
- main
- stable-*
jobs:
splitter:
continue-on-error: true
env:
kubernetes: "./kubernetes"
kubevirt: "./kubevirt"
py_version: 3.9
runs-on: ubuntu-latest
outputs:
test_targets: ${{ steps.splitter.outputs.kubevirt_targets }}
steps:
- name: Checkout kubernetes.core repository
uses: actions/checkout@v3
with:
path: ${{ env.kubernetes }}
ref: ${{ github.event.pull_request.head.sha }}
- name: Checkout the kubevirt.core collection
uses: actions/checkout@v3
with:
repository: kubevirt/kubevirt.core
path: ${{ env.kubevirt }}
- name: "Set up Python ${{ env.py_version }}"
uses: actions/setup-python@v4
with:
python-version: "${{ env.py_version }}"
- name: List targets from kubevirt.core collection
id: splitter
run: python ${{ env.kubernetes }}/tools/kubevirt_list_targets.py ${{ env.kubevirt }}
shell: bash
integration:
if: ${{ needs.splitter.outputs.test_targets != '' }}
name: "integration-kubevirt-${{ matrix.test-target }}"
runs-on: ubuntu-latest
continue-on-error: true
needs:
- splitter
env:
kubernetes: "./kubernetes"
kubevirt: "./kubevirt"
ansible_version: milestone
python_version: 3.12
strategy:
fail-fast: false
matrix:
test-target: ${{ fromJson(needs.splitter.outputs.test_targets) }}
steps:
- name: Checkout kubernetes.core repository
uses: actions/checkout@v4
with:
path: ${{ env.kubernetes }}
ref: ${{ github.event.pull_request.head.sha }}
- name: Checkout kubevirt.core repository
uses: actions/checkout@v4
with:
repository: kubevirt/kubevirt.core
path: ${{ env.kubevirt }}
ref: main
# Install ansible
- name: Install ansible-core (${{ env.ansible_version }})
run: >-
python3 -m pip install
https://github.com/ansible/ansible/archive/${{ env.ansible_version }}.tar.gz
--disable-pip-version-check
shell: bash
- name: Build and install kubevirt.core collection
id: install-kubevirt
uses: ansible-network/github_actions/.github/actions/build_install_collection@main
with:
install_python_dependencies: true
source_path: ${{ env.kubevirt }}
- name: Build and install kubernetes.core collection
id: install-kubernetes
uses: ansible-network/github_actions/.github/actions/build_install_collection@main
with:
install_python_dependencies: true
source_path: ${{ env.kubernetes }}
- name: Install kind / kubectl
uses: helm/kind-action@v1.9.0
with:
version: v0.22.0
install_only: true
- name: Deploy kubevirt
run: >-
${{ env.kubevirt }}/hack/e2e-setup.sh \
-v \
--configure-inotify-limits \
--configure-secondary-network \
--deploy-kubevirt \
--deploy-kubevirt-cdi \
--deploy-kubevirt-common-instancetypes \
--deploy-cnao \
--create-cluster \
--create-nad
env:
KIND: kind
KUBECTL: kubectl
- name: Run integration tests
uses: ansible-network/github_actions/.github/actions/ansible_test_integration@main
with:
collection_path: ${{ steps.install-kubevirt.outputs.collection_path }}
python_version: ${{ env.python_version }}
ansible_version: ${{ env.ansible_version }}
ansible_test_targets: ${{ matrix.test-target }}
env:
ANSIBLE_COLLECTIONS_PATHS: /home/runner/collections

View File

@@ -21,4 +21,4 @@ jobs:
- uses: actions/checkout@v4
- name: Run ansible-lint
uses: ansible/ansible-lint@v6.21.0
uses: ansible/ansible-lint@v24.2.3

View File

@@ -4,6 +4,59 @@ Kubernetes Collection Release Notes
.. contents:: Topics
v4.0.0
======
Release Summary
---------------
This major release brings several bug fixes. We have also removed support for ``ansible-core<2.15`` and deprecated functions and class from ``module_utils/common.py``.
Minor Changes
-------------
- inventory/k8s.py - Defer removal of k8s inventory plugin to version 5.0 (https://github.com/ansible-collections/kubernetes.core/pull/723).
- k8s - The module and K8sService were changed so warnings returned by the K8S API are now displayed to the user.
Removed Features (previously deprecated)
----------------------------------------
- k8s - Support for ``merge_type=json`` has been removed in version 4.0.0. Please use ``kubernetes.core.k8s_json_patch`` instead (https://github.com/ansible-collections/kubernetes.core/pull/722).
- k8s_exec - the previously deprecated ``result.return_code`` return value has been removed, consider using ``result.rc`` instead (https://github.com/ansible-collections/kubernetes.core/pull/726).
- module_utils/common.py - the previously deprecated ``K8sAnsibleMixin`` class has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
- module_utils/common.py - the previously deprecated ``configuration_digest()`` function has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
- module_utils/common.py - the previously deprecated ``get_api_client()`` function has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
- module_utils/common.py - the previously deprecated ``unique_string()`` function has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
Bugfixes
--------
- Resolve Collections util resource discovery fails when complex subresources present (https://github.com/ansible-collections/kubernetes.core/pull/676).
- align `helmdiff_check()` function commandline rendering with the `deploy()` function (https://github.com/ansible-collections/kubernetes.core/pull/670).
- avoid unsafe conditions in integration tests (https://github.com/ansible-collections/kubernetes.core/pull/665).
- helm - use ``reuse-values`` when running ``helm diff`` command (https://github.com/ansible-collections/kubernetes.core/issues/680).
- integrations test helm_kubeconfig - set helm version to v3.10.3 to avoid incompatability with new bitnami charts (https://github.com/ansible-collections/kubernetes.core/pull/670).
v3.1.0
======
Release Summary
---------------
This release comes with some bugfixes and documentation updates. It also adds new features to the kubectl connection plugin and the kustomize lookup plugin.
Minor Changes
-------------
- kubectl - added support of local enviroment variable that will be used for kubectl and may be requried for establishing connections ifself (https://github.com/ansible-collections/kubernetes.core/pull/702)
- kustomize - new parameter added to --enable-helm (https://github.com/ansible-collections/kubernetes.core/issues/568)
Bugfixes
--------
- helm - expand kubeconfig path with user's home directory for consistency with k8s
- k8s_json_patch - rename action symlink to ensure k8s action plugin is used (https://github.com/ansible-collections/kubernetes.core/pull/652).
v3.0.1
======

View File

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

View File

@@ -93,7 +93,7 @@ You can also include it in a `requirements.yml` file and install it via `ansible
---
collections:
- name: kubernetes.core
version: 3.0.0
version: 4.0.0
```
### Installing the Kubernetes Python Library

View File

@@ -833,3 +833,66 @@ releases:
- 20240228-fix-helm-diff-with-reuse-values.yml
- 3.0.1.yml
release_date: '2024-03-01'
3.1.0:
changes:
bugfixes:
- helm - expand kubeconfig path with user's home directory for consistency with
k8s
- k8s_json_patch - rename action symlink to ensure k8s action plugin is used
(https://github.com/ansible-collections/kubernetes.core/pull/652).
minor_changes:
- kubectl - added support of local enviroment variable that will be used for
kubectl and may be requried for establishing connections ifself (https://github.com/ansible-collections/kubernetes.core/pull/702)
- kustomize - new parameter added to --enable-helm (https://github.com/ansible-collections/kubernetes.core/issues/568)
release_summary: This release comes with some bugfixes and documentation updates.
It also adds new features to the kubectl connection plugin and the kustomize
lookup plugin.
fragments:
- 20240426-add-support-of-kubectl-local-env-vars-for-connection-plugin.yml
- 3.1.0.yml
- 592-kustomize-helm-support.yml
- 652-fix-json-patch-action.yml
- 654-helm-expand-user.yml
release_date: '2024-05-16'
4.0.0:
changes:
bugfixes:
- Resolve Collections util resource discovery fails when complex subresources
present (https://github.com/ansible-collections/kubernetes.core/pull/676).
- align `helmdiff_check()` function commandline rendering with the `deploy()`
function (https://github.com/ansible-collections/kubernetes.core/pull/670).
- avoid unsafe conditions in integration tests (https://github.com/ansible-collections/kubernetes.core/pull/665).
- helm - use ``reuse-values`` when running ``helm diff`` command (https://github.com/ansible-collections/kubernetes.core/issues/680).
- integrations test helm_kubeconfig - set helm version to v3.10.3 to avoid incompatability
with new bitnami charts (https://github.com/ansible-collections/kubernetes.core/pull/670).
minor_changes:
- inventory/k8s.py - Defer removal of k8s inventory plugin to version 5.0 (https://github.com/ansible-collections/kubernetes.core/pull/723).
- k8s - The module and K8sService were changed so warnings returned by the K8S
API are now displayed to the user.
release_summary: This major release brings several bug fixes. We have also removed
support for ``ansible-core<2.15`` and deprecated functions and class from
``module_utils/common.py``.
removed_features:
- k8s - Support for ``merge_type=json`` has been removed in version 4.0.0. Please
use ``kubernetes.core.k8s_json_patch`` instead (https://github.com/ansible-collections/kubernetes.core/pull/722).
- k8s_exec - the previously deprecated ``result.return_code`` return value has
been removed, consider using ``result.rc`` instead (https://github.com/ansible-collections/kubernetes.core/pull/726).
- module_utils/common.py - the previously deprecated ``K8sAnsibleMixin`` class
has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
- module_utils/common.py - the previously deprecated ``configuration_digest()``
function has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
- module_utils/common.py - the previously deprecated ``get_api_client()`` function
has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
- module_utils/common.py - the previously deprecated ``unique_string()`` function
has been removed (https://github.com/ansible-collections/kubernetes.core/pull/726).
fragments:
- 20231206-fix-unsafe-condition-in-integration.yml
- 20240117-fix-helm-diff-cmd-line-rendering.yml
- 20240222-Collections-util-resource-discovery-fails-when-complex-subresources-present.yml
- 20240228-fix-helm-diff-with-reuse-values.yml
- 20240423-k8s-display-warnings-to-users.yml
- 4.0.0.yaml
- inventory-update_removal_date.yml
- k8s-merge_type-removed.yml
- module_utils-common-remove-deprecated-functions-and-class.yaml
release_date: '2024-05-24'

View File

@@ -17,7 +17,7 @@ DEPRECATED
----------
:Removed in collection release after
:Why: As discussed in https://github.com/ansible-collections/kubernetes.core/issues/31, we decided to
remove the k8s inventory plugin in release 4.0.0.
remove the k8s inventory plugin in release 5.0.0.
:Alternative: Use :ref:`kubernetes.core.k8s_info <kubernetes.core.k8s_info_module>` and :ref:`ansible.builtin.add_host <ansible.builtin.add_host_module>` instead.
@@ -357,7 +357,7 @@ Status
------
- This inventory will be removed in version 4.0.0. *[deprecated]*
- This inventory will be removed in version 5.0.0. *[deprecated]*
- For more information see `DEPRECATED`_.

View File

@@ -121,7 +121,7 @@ Parameters
<td>
<div><code>apply</code> compares the desired resource definition with the previously supplied resource definition, ignoring properties that are automatically generated</div>
<div><code>apply</code> works better with Services than &#x27;force=yes&#x27;</div>
<div>mutually exclusive with <code>merge_type</code></div>
<div>Mutually exclusive with <code>merge_type</code>.</div>
</td>
</tr>
<tr>
@@ -513,18 +513,17 @@ Parameters
</td>
<td>
<ul style="margin: 0; padding: 0"><b>Choices:</b>
<li>json</li>
<li>merge</li>
<li>strategic-merge</li>
</ul>
</td>
<td>
<div>Whether to override the default patch merge approach with a specific type. By default, the strategic merge will typically be used.</div>
<div>For example, Custom Resource Definitions typically aren&#x27;t updatable by the usual strategic merge. You may want to use <code>merge</code> if you see &quot;strategic merge patch format is not supported&quot;</div>
<div>For example, Custom Resource Definitions typically aren&#x27;t updatable by the usual strategic merge. You may want to use <code>merge</code> if you see &quot;strategic merge patch format is not supported&quot;.</div>
<div>See <a href='https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/#use-a-json-merge-patch-to-update-a-deployment'>https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/#use-a-json-merge-patch-to-update-a-deployment</a></div>
<div>If more than one <code>merge_type</code> is given, the merge_types will be tried in order. This defaults to <code>[&#x27;strategic-merge&#x27;, &#x27;merge&#x27;]</code>, which is ideal for using the same parameters on resource kinds that combine Custom Resources and built-in resources.</div>
<div>mutually exclusive with <code>apply</code></div>
<div><em>merge_type=json</em> is deprecated and will be removed in version 3.0.0. Please use <span class='module'>kubernetes.core.k8s_json_patch</span> instead.</div>
<div>Mutually exclusive with <code>apply</code>.</div>
<div><em>merge_type=json</em> has been removed in version 4.0.0. Please use <span class='module'>kubernetes.core.k8s_json_patch</span> instead.</div>
</td>
</tr>
<tr>

View File

@@ -211,6 +211,27 @@ Parameters
<div>The configuration can be provided as dictionary. Added in version 2.4.0.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>kubectl_local_env_vars</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">dictionary</span>
</div>
<div style="font-style: italic; font-size: small; color: darkgreen">added in 3.1.0</div>
</td>
<td>
<b>Default:</b><br/><div style="color: blue">{}</div>
</td>
<td>
<div>var: ansible_kubectl_local_env_vars</div>
</td>
<td>
<div>Local enviromantal variable to be passed locally to the kubectl command line.</div>
<div>Please be aware that this passes information directly on the command line and it could expose sensitive data.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>

View File

@@ -77,6 +77,24 @@ Parameters
<div>If omitted, &#x27;.&#x27; is assumed.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>enable_helm</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">-</span>
</div>
</td>
<td>
<b>Default:</b><br/><div style="color: blue">"False"</div>
</td>
<td>
</td>
<td>
<div>Enable the helm chart inflation generator</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
@@ -112,17 +130,21 @@ Examples
.. code-block:: yaml
- name: Run lookup using kustomize
set_fact:
ansible.builtin.set_fact:
resources: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kustomize') }}"
- name: Run lookup using kubectl kustomize
set_fact:
ansible.builtin.set_fact:
resources: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kubectl') }}"
- name: Create kubernetes resources for lookup output
k8s:
kubernetes.core.k8s:
definition: "{{ lookup('kubernetes.core.kustomize', dir='/path/to/kustomization') }}"
- name: Create kubernetes resources for lookup output with `--enable-helm` set
kubernetes.core.k8s:
definition: "{{ lookup('kubernetes.core.kustomize', dir='/path/to/kustomization', enable_helm=True) }}"
Return Values

View File

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

View File

@@ -22,10 +22,10 @@ plugin_routing:
redirect: community.okd.openshift
k8s:
deprecation:
removal_version: 4.0.0
removal_version: 5.0.0
warning_text: >-
The k8s inventory plugin has been deprecated and
will be removed in release 4.0.0.
will be removed in release 5.0.0.
modules:
k8s_auth:
redirect: community.okd.k8s_auth

View File

@@ -72,6 +72,15 @@ DOCUMENTATION = r"""
- name: ansible_kubectl_extra_args
env:
- name: K8S_AUTH_EXTRA_ARGS
kubectl_local_env_vars:
description:
- Local enviromantal variable to be passed locally to the kubectl command line.
- Please be aware that this passes information directly on the command line and it could expose sensitive data.
default: {}
type: dict
version_added: 3.1.0
vars:
- name: ansible_kubectl_local_env_vars
kubectl_kubeconfig:
description:
- Path to a kubectl config file. Defaults to I(~/.kube/config)
@@ -301,6 +310,19 @@ class Connection(ConnectionBase):
return local_cmd, censored_local_cmd
def _local_env(self):
"""Return a dict of local environment variables to pass to the kubectl command"""
local_env = {}
local_local_env_vars_name = "{0}_local_env_vars".format(self.transport)
local_env_vars = self.get_option(local_local_env_vars_name)
if local_env_vars:
if isinstance(local_env_vars, dict):
local_env_vars = json.dumps(local_env_vars)
local_env = os.environ.copy()
local_env.update(json.loads(local_env_vars))
return local_env
return None
def _connect(self, port=None):
"""Connect to the container. Nothing to do"""
super(Connection, self)._connect()
@@ -329,6 +351,7 @@ class Connection(ConnectionBase):
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=self._local_env(),
)
stdout, stderr = p.communicate(in_data)
@@ -378,7 +401,11 @@ class Connection(ConnectionBase):
args = [to_bytes(i, errors="surrogate_or_strict") for i in args]
try:
p = subprocess.Popen(
args, stdin=in_file, stdout=subprocess.PIPE, stderr=subprocess.PIPE
args,
stdin=in_file,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=self._local_env(),
)
except OSError:
raise AnsibleError(
@@ -415,7 +442,11 @@ class Connection(ConnectionBase):
) as out_file:
try:
p = subprocess.Popen(
args, stdin=subprocess.PIPE, stdout=out_file, stderr=subprocess.PIPE
args,
stdin=subprocess.PIPE,
stdout=out_file,
stderr=subprocess.PIPE,
env=self._local_env(),
)
except OSError:
raise AnsibleError(

View File

@@ -36,12 +36,12 @@ options:
description:
- Provide a URL for accessing the API. Can also be specified via C(K8S_AUTH_HOST) environment variable.
type: str
version_added: "1.2.0"
version_added: 1.2.0
api_key:
description:
- Token used to authenticate with the API. Can also be specified via C(K8S_AUTH_API_KEY) environment variable.
type: str
version_added: "1.2.0"
version_added: 1.2.0
validate_certs:
description:
- Whether or not to verify the API server's SSL certificates. Can also be specified via C(K8S_AUTH_VERIFY_SSL)
@@ -49,12 +49,12 @@ options:
type: bool
aliases: [ verify_ssl ]
default: True
version_added: "1.2.0"
version_added: 1.2.0
ca_cert:
description:
- Path to a CA certificate used to authenticate with the API. The full certificate chain must be provided to
avoid certificate validation errors. Can also be specified via C(K8S_AUTH_SSL_CA_CERT) environment variable.
type: path
aliases: [ ssl_ca_cert ]
version_added: "1.2.0"
version_added: 1.2.0
"""

View File

@@ -15,7 +15,7 @@ class ModuleDocFragment(object):
options:
delete_options:
type: dict
version_added: '1.2.0'
version_added: 1.2.0
description:
- Configure behavior when deleting an object.
- Only used when I(state=absent).

View File

@@ -20,10 +20,10 @@ DOCUMENTATION = """
- Uses k8s.(yml|yaml) YAML configuration file to set parameter values.
deprecated:
removed_in: 4.0.0
removed_in: 5.0.0
why: |
As discussed in U(https://github.com/ansible-collections/kubernetes.core/issues/31), we decided to
remove the k8s inventory plugin in release 4.0.0.
remove the k8s inventory plugin in release 5.0.0.
alternative: "Use M(kubernetes.core.k8s_info) and M(ansible.builtin.add_host) instead."
options:
@@ -125,18 +125,18 @@ import json
from ansible.errors import AnsibleError
from ansible.plugins.inventory import BaseInventoryPlugin, Cacheable, Constructable
from ansible_collections.kubernetes.core.plugins.module_utils.common import (
HAS_K8S_MODULE_HELPER,
k8s_import_exception,
)
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
get_api_client,
)
try:
from kubernetes.dynamic.exceptions import DynamicApiError
except ImportError:
pass
HAS_K8S_MODULE_HELPER = True
k8s_import_exception = None
except ImportError as e:
HAS_K8S_MODULE_HELPER = False
k8s_import_exception = e
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
get_api_client,
)
def format_dynamic_api_exc(exc):
@@ -164,8 +164,8 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
super(InventoryModule, self).parse(inventory, loader, path)
self.display.deprecated(
"The 'k8s' inventory plugin has been deprecated and will be removed in release 4.0.0",
version="4.0.0",
"The 'k8s' inventory plugin has been deprecated and will be removed in release 5.0.0",
version="5.0.0",
collection_name="kubernetes.core",
)
cache_key = self._get_cache_prefix(path)

View File

@@ -8,7 +8,7 @@ DOCUMENTATION = """
short_description: Build a set of kubernetes resources using a 'kustomization.yaml' file.
version_added: "2.2.0"
version_added: 2.2.0
author:
- Aubin Bikouo (@abikouo)
@@ -30,6 +30,10 @@ DOCUMENTATION = """
opt_dirs:
description:
- An optional list of directories to search for the executable in addition to PATH.
enable_helm:
description:
- Enable the helm chart inflation generator
default: "False"
requirements:
- "python >= 3.6"
@@ -37,16 +41,20 @@ DOCUMENTATION = """
EXAMPLES = """
- name: Run lookup using kustomize
set_fact:
ansible.builtin.set_fact:
resources: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kustomize') }}"
- name: Run lookup using kubectl kustomize
set_fact:
ansible.builtin.set_fact:
resources: "{{ lookup('kubernetes.core.kustomize', binary_path='/path/to/kubectl') }}"
- name: Create kubernetes resources for lookup output
k8s:
kubernetes.core.k8s:
definition: "{{ lookup('kubernetes.core.kustomize', dir='/path/to/kustomization') }}"
- name: Create kubernetes resources for lookup output with `--enable-helm` set
kubernetes.core.k8s:
definition: "{{ lookup('kubernetes.core.kustomize', dir='/path/to/kustomization', enable_helm=True) }}"
"""
RETURN = """
@@ -91,7 +99,14 @@ def run_command(command):
class LookupModule(LookupBase):
def run(
self, terms, variables=None, dir=".", binary_path=None, opt_dirs=None, **kwargs
self,
terms,
variables=None,
dir=".",
binary_path=None,
opt_dirs=None,
enable_helm=False,
**kwargs
):
executable_path = binary_path
if executable_path is None:
@@ -122,6 +137,9 @@ class LookupModule(LookupBase):
)
)
if enable_helm:
command += ["--enable-helm"]
(out, err) = run_command(command)
if err:
raise AnsibleLookupError(

View File

@@ -149,6 +149,7 @@ def k8s_apply(resource, definition, **kwargs):
force_conflicts=kwargs.get("force_conflicts"),
field_manager=kwargs.get("field_manager"),
dry_run=kwargs.get("dry_run"),
serialize=kwargs.get("serialize"),
)
if not existing:
return resource.create(
@@ -158,6 +159,7 @@ def k8s_apply(resource, definition, **kwargs):
return resource.get(
name=definition["metadata"]["name"],
namespace=definition["metadata"].get("namespace"),
**kwargs
)
return resource.patch(
body=desired,

File diff suppressed because it is too large Load Diff

View File

@@ -115,7 +115,7 @@ class AnsibleHelmModule(object):
kubeconfig = self.params.get("kubeconfig")
if kubeconfig:
if isinstance(kubeconfig, string_types):
with open(kubeconfig) as fd:
with open(os.path.expanduser(kubeconfig)) as fd:
kubeconfig_content = yaml.safe_load(fd)
elif isinstance(kubeconfig, dict):
kubeconfig_content = kubeconfig

View File

@@ -139,6 +139,7 @@ def perform_action(svc, definition: Dict, params: Dict) -> Dict:
result = {"changed": False, "result": {}}
instance = {}
warnings = []
resource = svc.find_resource(kind, api_version, fail=True)
definition["kind"] = resource.kind
@@ -172,7 +173,7 @@ def perform_action(svc, definition: Dict, params: Dict) -> Dict:
return result
if params.get("apply"):
instance = svc.apply(resource, definition, existing)
instance, warnings = svc.apply(resource, definition, existing)
result["method"] = "apply"
elif not existing:
if state == "patched":
@@ -183,16 +184,19 @@ def perform_action(svc, definition: Dict, params: Dict) -> Dict:
)
)
return result
instance = svc.create(resource, definition)
instance, warnings = svc.create(resource, definition)
result["method"] = "create"
result["changed"] = True
elif params.get("force", False):
instance = svc.replace(resource, definition, existing)
instance, warnings = svc.replace(resource, definition, existing)
result["method"] = "replace"
else:
instance = svc.update(resource, definition, existing)
instance, warnings = svc.update(resource, definition, existing)
result["method"] = "update"
if warnings:
result["warnings"] = warnings
# If needed, wait and/or create diff
success = True

View File

@@ -2,6 +2,8 @@
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
import copy
from json import loads
from re import compile
from typing import Any, Dict, List, Optional, Tuple
from ansible.module_utils.common.dict_transformations import dict_merge
@@ -142,18 +144,12 @@ class K8sService:
name: str,
namespace: str,
merge_type: str = None,
) -> Dict:
if merge_type == "json":
self.module.deprecate(
msg="json as a merge_type value is deprecated. Please use the k8s_json_patch module instead.",
version="4.0.0",
collection_name="kubernetes.core",
)
) -> Tuple[Dict, List[str]]:
try:
params = dict(name=name, namespace=namespace)
params = dict(name=name, namespace=namespace, serialize=False)
if merge_type:
params["content_type"] = "application/{0}-patch+json".format(merge_type)
return self.client.patch(resource, definition, **params).to_dict()
return decode_response(self.client.patch(resource, definition, **params))
except Exception as e:
reason = e.body if hasattr(e, "body") else e
msg = "Failed to patch object: {0}".format(reason)
@@ -330,123 +326,124 @@ class K8sService:
result["resources"].append(hide_fields(res, hidden_fields))
return result
def create(self, resource: Resource, definition: Dict) -> Dict:
def create(self, resource: Resource, definition: Dict) -> Tuple[Dict, List[str]]:
namespace = definition["metadata"].get("namespace")
name = definition["metadata"].get("name")
if self._client_side_dry_run:
k8s_obj = _encode_stringdata(definition)
else:
try:
k8s_obj = self.client.create(
resource, definition, namespace=namespace
).to_dict()
except ConflictError:
# Some resources, like ProjectRequests, can't be created multiple times,
# because the resources that they create don't match their kind
# In this case we'll mark it as unchanged and warn the user
self.module.warn(
"{0} was not found, but creating it returned a 409 Conflict error. This can happen \
if the resource you are creating does not directly create a resource of the same kind.".format(
name
)
return _encode_stringdata(definition), []
try:
return decode_response(
self.client.create(
resource, definition, namespace=namespace, serialize=False
)
return dict()
except Exception as e:
reason = e.body if hasattr(e, "body") else e
msg = "Failed to create object: {0}".format(reason)
raise CoreException(msg) from e
return k8s_obj
)
except ConflictError:
# Some resources, like ProjectRequests, can't be created multiple times,
# because the resources that they create don't match their kind
# In this case we'll mark it as unchanged and warn the user
self.module.warn(
"{0} was not found, but creating it returned a 409 Conflict error. This can happen \
if the resource you are creating does not directly create a resource of the same kind.".format(
name
)
)
return dict(), []
except Exception as e:
reason = e.body if hasattr(e, "body") else e
msg = "Failed to create object: {0}".format(reason)
raise CoreException(msg) from e
def apply(
self,
resource: Resource,
definition: Dict,
existing: Optional[ResourceInstance] = None,
) -> Dict:
) -> Tuple[Dict, List[str]]:
namespace = definition["metadata"].get("namespace")
server_side_apply = self.module.params.get("server_side_apply")
if server_side_apply:
requires("kubernetes", "19.15.0", reason="to use server side apply")
if self._client_side_dry_run:
ignored, patch = apply_object(resource, _encode_stringdata(definition))
if existing:
k8s_obj = dict_merge(existing.to_dict(), patch)
return dict_merge(existing.to_dict(), patch), []
else:
k8s_obj = patch
else:
try:
params = {}
if server_side_apply:
params["server_side"] = True
params.update(server_side_apply)
k8s_obj = self.client.apply(
resource, definition, namespace=namespace, **params
).to_dict()
except Exception as e:
reason = e.body if hasattr(e, "body") else e
msg = "Failed to apply object: {0}".format(reason)
raise CoreException(msg) from e
return k8s_obj
return patch, []
try:
params = {}
if server_side_apply:
params["server_side"] = True
params.update(server_side_apply)
return decode_response(
self.client.apply(
resource, definition, namespace=namespace, serialize=False, **params
)
)
except Exception as e:
reason = e.body if hasattr(e, "body") else e
msg = "Failed to apply object: {0}".format(reason)
raise CoreException(msg) from e
def replace(
self,
resource: Resource,
definition: Dict,
existing: ResourceInstance,
) -> Dict:
) -> Tuple[Dict, List[str]]:
append_hash = self.module.params.get("append_hash", False)
name = definition["metadata"].get("name")
namespace = definition["metadata"].get("namespace")
if self._client_side_dry_run:
k8s_obj = _encode_stringdata(definition)
else:
try:
k8s_obj = self.client.replace(
return _encode_stringdata(definition), []
try:
return decode_response(
self.client.replace(
resource,
definition,
name=name,
namespace=namespace,
append_hash=append_hash,
).to_dict()
except Exception as e:
reason = e.body if hasattr(e, "body") else e
msg = "Failed to replace object: {0}".format(reason)
raise CoreException(msg) from e
return k8s_obj
serialize=False,
)
)
except Exception as e:
reason = e.body if hasattr(e, "body") else e
msg = "Failed to replace object: {0}".format(reason)
raise CoreException(msg) from e
def update(
self, resource: Resource, definition: Dict, existing: ResourceInstance
) -> Dict:
) -> Tuple[Dict, List[str]]:
name = definition["metadata"].get("name")
namespace = definition["metadata"].get("namespace")
if self._client_side_dry_run:
k8s_obj = dict_merge(existing.to_dict(), _encode_stringdata(definition))
else:
exception = None
for merge_type in self.module.params.get("merge_type") or [
"strategic-merge",
"merge",
]:
try:
k8s_obj = self.patch_resource(
resource,
definition,
name,
namespace,
merge_type=merge_type,
)
exception = None
except CoreException as e:
exception = e
continue
break
if exception:
raise exception
return k8s_obj
return dict_merge(existing.to_dict(), _encode_stringdata(definition)), []
exception = None
for merge_type in self.module.params.get("merge_type") or [
"strategic-merge",
"merge",
]:
try:
return self.patch_resource(
resource,
definition,
name,
namespace,
merge_type=merge_type,
)
except CoreException as e:
exception = e
continue
raise exception
def delete(
self,
@@ -543,3 +540,83 @@ def hide_field(definition: dict, hidden_field: str) -> dict:
else:
del definition[split[0]]
return definition
def decode_response(resp) -> Tuple[Dict, List[str]]:
"""
This function decodes unserialized responses from the Kubernetes python
client and decodes the RFC2616 14.46 warnings found in the response
headers.
"""
obj = ResourceInstance(None, loads(resp.data.decode("utf8"))).to_dict()
warnings = []
if (
resp.headers is not None
and "warning" in resp.headers
and resp.headers["warning"] is not None
):
warnings = resp.headers["warning"].split(", ")
return obj, decode_warnings(warnings)
def decode_warnings(warnings: str) -> List[str]:
"""
This function decodes RFC2616 14.46 warnings in a simplified way, where
only the warn-texts are returned in a list.
"""
p = compile('\\d{3} .+ (".+")')
decoded = []
for warning in warnings:
m = p.match(warning)
if m:
try:
parsed, unused = parse_quoted_string(m.group(1))
decoded.append(parsed)
except ValueError:
continue
return decoded
def parse_quoted_string(quoted_string: str) -> Tuple[str, str]:
"""
This function was adapted from:
https://github.com/kubernetes/apimachinery/blob/bb8822152cabfb4f34dbc26270f874ce53db50de/pkg/util/net/http.go#L609
"""
if len(quoted_string) == 0:
raise ValueError("invalid quoted string: 0-length")
if quoted_string[0] != '"':
raise ValueError("invalid quoted string: missing initial quote")
quoted_string = quoted_string[1:]
remainder = ""
escaping = False
closed_quote = False
result = []
for i, b in enumerate(quoted_string):
if b == '"':
if escaping:
result.append(b)
escaping = False
else:
closed_quote = True
remainder_start = i + 1
remainder = quoted_string[remainder_start:].strip()
break
elif b == "\\":
if escaping:
result.append(b)
escaping = False
else:
escaping = True
else:
result.append(b)
escaping = False
if not closed_quote:
raise ValueError("invalid quoted string: missing closing quote")
return "".join(result), remainder

View File

@@ -14,7 +14,7 @@ module: helm
short_description: Manages Kubernetes packages with the Helm package manager
version_added: "0.11.0"
version_added: 0.11.0
author:
- Lucas Boisserie (@LucasBoisserie)
@@ -61,7 +61,7 @@ options:
default: false
type: bool
aliases: [ dep_up ]
version_added: "2.4.0"
version_added: 2.4.0
release_name:
description:
- Release name to manage.
@@ -99,7 +99,7 @@ options:
default: []
type: list
elements: str
version_added: '1.1.0'
version_added: 1.1.0
update_repo_cache:
description:
- Run C(helm repo update) before the operation. Can be run as part of the package installation or as a separate step (see Examples).
@@ -129,7 +129,7 @@ options:
- string
- json
- file
version_added: '2.4.0'
version_added: 2.4.0
reuse_values:
description:
- When upgrading package, specifies wether to reuse the last release's values and merge in any overrides from parameters I(release_values),
@@ -137,14 +137,14 @@ options:
- If I(reset_values) is set to C(True), this is ignored.
type: bool
required: false
version_added: '2.5.0'
version_added: 2.5.0
reset_values:
description:
- When upgrading package, reset the values to the ones built into the chart.
type: bool
required: false
default: True
version_added: '2.5.0'
version_added: 2.5.0
#Helm options
disable_hook:
@@ -181,7 +181,7 @@ options:
- similar to C(wait_timeout) but does not required C(wait) to be activated.
- Mutually exclusive with C(wait_timeout).
type: str
version_added: "2.3.0"
version_added: 2.3.0
atomic:
description:
- If set, the installation process deletes the installation on failure.
@@ -192,12 +192,12 @@ options:
- Create the release namespace if not present.
type: bool
default: False
version_added: "0.11.1"
version_added: 0.11.1
post_renderer:
description:
- Path to an executable to be used for post rendering.
type: str
version_added: "2.4.0"
version_added: 2.4.0
replace:
description:
- Reuse the given name, only if that name is a deleted release which remains in the history.
@@ -205,19 +205,19 @@ options:
- mutually exclusive with with C(history_max).
type: bool
default: False
version_added: "1.11.0"
version_added: 1.11.0
skip_crds:
description:
- Skip custom resource definitions when installing or upgrading.
type: bool
default: False
version_added: "1.2.0"
version_added: 1.2.0
history_max:
description:
- Limit the maximum number of revisions saved per release.
- mutually exclusive with with C(replace).
type: int
version_added: "2.2.0"
version_added: 2.2.0
extends_documentation_fragment:
- kubernetes.core.helm_common_options
"""

View File

@@ -14,7 +14,7 @@ module: helm_info
short_description: Get information from Helm package deployed inside the cluster
version_added: "0.11.0"
version_added: 0.11.0
author:
- Lucas Boisserie (@LucasBoisserie)
@@ -53,7 +53,7 @@ options:
type: list
elements: str
default: []
version_added: "2.3.0"
version_added: 2.3.0
get_all_values:
description:
- Set to C(True) if you want to get all (computed) values of the release.
@@ -61,7 +61,7 @@ options:
required: false
default: false
type: bool
version_added: "2.4.0"
version_added: 2.4.0
extends_documentation_fragment:
- kubernetes.core.helm_common_options
"""
@@ -123,18 +123,18 @@ status:
elements: dict
description: Hooks of the release
returned: always
version_added: "2.4.0"
version_added: 2.4.0
notes:
type: str
description: Notes of the release
returned: always
version_added: "2.4.0"
version_added: 2.4.0
manifest:
type: list
elements: dict
description: Manifest of the release
returned: always
version_added: "2.4.0"
version_added: 2.4.0
"""
import copy

View File

@@ -12,7 +12,7 @@ DOCUMENTATION = r"""
---
module: helm_plugin
short_description: Manage Helm plugins
version_added: "1.0.0"
version_added: 1.0.0
author:
- Abhijeet Kasurde (@Akasurde)
requirements:
@@ -47,7 +47,7 @@ options:
- Ignored when C(state=absent) or C(state=latest).
required: false
type: str
version_added: "2.3.0"
version_added: 2.3.0
extends_documentation_fragment:
- kubernetes.core.helm_common_options
"""

View File

@@ -12,7 +12,7 @@ DOCUMENTATION = r"""
---
module: helm_plugin_info
short_description: Gather information about Helm plugins
version_added: "1.0.0"
version_added: 1.0.0
author:
- Abhijeet Kasurde (@Akasurde)
requirements:

View File

@@ -12,7 +12,7 @@ DOCUMENTATION = r"""
---
module: helm_pull
short_description: download a chart from a repository and (optionally) unpack it in local directory.
version_added: "2.4.0"
version_added: 2.4.0
author:
- Aubin Bikouo (@abikouo)
description:

View File

@@ -14,7 +14,7 @@ module: helm_repository
short_description: Manage Helm repositories.
version_added: "0.11.0"
version_added: 0.11.0
author:
- Lucas Boisserie (@LucasBoisserie)
@@ -76,12 +76,12 @@ options:
description:
- Provide a URL for accessing the API. Can also be specified via C(K8S_AUTH_HOST) environment variable.
type: str
version_added: "2.3.0"
version_added: 2.3.0
api_key:
description:
- Token used to authenticate with the API. Can also be specified via C(K8S_AUTH_API_KEY) environment variable.
type: str
version_added: "2.3.0"
version_added: 2.3.0
validate_certs:
description:
- Whether or not to verify the API server's SSL certificates. Can also be specified via C(K8S_AUTH_VERIFY_SSL)
@@ -89,21 +89,21 @@ options:
type: bool
aliases: [ verify_ssl ]
default: True
version_added: "2.3.0"
version_added: 2.3.0
ca_cert:
description:
- Path to a CA certificate used to authenticate with the API. The full certificate chain must be provided to
avoid certificate validation errors. Can also be specified via C(K8S_AUTH_SSL_CA_CERT) environment variable.
type: path
aliases: [ ssl_ca_cert ]
version_added: "2.3.0"
version_added: 2.3.0
context:
description:
- Helm option to specify which kubeconfig context to use.
- If the value is not specified in the task, the value of environment variable C(K8S_AUTH_CONTEXT) will be used instead.
type: str
aliases: [ kube_context ]
version_added: "2.4.0"
version_added: 2.4.0
kubeconfig:
description:
- Helm option to specify kubeconfig path to use.
@@ -111,14 +111,14 @@ options:
- The configuration can be provided as dictionary.
type: raw
aliases: [ kubeconfig_path ]
version_added: "2.4.0"
version_added: 2.4.0
force_update:
description:
- Whether or not to replace (overwrite) the repo if it already exists.
type: bool
aliases: [ force ]
default: False
version_added: "2.4.0"
version_added: 2.4.0
"""
EXAMPLES = r"""

View File

@@ -53,7 +53,7 @@ options:
default: false
type: bool
aliases: [ dep_up ]
version_added: "2.4.0"
version_added: 2.4.0
disable_hook:
description:
- Prevent hooks from running during install.
@@ -139,7 +139,7 @@ options:
- string
- json
- file
version_added: '2.4.0'
version_added: 2.4.0
"""
EXAMPLES = r"""

View File

@@ -57,15 +57,14 @@ options:
- Whether to override the default patch merge approach with a specific type. By default, the strategic
merge will typically be used.
- For example, Custom Resource Definitions typically aren't updatable by the usual strategic merge. You may
want to use C(merge) if you see "strategic merge patch format is not supported"
want to use C(merge) if you see "strategic merge patch format is not supported".
- See U(https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/#use-a-json-merge-patch-to-update-a-deployment)
- If more than one C(merge_type) is given, the merge_types will be tried in order. This defaults to
C(['strategic-merge', 'merge']), which is ideal for using the same parameters on resource kinds that
combine Custom Resources and built-in resources.
- mutually exclusive with C(apply)
- I(merge_type=json) is deprecated and will be removed in version 3.0.0. Please use M(kubernetes.core.k8s_json_patch) instead.
- Mutually exclusive with C(apply).
- I(merge_type=json) has been removed in version 4.0.0. Please use M(kubernetes.core.k8s_json_patch) instead.
choices:
- json
- merge
- strategic-merge
type: list
@@ -101,7 +100,7 @@ options:
- C(apply) compares the desired resource definition with the previously supplied resource definition,
ignoring properties that are automatically generated
- C(apply) works better with Services than 'force=yes'
- mutually exclusive with C(merge_type)
- Mutually exclusive with C(merge_type).
default: False
type: bool
template:
@@ -460,7 +459,7 @@ def argspec():
argument_spec.update(copy.deepcopy(AUTH_ARG_SPEC))
argument_spec.update(copy.deepcopy(WAIT_ARG_SPEC))
argument_spec["merge_type"] = dict(
type="list", elements="str", choices=["json", "merge", "strategic-merge"]
type="list", elements="str", choices=["merge", "strategic-merge"]
)
argument_spec["validate"] = dict(type="dict", default=None, options=validate_spec())
argument_spec["append_hash"] = dict(type="bool", default=False)

View File

@@ -11,7 +11,7 @@ __metaclass__ = type
DOCUMENTATION = r"""
module: k8s_cluster_info
version_added: "0.11.1"
version_added: 0.11.1
short_description: Describe Kubernetes (K8s) cluster, APIs available and their respective versions

View File

@@ -14,7 +14,7 @@ module: k8s_cp
short_description: Copy files and directories to and from pod.
version_added: "2.2.0"
version_added: 2.2.0
author:
- Aubin Bikouo (@abikouo)

View File

@@ -15,7 +15,7 @@ module: k8s_drain
short_description: Drain, Cordon, or Uncordon node in k8s cluster
version_added: "2.2.0"
version_added: 2.2.0
author: Aubin Bikouo (@abikouo)

View File

@@ -15,7 +15,7 @@ module: k8s_exec
short_description: Execute command in Pod
version_added: "0.10.0"
version_added: 0.10.0
author: "Tristan de Cacqueray (@tristanC)"
@@ -135,7 +135,7 @@ from ansible.module_utils._text import to_native
from ansible_collections.kubernetes.core.plugins.module_utils.ansiblemodule import (
AnsibleModule,
)
from ansible_collections.kubernetes.core.plugins.module_utils.common import (
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (
AUTH_ARG_SPEC,
)
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.client import (
@@ -219,12 +219,6 @@ def execute_module(module, client):
else:
rc = int(err["details"]["causes"][0]["message"])
module.deprecate(
"The 'return_code' return key is being renamed to 'rc'. "
"Both keys are being returned for now to allow users to migrate their automation.",
version="4.0.0",
collection_name="kubernetes.core",
)
module.exit_json(
# Some command might change environment, but ultimately failing at end
changed=True,

View File

@@ -14,7 +14,7 @@ module: k8s_log
short_description: Fetch logs from Kubernetes resources
version_added: "0.10.0"
version_added: 0.10.0
author:
- "Fabian von Feilitzsch (@fabianvf)"
@@ -61,26 +61,26 @@ options:
- A relative time in seconds before the current time from which to show logs.
required: no
type: str
version_added: '2.2.0'
version_added: 2.2.0
previous:
description:
- If C(true), print the logs for the previous instance of the container in a pod if it exists.
required: no
type: bool
default: False
version_added: '2.4.0'
version_added: 2.4.0
tail_lines:
description:
- A number of lines from the end of the logs to retrieve.
required: no
type: int
version_added: '2.4.0'
version_added: 2.4.0
all_containers:
description:
- If set to C(true), retrieve all containers' logs in the pod(s).
- mutually exclusive with C(container).
type: bool
version_added: '2.4.0'
version_added: 2.4.0
requirements:
- "python >= 3.9"

View File

@@ -12,7 +12,7 @@ __metaclass__ = type
DOCUMENTATION = r"""
module: k8s_rollback
short_description: Rollback Kubernetes (K8S) Deployments and DaemonSets
version_added: "1.0.0"
version_added: 1.0.0
author:
- "Julien Huon (@julienhuon)"
description:

View File

@@ -13,7 +13,7 @@ __metaclass__ = type
DOCUMENTATION = r"""
module: k8s_taint
short_description: Taint a node in a Kubernetes/OpenShift cluster
version_added: "2.3.0"
version_added: 2.3.0
author: Alina Buzachis (@alinabuzachis)
description:
- Taint allows a node to refuse Pod to be scheduled unless that Pod has a matching toleration.

View File

@@ -73,7 +73,7 @@
assert:
that:
- install is changed
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
- install.status.chart == chart_test+"-"+chart_test_version
- install.status.status | lower == 'deployed'
- name: Check helm_info content
@@ -95,7 +95,7 @@
- name: "Assert that {{ chart_test }} is installed from {{ source }} with helm_info"
assert:
that:
- content_info.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
- content_info.status.chart == chart_test+"-"+chart_test_version
- content_info.status.status | lower == 'deployed'
- release_state_content_info.status.status | lower == 'deployed'
@@ -112,7 +112,7 @@
assert:
that:
- install is not changed
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
- install.status.chart == chart_test+"-"+chart_test_version
- install.status.status | lower == 'deployed'
- name: "Add vars to {{ chart_test }} from {{ source }}"
@@ -130,7 +130,7 @@
that:
- install is changed
- install.status.status | lower == 'deployed'
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
- install.status.chart == chart_test+"-"+chart_test_version
- "install.status['values'].revisionHistoryLimit == 0"
- name: Check idempotency after adding vars
@@ -148,7 +148,7 @@
that:
- install is not changed
- install.status.status | lower == 'deployed'
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
- install.status.chart == chart_test+"-"+chart_test_version
- "install.status['values'].revisionHistoryLimit == 0"
- name: "Remove Vars to {{ chart_test }} from {{ source }}"
@@ -165,7 +165,7 @@
that:
- install is changed
- install.status.status | lower == 'deployed'
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
- install.status.chart == chart_test+"-"+chart_test_version
- install.status['values'] == {}
- name: Check idempotency after removing vars
@@ -182,7 +182,7 @@
that:
- install is not changed
- install.status.status | lower == 'deployed'
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
- install.status.chart == chart_test+"-"+chart_test_version
- install.status['values'] == {}
- name: "Upgrade {{ chart_test }} from {{ source }}"
@@ -199,7 +199,7 @@
that:
- install is changed
- install.status.status | lower == 'deployed'
- install.status.chart == "{{ chart_test }}-{{ chart_test_version_upgrade }}"
- install.status.chart == chart_test+"-"+chart_test_version_upgrade
- name: Check idempotency after upgrade
helm:
@@ -215,7 +215,7 @@
that:
- install is not changed
- install.status.status | lower == 'deployed'
- install.status.chart == "{{ chart_test }}-{{ chart_test_version_upgrade }}"
- install.status.chart == chart_test+"-"+chart_test_version_upgrade
- name: "Remove {{ chart_test }} from {{ source }}"
helm:
@@ -316,7 +316,7 @@
that:
- install is changed
- install.status.status | lower == 'deployed'
- install.status.chart == "{{ chart_test }}-{{ chart_test_version }}"
- install.status.chart == chart_test+"-"+chart_test_version
- "install.status['values'].revisionHistoryLimit == 0"
- name: "Install {{ chart_test }} from {{ source }} with values_files (again)"
@@ -357,7 +357,7 @@
- result is changed
- result is not failed
- result.rc == 0
- result.command is match("{{ helm_binary }} template {{ chart_source }}")
- result.command is match(helm_binary+" template "+chart_source)
- name: Check templates created
stat:
@@ -388,7 +388,7 @@
- result is changed
- result is not failed
- result.rc == 0
- result.command is match("{{ helm_binary }} template MyRelease {{ chart_source }}")
- result.command is match(helm_binary+" template MyRelease "+chart_source)
- result.stdout is search("ThisValue")
when: chart_source is search("test-chart")
# limit assertion of test result to controlled (local) chart_source

View File

@@ -182,7 +182,7 @@
- name: assert that pods are running on cordoned node
assert:
that:
- "{{ Pod.resources | selectattr('status.phase', 'equalto', 'Running') | selectattr('spec.nodeName', 'equalto', node_to_drain) | list | length > 0 }}"
- Pod.resources | selectattr('status.phase', 'equalto', 'Running') | selectattr('spec.nodeName', 'equalto', node_to_drain) | list | length > 0
- name: Uncordon node
k8s_drain:
@@ -236,7 +236,7 @@
assert:
that:
- drain_result is changed
- '"node {{ node_to_drain }} marked unschedulable." in drain_result.result'
- '"node "+node_to_drain+" marked unschedulable." in drain_result.result'
- name: assert that unmanaged pod were deleted
k8s_info:
@@ -338,7 +338,7 @@
assert:
that:
- disable_evict is changed
- '"node {{ node_to_drain }} marked unschedulable." in disable_evict.result'
- '"node "+node_to_drain+" marked unschedulable." in disable_evict.result'
- name: assert that unmanaged pod were deleted
k8s_info:
@@ -401,7 +401,7 @@
assert:
that:
- drain_pod_selector is changed
- '"node {{ node_to_drain }} marked unschedulable." in drain_pod_selector.result'
- '"node "+node_to_drain+" marked unschedulable." in drain_pod_selector.result'
- name: assert that pod created before is still running
k8s_info:
@@ -429,8 +429,8 @@
assert:
that:
- drain_pod_selector_equal is changed
- '"node {{ node_to_drain }} already marked unschedulable." in drain_pod_selector_equal.result'
- '"Deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: {{ test_namespace }}/ansible-drain-pod." in drain_pod_selector_equal.warnings'
- '"node "+node_to_drain+" already marked unschedulable." in drain_pod_selector_equal.result'
- '"Deleting Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet: "+test_namespace+"/ansible-drain-pod." in drain_pod_selector_equal.warnings'
- name: Uncordon node
k8s_drain:

View File

@@ -424,7 +424,7 @@
- assert:
that:
- result.resources[0].data.testkey == "{{ cmap_data.stdout | b64encode }}"
- result.resources[0].data.testkey == (cmap_data.stdout | b64encode)
# test setting module defaults for kubernetes.core.k8s_info
- block:

View File

@@ -69,7 +69,7 @@
- name: assert pod has been created
assert:
that:
- "{{ pods.resources | length == 1 }}"
- pods.resources | length == 1
- name: create pod using generate_name parameter should succeed
k8s:
@@ -86,7 +86,7 @@
- name: assert pod has been created
assert:
that:
- "{{ pods.resources | length == 2 }}"
- pods.resources | length == 2
- name: create pod using metadata.generateName parameter should succeed
k8s:
@@ -102,7 +102,7 @@
- name: assert pod has been created
assert:
that:
- "{{ pods.resources | length == 3 }}"
- pods.resources | length == 3
- name: create object using metadata.generateName should support wait option
k8s:

View File

@@ -192,7 +192,7 @@
- name: Check that module waited
assert:
that:
- "{{ lookup('pipe', 'date +%s') }} - {{ start }} > 30"
- ( lookup('pipe', 'date +%s')|int - start|int ) > 30
- name: Create simple pod
k8s:

View File

@@ -11,7 +11,7 @@
assert:
that:
- fake_pod is failed
- 'fake_pod.msg == "Pod {{ test_namespace }}/this_pod_does_exist not found."'
- fake_pod.msg == "Pod "+test_namespace+"/this_pod_does_exist not found."
- name: create hello-world deployment
k8s:

View File

@@ -65,7 +65,7 @@
assert:
that:
- _result.result.status.phase == 'Running'
- _result.result.spec.nodeName == "{{ node_to_taint }}"
- _result.result.spec.nodeName == node_to_taint
- name: Taint node (check_mode)
kubernetes.core.k8s_taint:
@@ -89,8 +89,8 @@
assert:
that:
- _result.changed
- "{{ item['effect'] == taint_patch_1[0]['effect'] }}"
- "{{ item['key'] == taint_patch_1[0]['key'] }}"
- item['effect'] == taint_patch_1[0]['effect']
- item['key'] == taint_patch_1[0]['key']
loop: "{{ _result.result.spec.taints }}"
- name: Taint node (idempotency) - (check_mode)

View File

@@ -213,8 +213,8 @@
- name: check that resources creation failed
assert:
that:
- '{{ resource.results[0].resources | length == 0 }}'
- '{{ resource.results[1].resources | length == 0 }}'
- resource.results.0.resources | length == 0
- resource.results.1.resources | length == 0
- name: create pod without namespace (continue_on_error = true)
kubernetes.core.k8s:

View File

@@ -130,9 +130,9 @@
assert:
that:
- result_configmap.apiVersion == 'v1'
- result_configmap.metadata.name == "{{ configmap_name }}"
- result_configmap.metadata.namespace == "{{ test_namespace[2] }}"
- result_configmap.data.value == "{{ configmap_data }}"
- result_configmap.metadata.name == configmap_name
- result_configmap.metadata.namespace == test_namespace[2]
- result_configmap.data.value == configmap_data
# test lookup plugin using src parameter
- block:
@@ -159,9 +159,9 @@
assert:
that:
- src_configmap.apiVersion == 'v1'
- src_configmap.metadata.name == "{{ configmap_name }}"
- src_configmap.metadata.namespace == "{{ test_namespace[2] }}"
- src_configmap.data.value == "{{ configmap_data }}"
- src_configmap.metadata.name == configmap_name
- src_configmap.metadata.namespace == test_namespace[2]
- src_configmap.data.value == configmap_data
always:
- name: Delete temporary file created
@@ -198,9 +198,9 @@
assert:
that:
- configmap_no_ssl.apiVersion == 'v1'
- configmap_no_ssl.metadata.name == "{{ configmap_name }}"
- configmap_no_ssl.metadata.namespace == "{{ test_namespace[2] }}"
- configmap_no_ssl.data.value == "{{ configmap_data }}"
- configmap_no_ssl.metadata.name == configmap_name
- configmap_no_ssl.metadata.namespace == test_namespace[2]
- configmap_no_ssl.data.value == configmap_data
- name: Retrieve configmap using authentication aliases (validate_certs=true)
set_fact:
@@ -210,9 +210,9 @@
assert:
that:
- configmap_with_ssl.apiVersion == 'v1'
- configmap_with_ssl.metadata.name == "{{ configmap_name }}"
- configmap_with_ssl.metadata.namespace == "{{ test_namespace[2] }}"
- configmap_with_ssl.data.value == "{{ configmap_data }}"
- configmap_with_ssl.metadata.name == configmap_name
- configmap_with_ssl.metadata.namespace == test_namespace[2]
- configmap_with_ssl.data.value == configmap_data
always:
- name: Delete temporary directory

View File

@@ -1,18 +1,9 @@
plugins/module_utils/client/discovery.py import-3.6!skip
plugins/module_utils/client/discovery.py import-3.7!skip
plugins/module_utils/client/discovery.py import-3.8!skip
plugins/module_utils/client/discovery.py import-3.9!skip
plugins/module_utils/client/discovery.py import-3.10!skip
plugins/module_utils/client/discovery.py import-3.11!skip
plugins/module_utils/client/resource.py import-3.6!skip
plugins/module_utils/client/resource.py import-3.7!skip
plugins/module_utils/client/resource.py import-3.8!skip
plugins/module_utils/client/resource.py import-3.9!skip
plugins/module_utils/client/resource.py import-3.10!skip
plugins/module_utils/client/resource.py import-3.11!skip
plugins/module_utils/k8sdynamicclient.py import-3.6!skip
plugins/module_utils/k8sdynamicclient.py import-3.7!skip
plugins/module_utils/k8sdynamicclient.py import-3.8!skip
plugins/module_utils/k8sdynamicclient.py import-3.9!skip
plugins/module_utils/k8sdynamicclient.py import-3.10!skip
plugins/module_utils/k8sdynamicclient.py import-3.11!skip

View File

@@ -1,18 +1,9 @@
plugins/module_utils/client/discovery.py import-3.6!skip
plugins/module_utils/client/discovery.py import-3.7!skip
plugins/module_utils/client/discovery.py import-3.8!skip
plugins/module_utils/client/discovery.py import-3.9!skip
plugins/module_utils/client/discovery.py import-3.10!skip
plugins/module_utils/client/discovery.py import-3.11!skip
plugins/module_utils/client/resource.py import-3.6!skip
plugins/module_utils/client/resource.py import-3.7!skip
plugins/module_utils/client/resource.py import-3.8!skip
plugins/module_utils/client/resource.py import-3.9!skip
plugins/module_utils/client/resource.py import-3.10!skip
plugins/module_utils/client/resource.py import-3.11!skip
plugins/module_utils/k8sdynamicclient.py import-3.6!skip
plugins/module_utils/k8sdynamicclient.py import-3.7!skip
plugins/module_utils/k8sdynamicclient.py import-3.8!skip
plugins/module_utils/k8sdynamicclient.py import-3.9!skip
plugins/module_utils/k8sdynamicclient.py import-3.10!skip
plugins/module_utils/k8sdynamicclient.py import-3.11!skip

View File

@@ -1,20 +1,11 @@
plugins/module_utils/client/discovery.py import-3.6!skip
plugins/module_utils/client/discovery.py import-3.7!skip
plugins/module_utils/client/discovery.py import-3.8!skip
plugins/module_utils/client/discovery.py import-3.9!skip
plugins/module_utils/client/discovery.py import-3.10!skip
plugins/module_utils/client/discovery.py import-3.11!skip
plugins/module_utils/client/discovery.py import-3.12!skip
plugins/module_utils/client/resource.py import-3.6!skip
plugins/module_utils/client/resource.py import-3.7!skip
plugins/module_utils/client/resource.py import-3.8!skip
plugins/module_utils/client/resource.py import-3.9!skip
plugins/module_utils/client/resource.py import-3.10!skip
plugins/module_utils/client/resource.py import-3.11!skip
plugins/module_utils/client/resource.py import-3.12!skip
plugins/module_utils/k8sdynamicclient.py import-3.6!skip
plugins/module_utils/k8sdynamicclient.py import-3.7!skip
plugins/module_utils/k8sdynamicclient.py import-3.8!skip
plugins/module_utils/k8sdynamicclient.py import-3.9!skip
plugins/module_utils/k8sdynamicclient.py import-3.10!skip
plugins/module_utils/k8sdynamicclient.py import-3.11!skip

View File

@@ -0,0 +1,31 @@
plugins/module_utils/client/discovery.py import-3.9!skip
plugins/module_utils/client/discovery.py import-3.10!skip
plugins/module_utils/client/discovery.py import-3.11!skip
plugins/module_utils/client/discovery.py import-3.12!skip
plugins/module_utils/client/resource.py import-3.9!skip
plugins/module_utils/client/resource.py import-3.10!skip
plugins/module_utils/client/resource.py import-3.11!skip
plugins/module_utils/client/resource.py import-3.12!skip
plugins/module_utils/k8sdynamicclient.py import-3.9!skip
plugins/module_utils/k8sdynamicclient.py import-3.10!skip
plugins/module_utils/k8sdynamicclient.py import-3.11!skip
plugins/module_utils/k8sdynamicclient.py import-3.12!skip
plugins/module_utils/version.py pylint!skip
plugins/modules/k8s.py validate-modules:parameter-type-not-in-doc
plugins/modules/k8s_scale.py validate-modules:parameter-type-not-in-doc
plugins/modules/k8s_service.py validate-modules:parameter-type-not-in-doc
tests/unit/module_utils/fixtures/definitions.yml yamllint!skip
tests/unit/module_utils/fixtures/deployments.yml yamllint!skip
tests/integration/targets/k8s_delete/files/deployments.yaml yamllint!skip
tests/unit/module_utils/fixtures/pods.yml yamllint!skip
tests/integration/targets/helm/files/appversionless-chart-v2/templates/configmap.yaml yamllint!skip
tests/integration/targets/helm/files/appversionless-chart/templates/configmap.yaml yamllint!skip
tests/integration/targets/helm/files/test-chart-v2/templates/configmap.yaml yamllint!skip
tests/integration/targets/helm/files/test-chart/templates/configmap.yaml yamllint!skip
tests/integration/targets/helm_diff/files/test-chart/templates/configmap.yaml yamllint!skip
tests/integration/targets/k8s_scale/files/deployment.yaml yamllint!skip
plugins/modules/k8s.py validate-modules:return-syntax-error
plugins/modules/k8s_scale.py validate-modules:return-syntax-error
plugins/modules/k8s_service.py validate-modules:return-syntax-error
plugins/modules/k8s_taint.py validate-modules:return-syntax-error
tests/integration/targets/helm_diff/files/test-chart-reuse-values/templates/configmap.yaml yamllint!skip

View File

@@ -31,7 +31,7 @@ modified_def["metadata"]["labels"]["environment"] = "testing"
@pytest.mark.parametrize(
"action, params, existing, instance, expected",
"action, params, existing, instance_warnings, expected",
[
(
"delete",
@@ -51,14 +51,26 @@ modified_def["metadata"]["labels"]["environment"] = "testing"
"apply",
{"apply": "yes"},
{},
definition,
(definition, []),
{"changed": True, "method": "apply", "result": definition},
),
(
"apply",
{"apply": "yes"},
{},
(definition, ["test warning"]),
{
"changed": True,
"method": "apply",
"result": definition,
"warnings": ["test warning"],
},
),
(
"create",
{"state": "patched"},
{},
{},
({}, []),
{
"changed": False,
"result": {},
@@ -71,42 +83,78 @@ modified_def["metadata"]["labels"]["environment"] = "testing"
"create",
{},
{},
definition,
(definition, []),
{"changed": True, "method": "create", "result": definition},
),
(
"create",
{},
{},
(definition, ["test warning"]),
{
"changed": True,
"method": "create",
"result": definition,
"warnings": ["test warning"],
},
),
(
"replace",
{"force": "yes"},
definition,
definition,
(definition, []),
{"changed": False, "method": "replace", "result": definition},
),
(
"replace",
{"force": "yes"},
definition,
modified_def,
(modified_def, []),
{"changed": True, "method": "replace", "result": modified_def},
),
(
"replace",
{"force": "yes"},
definition,
(modified_def, ["test warning"]),
{
"changed": True,
"method": "replace",
"result": modified_def,
"warnings": ["test warning"],
},
),
(
"update",
{},
definition,
definition,
(definition, []),
{"changed": False, "method": "update", "result": definition},
),
(
"update",
{},
definition,
modified_def,
(modified_def, []),
{"changed": True, "method": "update", "result": modified_def},
),
(
"update",
{},
definition,
(modified_def, ["test warning"]),
{
"changed": True,
"method": "update",
"result": modified_def,
"warnings": ["test warning"],
},
),
(
"create",
{"label_selectors": ["app=foo"]},
{},
definition,
(definition, []),
{
"changed": False,
"msg": "resource 'kind=Pod,name=foo,namespace=foo' filtered by label_selectors.",
@@ -116,18 +164,18 @@ modified_def["metadata"]["labels"]["environment"] = "testing"
"create",
{"label_selectors": ["app=nginx"]},
{},
definition,
(definition, []),
{"changed": True, "method": "create", "result": definition},
),
],
)
def test_perform_action(action, params, existing, instance, expected):
def test_perform_action(action, params, existing, instance_warnings, expected):
svc = Mock()
svc.find_resource.return_value = Mock(
kind=definition["kind"], group_version=definition["apiVersion"]
)
svc.retrieve.return_value = ResourceInstance(None, existing) if existing else None
spec = {action + ".return_value": instance}
spec = {action + ".return_value": instance_warnings}
svc.configure_mock(**spec)
result = perform_action(svc, definition, params)

View File

@@ -1,9 +1,11 @@
from json import dumps
from unittest.mock import Mock
import pytest
from ansible_collections.kubernetes.core.plugins.module_utils.k8s.service import (
K8sService,
diff_objects,
parse_quoted_string,
)
from kubernetes.dynamic.exceptions import NotFoundError
from kubernetes.dynamic.resource import Resource, ResourceInstance
@@ -57,6 +59,22 @@ def mock_pod_updated_resource_instance():
return ResourceInstance(None, pod_definition_updated)
@pytest.fixture(scope="module")
def mock_pod_response():
resp = Mock()
resp.data.decode.return_value = dumps(pod_definition)
resp.headers = {}
return resp
@pytest.fixture(scope="module")
def mock_pod_warnings_response():
resp = Mock()
resp.data.decode.return_value = dumps(pod_definition)
resp.headers = {"warning": '299 - "test warning 1", 299 - "test warning 2"'}
return resp
def test_diff_objects_no_diff():
match, diff = diff_objects(pod_definition, pod_definition)
@@ -159,16 +177,33 @@ def test_service_delete_existing_resource_check_mode(mock_pod_resource_instance)
client.delete.assert_not_called()
def test_service_create_resource(mock_pod_resource_instance):
spec = {"create.side_effect": [mock_pod_resource_instance]}
def test_service_create_resource(mock_pod_response, mock_pod_resource_instance):
spec = {"create.side_effect": [mock_pod_response]}
client = Mock(**spec)
module = Mock()
module.params = {}
module.check_mode = False
svc = K8sService(client, module)
result = svc.create(Mock(), pod_definition)
result, warnings = svc.create(Mock(), pod_definition)
assert result == mock_pod_resource_instance.to_dict()
assert not warnings
def test_service_create_resource_warnings(
mock_pod_warnings_response, mock_pod_resource_instance
):
spec = {"create.side_effect": [mock_pod_warnings_response]}
client = Mock(**spec)
module = Mock()
module.params = {}
module.check_mode = False
svc = K8sService(client, module)
result, warnings = svc.create(Mock(), pod_definition)
assert result == mock_pod_resource_instance.to_dict()
assert warnings[0] == "test warning 1"
assert warnings[1] == "test warning 2"
def test_service_create_resource_check_mode():
@@ -176,9 +211,10 @@ def test_service_create_resource_check_mode():
client.create.return_value = mock_pod_resource_instance
module = Mock(params={}, check_mode=True)
svc = K8sService(client, module)
result = svc.create(Mock(), pod_definition)
result, warnings = svc.create(Mock(), pod_definition)
assert result == pod_definition
assert not warnings
client.create.assert_not_called()
@@ -224,40 +260,99 @@ def test_create_project_request():
assert results["result"] == project_definition
def test_service_apply_existing_resource(mock_pod_resource_instance):
spec = {"apply.side_effect": [mock_pod_resource_instance]}
def test_service_apply_existing_resource(mock_pod_response, mock_pod_resource_instance):
spec = {"apply.side_effect": [mock_pod_response]}
client = Mock(**spec)
module = Mock()
module.params = {"apply": True}
module.check_mode = False
svc = K8sService(client, module)
result = svc.apply(Mock(), pod_definition_updated, mock_pod_resource_instance)
result, warnings = svc.apply(
Mock(), pod_definition_updated, mock_pod_resource_instance
)
assert result == mock_pod_resource_instance.to_dict()
assert not warnings
def test_service_replace_existing_resource(mock_pod_resource_instance):
spec = {"replace.side_effect": [mock_pod_resource_instance]}
def test_service_apply_existing_resource_warnings(
mock_pod_warnings_response, mock_pod_resource_instance
):
spec = {"apply.side_effect": [mock_pod_warnings_response]}
client = Mock(**spec)
module = Mock()
module.params = {"apply": True}
module.check_mode = False
svc = K8sService(client, module)
result, warnings = svc.apply(
Mock(), pod_definition_updated, mock_pod_resource_instance
)
assert result == mock_pod_resource_instance.to_dict()
assert warnings[0] == "test warning 1"
assert warnings[1] == "test warning 2"
def test_service_replace_existing_resource(
mock_pod_response, mock_pod_resource_instance
):
spec = {"replace.side_effect": [mock_pod_response]}
client = Mock(**spec)
module = Mock()
module.params = {}
module.check_mode = False
svc = K8sService(client, module)
result = svc.replace(Mock(), pod_definition, mock_pod_resource_instance)
result, warnings = svc.replace(Mock(), pod_definition, mock_pod_resource_instance)
assert result == mock_pod_resource_instance.to_dict()
assert not warnings
def test_service_update_existing_resource(mock_pod_resource_instance):
spec = {"replace.side_effect": [mock_pod_resource_instance]}
def test_service_replace_existing_resource_warnings(
mock_pod_warnings_response, mock_pod_resource_instance
):
spec = {"replace.side_effect": [mock_pod_warnings_response]}
client = Mock(**spec)
module = Mock()
module.params = {}
module.check_mode = False
svc = K8sService(client, module)
result = svc.replace(Mock(), pod_definition, mock_pod_resource_instance)
result, warnings = svc.replace(Mock(), pod_definition, mock_pod_resource_instance)
assert result == mock_pod_resource_instance.to_dict()
assert warnings[0] == "test warning 1"
assert warnings[1] == "test warning 2"
def test_service_update_existing_resource(
mock_pod_response, mock_pod_resource_instance
):
spec = {"replace.side_effect": [mock_pod_response]}
client = Mock(**spec)
module = Mock()
module.params = {}
module.check_mode = False
svc = K8sService(client, module)
result, warnings = svc.replace(Mock(), pod_definition, mock_pod_resource_instance)
assert result == mock_pod_resource_instance.to_dict()
assert not warnings
def test_service_update_existing_resource_warnings(
mock_pod_warnings_response, mock_pod_resource_instance
):
spec = {"replace.side_effect": [mock_pod_warnings_response]}
client = Mock(**spec)
module = Mock()
module.params = {}
module.check_mode = False
svc = K8sService(client, module)
result, warnings = svc.replace(Mock(), pod_definition, mock_pod_resource_instance)
assert result == mock_pod_resource_instance.to_dict()
assert warnings[0] == "test warning 1"
assert warnings[1] == "test warning 2"
def test_service_find(mock_pod_resource_instance):
@@ -288,3 +383,24 @@ def test_service_find_error():
assert isinstance(results, dict)
assert results["api_found"] is True
assert results["resources"] == []
@pytest.mark.parametrize(
"quoted_string,expected_val,expected_remainder",
[
(
'"Response is stale" Tue, 15 Nov 1994 12:45:26 GMT',
"Response is stale",
"Tue, 15 Nov 1994 12:45:26 GMT",
),
(
'"unknown field \\"spec.template.spec.disk\\""',
'unknown field "spec.template.spec.disk"',
"",
),
],
)
def test_parse_quoted_string(quoted_string, expected_val, expected_remainder):
val, remainder = parse_quoted_string(quoted_string)
assert val == expected_val
assert remainder == expected_remainder

View File

@@ -0,0 +1,22 @@
import os
import sys
from pathlib import PosixPath
def main():
src = sys.argv[1]
path = PosixPath(src) / PosixPath("tests/integration/targets/")
def _is_disable(path):
flags = ("unsupported", "disabled", "unstable", "hidden")
aliases_path = path / PosixPath("aliases")
return (aliases_path.exists() and any((d.startswith(flags) for d in aliases_path.read_text().split("\n"))))
targets = [i.stem for i in path.glob("*") if i.is_dir() and not _is_disable(i)]
with open(os.environ.get("GITHUB_OUTPUT"), "a", encoding="utf-8") as fw:
fw.write(f"kubevirt_targets={targets}\n")
if __name__ == "__main__":
main()