Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make name optional to delete all resources for the specified resource type #517

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelogs/fragments/517-k8s-make-name-optional.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
minor_changes:
- k8s - add new option delete_all to support deletion of all resources when state is set to absent. (https://github.com/ansible-collections/kubernetes.core/issues/504)
45 changes: 40 additions & 5 deletions plugins/module_utils/k8s/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,51 @@ def _prepend_resource_info(resource, msg):
return [_prepend_resource_info(resource, msg) for msg in warnings + errors]


def get_definitions(svc, params):
try:
definitions = create_definitions(params)
except Exception as e:
msg = "Failed to load resource definition: {0}".format(e)
raise CoreException(msg) from e

delete_all = params.get("delete_all")
src = params.get("src")
resource_definition = params.get("resource_definition")
name = params.get("name")
state = params.get("state")

if (
delete_all
and state == "absent"
and name is None
and resource_definition is None
and src is None
):
# Delete all resources in the namespace for the specified resource type
if params.get("kind") is None:
raise CoreException(
"'kind' option is required to specify the resource type."
)

resource = svc.find_resource(
params.get("kind"), params.get("api_version"), fail=True
)
definitions = svc.retrieve_all(
resource,
params.get("namespace"),
params.get("label_selectors"),
)

return definitions


def run_module(module) -> None:
results = []
changed = False
client = get_api_client(module)
svc = K8sService(client, module)
try:
definitions = create_definitions(module.params)
except Exception as e:
msg = "Failed to load resource definition: {0}".format(e)
raise CoreException(msg) from e

definitions = get_definitions(svc, module.params)

for definition in definitions:
result = {"changed": False, "result": {}}
Expand Down
24 changes: 24 additions & 0 deletions plugins/module_utils/k8s/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,30 @@ def retrieve(self, resource: Resource, definition: Dict) -> ResourceInstance:

return existing

def retrieve_all(
self, resource: Resource, namespace: str, label_selectors: List[str] = None
) -> List[Dict]:
definitions: List[ResourceInstance] = []

try:
params = dict(namespace=namespace)
if label_selectors:
params["label_selector"] = ",".join(label_selectors)
resource_list = self.client.get(resource, **params)
for item in resource_list.items:
existing = self.client.get(
resource, name=item.metadata.name, namespace=namespace
)
definitions.append(existing.to_dict())
except (NotFoundError, MethodNotAllowedError):
pass
except Exception as e:
reason = e.body if hasattr(e, "body") else e
msg = "Failed to retrieve requested object: {0}".format(reason)
raise CoreException(msg) from e

return definitions

def find(
self,
kind: str,
Expand Down
22 changes: 22 additions & 0 deletions plugins/modules/k8s.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,19 @@
- When set to True, server-side apply will force the changes against conflicts.
type: bool
default: False
delete_all:
description:
- When this option is set to I(true) and I(state=absent),
module will delete all resources of the specified resource type in the requested namespace.
- Ignored when C(state) is not set to I(absent) or when one of (src),
C(name) or C(resource_definition) is provided.
- Parameter C(kind) is required to use this option.
abikouo marked this conversation as resolved.
Show resolved Hide resolved
- This parameter can be used with C(label_selectors) to restrict the resources to be deleted.
type: bool
default: false
version_added: 2.5.0
aliases:
- all

requirements:
- "python >= 3.6"
Expand Down Expand Up @@ -343,6 +356,14 @@
apply: yes
server_side_apply:
field_manager: ansible

# Delete all Deployment from specified namespace
- name: Delete all Deployment from specified namespace
kubernetes.core.k8s:
api_version: apps/v1
namespace: testing
kind: Deployment
delete_all: true
"""

RETURN = r"""
Expand Down Expand Up @@ -450,6 +471,7 @@ def argspec():
argument_spec["server_side_apply"] = dict(
type="dict", default=None, options=server_apply_spec()
)
argument_spec["delete_all"] = dict(type="bool", default=False, aliases=["all"])

return argument_spec

Expand Down
70 changes: 70 additions & 0 deletions tests/integration/targets/k8s_delete/files/deployments.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-d
labels:
context: ansible
spec:
replicas: 1
selector:
matchLabels:
context: ansible
template:
metadata:
labels:
context: ansible
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: openjdk-d
labels:
context: ansible
spec:
replicas: 2
selector:
matchLabels:
context: ansible
template:
metadata:
labels:
context: ansible
spec:
containers:
- name: openjdk
image: openjdk:17
command:
- /bin/sh
- -c
- while true;do date;sleep 5; done
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: alpine-d
labels:
context: ansible
spec:
replicas: 3
selector:
matchLabels:
context: ansible
template:
metadata:
labels:
context: ansible
spec:
containers:
- name: alpine
image: alpine
command:
- /bin/sh
- -c
- while true;do date;sleep 5; done
71 changes: 71 additions & 0 deletions tests/integration/targets/k8s_delete/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,77 @@
that:
- _result.resources | length == 0

# test deletion using delete_all=true
- name: Create deployments
k8s:
namespace: "{{ test_namespace }}"
src: files/deployments.yaml
wait: true
register: result

- name: Trying to delete deployments without name and label_selectors and select_all=false
k8s:
kind: Deployment
api_version: apps/v1
namespace: "{{ test_namespace }}"
state: absent
register: _delete

- name: Ensure Deployment were not deleted
assert:
that:
- _delete is not changed

- name: Validate that Deployment still exist
k8s_info:
kind: Deployment
api_version: apps/v1
namespace: "{{ test_namespace }}"
label_selectors:
- context=ansible
register: _deployment
failed_when: _deployment.resources | length == 0

- name: Trying to delete using delete_all=true but missing kind option
k8s:
api_version: apps/v1
namespace: "{{ test_namespace }}"
delete_all: true
state: absent
register: _delete
ignore_errors: true

- name: assert task failed with proper message
assert:
that:
- _delete is failed
- _delete.msg == "'kind' option is required to specify the resource type."

- name: Trying to delete deployments without name and label_selectors and delete_all=true
k8s:
kind: Deployment
api_version: apps/v1
namespace: "{{ test_namespace }}"
delete_all: true
wait: true
state: absent
register: _delete

- name: Ensure Deployment were deleted
assert:
that:
- _delete is changed

- name: Validate that Deployment do not exist anymore
k8s_info:
kind: Deployment
api_version: apps/v1
namespace: "{{ test_namespace }}"
label_selectors:
- context=ansible
register: _deployment
failed_when: _deployment.resources | length > 0

always:
- name: Remove namespace
k8s:
Expand Down
1 change: 1 addition & 0 deletions tests/sanity/ignore-2.11.txt
Original file line number Diff line number Diff line change
Expand Up @@ -590,3 +590,4 @@ tests/integration/targets/setup_kubeconfig/library/test_inventory_read_credentia
tests/integration/targets/helm/library/helm_test_version.py compile-2.6!skip
tests/integration/targets/helm/library/helm_test_version.py compile-2.7!skip
tests/integration/targets/helm/library/helm_test_version.py compile-3.5!skip
tests/integration/targets/k8s_delete/files/deployments.yaml yamllint!skip
1 change: 1 addition & 0 deletions tests/sanity/ignore-2.12.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ 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/k8s_delete/files/deployments.yaml yamllint!skip
1 change: 1 addition & 0 deletions tests/sanity/ignore-2.13.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ 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/k8s_delete/files/deployments.yaml yamllint!skip
1 change: 1 addition & 0 deletions tests/sanity/ignore-2.14.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,4 @@ 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/k8s_delete/files/deployments.yaml yamllint!skip
1 change: 1 addition & 0 deletions tests/sanity/refresh_ignore_files
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ YAML_LINT_SKIPS = [
"tests/integration/targets/helm/files/test-chart/templates/configmap.yaml",
"tests/integration/targets/helm_diff/files/test-chart/templates/configmap.yaml",
"tests/integration/targets/k8s_scale/files/deployment.yaml",
"tests/integration/targets/k8s_delete/files/deployments.yaml",
]

# Add shebang!skip
Expand Down