mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-07-28 02:14:41 +00:00
[helm] add the ability for the module to uninstall pending-install releases (#589)
[helm] add the ability for the module to uninstall pending-install releases SUMMARY closes #319 ISSUE TYPE Feature Pull Request COMPONENT NAME helm Reviewed-by: Mike Graves <mgraves@redhat.com> Reviewed-by: Bikouo Aubin
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
bugfixes:
|
||||||
|
- helm - fix issue occurring when uninstalling chart with statues others than 'deployed' (https://github.com/ansible-collections/kubernetes.core/issues/319).
|
||||||
@@ -432,14 +432,20 @@ def get_release(state, release_name):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_release_status(module, release_name):
|
def get_release_status(module, release_name, all_status=False):
|
||||||
"""
|
"""
|
||||||
Get Release state from deployed release
|
Get Release state from all release status (deployed, failed, pending-install, etc)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
list_command = (
|
list_command = [
|
||||||
module.get_helm_binary() + " list --output=yaml --filter " + release_name
|
module.get_helm_binary(),
|
||||||
)
|
"list",
|
||||||
|
"--output=yaml",
|
||||||
|
"--filter",
|
||||||
|
release_name,
|
||||||
|
]
|
||||||
|
if all_status:
|
||||||
|
list_command.append("--all")
|
||||||
|
|
||||||
rc, out, err = module.run_helm_command(list_command)
|
rc, out, err = module.run_helm_command(list_command)
|
||||||
|
|
||||||
@@ -773,29 +779,31 @@ def main():
|
|||||||
run_repo_update(module)
|
run_repo_update(module)
|
||||||
|
|
||||||
# Get real/deployed release status
|
# Get real/deployed release status
|
||||||
release_status = get_release_status(module, release_name)
|
all_status = release_state == "absent"
|
||||||
|
release_status = get_release_status(module, release_name, all_status=all_status)
|
||||||
|
|
||||||
helm_cmd = module.get_helm_binary()
|
helm_cmd = module.get_helm_binary()
|
||||||
opt_result = {}
|
opt_result = {}
|
||||||
if release_state == "absent" and release_status is not None:
|
if release_state == "absent" and release_status is not None:
|
||||||
if replace:
|
# skip release statuses 'uninstalled' and 'uninstalling'
|
||||||
module.fail_json(msg="replace is not applicable when state is absent")
|
if not release_status["status"].startswith("uninstall"):
|
||||||
|
if replace:
|
||||||
|
module.fail_json(msg="replace is not applicable when state is absent")
|
||||||
|
|
||||||
if wait:
|
if wait:
|
||||||
helm_version = module.get_helm_version()
|
helm_version = module.get_helm_version()
|
||||||
if LooseVersion(helm_version) < LooseVersion("3.7.0"):
|
if LooseVersion(helm_version) < LooseVersion("3.7.0"):
|
||||||
opt_result["warnings"] = []
|
opt_result["warnings"] = []
|
||||||
opt_result["warnings"].append(
|
opt_result["warnings"].append(
|
||||||
"helm uninstall support option --wait for helm release >= 3.7.0"
|
"helm uninstall support option --wait for helm release >= 3.7.0"
|
||||||
)
|
)
|
||||||
wait = False
|
wait = False
|
||||||
|
|
||||||
helm_cmd = delete(
|
helm_cmd = delete(
|
||||||
helm_cmd, release_name, purge, disable_hook, wait, wait_timeout
|
helm_cmd, release_name, purge, disable_hook, wait, wait_timeout
|
||||||
)
|
)
|
||||||
changed = True
|
changed = True
|
||||||
elif release_state == "present":
|
elif release_state == "present":
|
||||||
|
|
||||||
if chart_version is not None:
|
if chart_version is not None:
|
||||||
helm_cmd += " --version=" + chart_version
|
helm_cmd += " --version=" + chart_version
|
||||||
|
|
||||||
@@ -956,7 +964,7 @@ def main():
|
|||||||
changed=changed,
|
changed=changed,
|
||||||
stdout=out,
|
stdout=out,
|
||||||
stderr=err,
|
stderr=err,
|
||||||
status=get_release_status(module, release_name),
|
status=get_release_status(module, release_name, all_status=True),
|
||||||
command=helm_cmd,
|
command=helm_cmd,
|
||||||
**opt_result,
|
**opt_result,
|
||||||
)
|
)
|
||||||
|
|||||||
129
tests/integration/targets/helm/library/helm_test_pending.py
Normal file
129
tests/integration/targets/helm/library/helm_test_pending.py
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright: (c) 2023, Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
DOCUMENTATION = r"""
|
||||||
|
---
|
||||||
|
module: helm_test_pending
|
||||||
|
short_description: created pending-install release
|
||||||
|
author:
|
||||||
|
- Aubin Bikouo (@abikouo)
|
||||||
|
requirements:
|
||||||
|
- "helm (https://github.com/helm/helm/releases)"
|
||||||
|
description:
|
||||||
|
- This module is used to create a pending install release for integration testing
|
||||||
|
- The scope of this module is the integration testing of the kubernetes.core collection only.
|
||||||
|
options:
|
||||||
|
binary_path:
|
||||||
|
description:
|
||||||
|
- The path of a helm binary to use.
|
||||||
|
required: true
|
||||||
|
type: path
|
||||||
|
chart_ref:
|
||||||
|
description:
|
||||||
|
- chart reference on chart repository (e.g. my-repo/my-chart-ref)
|
||||||
|
required: true
|
||||||
|
type: str
|
||||||
|
chart_release:
|
||||||
|
description:
|
||||||
|
- Release name to manage.
|
||||||
|
required: true
|
||||||
|
type: str
|
||||||
|
chart_release_namespace:
|
||||||
|
description:
|
||||||
|
- Kubernetes namespace where the chart should be installed.
|
||||||
|
required: true
|
||||||
|
type: str
|
||||||
|
"""
|
||||||
|
|
||||||
|
EXAMPLES = r"""
|
||||||
|
"""
|
||||||
|
|
||||||
|
RETURN = r"""
|
||||||
|
"""
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
|
||||||
|
|
||||||
|
class HelmReleaseNotFoundError(Exception):
|
||||||
|
def __init__(self, message):
|
||||||
|
super().__init__(message)
|
||||||
|
|
||||||
|
|
||||||
|
def create_pending_install_release(helm_binary, chart_ref, chart_release, namespace):
|
||||||
|
# create pending-install release
|
||||||
|
command = [
|
||||||
|
helm_binary,
|
||||||
|
"install",
|
||||||
|
chart_release,
|
||||||
|
chart_ref,
|
||||||
|
"--namespace",
|
||||||
|
namespace,
|
||||||
|
"--wait",
|
||||||
|
]
|
||||||
|
proc = subprocess.Popen(command)
|
||||||
|
time.sleep(2)
|
||||||
|
proc.kill()
|
||||||
|
# ensure release status is pending-install
|
||||||
|
command = [
|
||||||
|
helm_binary,
|
||||||
|
"list",
|
||||||
|
"--all",
|
||||||
|
"--output=json",
|
||||||
|
"--namespace",
|
||||||
|
namespace,
|
||||||
|
"--filter",
|
||||||
|
chart_release,
|
||||||
|
]
|
||||||
|
cmd = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
out, err = cmd.communicate()
|
||||||
|
|
||||||
|
data = json.loads(out)
|
||||||
|
if not data:
|
||||||
|
error = "Release %s not found." % chart_release
|
||||||
|
raise HelmReleaseNotFoundError(message=error)
|
||||||
|
return data[0]["status"] == "pending-install", data[0]["status"]
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
module = AnsibleModule(
|
||||||
|
argument_spec=dict(
|
||||||
|
binary_path=dict(type="path", required=True),
|
||||||
|
chart_ref=dict(type="str", required=True),
|
||||||
|
chart_release=dict(type="str", required=True),
|
||||||
|
chart_release_namespace=dict(type="str", required=True),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
params = dict(
|
||||||
|
helm_binary=module.params.get("binary_path"),
|
||||||
|
chart_release=module.params.get("chart_release"),
|
||||||
|
chart_ref=module.params.get("chart_ref"),
|
||||||
|
namespace=module.params.get("chart_release_namespace"),
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
result, status = create_pending_install_release(**params)
|
||||||
|
if not result:
|
||||||
|
module.fail_json(
|
||||||
|
msg="unable to create pending-install release, current status is %s"
|
||||||
|
% status
|
||||||
|
)
|
||||||
|
module.exit_json(changed=True, msg="Release created with status '%s'" % status)
|
||||||
|
except HelmReleaseNotFoundError as err:
|
||||||
|
module.fail_json(
|
||||||
|
msg="Error while trying to create pending-install release due to '%s'" % err
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
- vars:
|
- vars:
|
||||||
chart_source: "https://github.com/kubernetes/kube-state-metrics/releases/download/kube-state-metrics-helm-chart-2.13.3/kube-state-metrics-2.13.3.tgz"
|
chart_source: "https://github.com/kubernetes/kube-state-metrics/releases/download/kube-state-metrics-helm-chart-2.13.3/kube-state-metrics-2.13.3.tgz"
|
||||||
chart_name: "test-wait-uninstall"
|
chart_name: "test-wait-uninstall"
|
||||||
|
chart_name_pending: "test-uninstall-pending-release"
|
||||||
helm_namespace: "{{ test_namespace[1] }}"
|
helm_namespace: "{{ test_namespace[1] }}"
|
||||||
block:
|
block:
|
||||||
|
|
||||||
@@ -64,6 +65,36 @@
|
|||||||
wait: yes
|
wait: yes
|
||||||
register: uninstall
|
register: uninstall
|
||||||
|
|
||||||
|
# Test uninstall chart release with 'pending-install' status
|
||||||
|
- name: Create chart release with 'pending-install' status
|
||||||
|
helm_test_pending:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
chart_ref: "{{ chart_source }}"
|
||||||
|
chart_release: "{{ chart_name_pending }}"
|
||||||
|
chart_release_namespace: "{{ helm_namespace }}"
|
||||||
|
|
||||||
|
- name: Uninstall chart release with 'pending-install' status
|
||||||
|
helm:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
release_name: "{{ chart_name_pending }}"
|
||||||
|
namespace: "{{ helm_namespace }}"
|
||||||
|
release_state: absent
|
||||||
|
register: _uninstall
|
||||||
|
|
||||||
|
- name: Get Helm release details
|
||||||
|
helm_info:
|
||||||
|
binary_path: "{{ helm_binary }}"
|
||||||
|
release_namespace: "{{ helm_namespace }}"
|
||||||
|
release_state: pending
|
||||||
|
release_name: "{{ chart_name_pending }}"
|
||||||
|
register: _info
|
||||||
|
|
||||||
|
- name: assert release does not exist anymore
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- _uninstall is changed
|
||||||
|
- _info.status is undefined
|
||||||
|
|
||||||
always:
|
always:
|
||||||
- name: Delete temp directory
|
- name: Delete temp directory
|
||||||
file:
|
file:
|
||||||
|
|||||||
Reference in New Issue
Block a user