I am trying to create an ansible playbook to delete specific pods from k8s default namespace.
There are 2 lists:
pod_list(dynamically created withkubectl get podscommand output)pod_filter(pre-defined regular expressions, or just the beginning of the pod names)
The idea is to iterate over the pod_list and filter out the names that matches the patterns specified in pod_filter.
Playbook:
---
- name: Delete specific pods
hosts: localhost
vars:
pod_filter:
- hello # beginning of the pod name
- mysql # beginning of the pod name
- myui-557f994996-5vp8l # exact pod name
tasks:
- name: Get a list of all pods from the namespace
#command: kubectl get pods --output=jsonpath='{.items[*].metadata.name}' # Output is a single line
command: kubectl get pods --no-headers -o custom-columns=":metadata.name" # Output is a column
register: pod_list
- name: Iterate over pod names
debug:
msg: "{{ item }}"
# command: kubectl delete pod "{{ item }}"
# pod_list.stdout_lines is a list, but pod_list.stdout is not.
loop: "{{ pod_list.stdout_lines }}"
when: item in pod_filter
The output is like:
$ ansible-playbook test.yaml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
PLAY [Delete specific pods] *******************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************************
ok: [localhost]
TASK [Get a list of all pods from the namespace] ***********************************************************************************************************
changed: [localhost]
TASK [Iterate over pod names] ******************************************************************************************************************************
skipping: [localhost] => (item=hello-768bb8fcd-qptnl)
skipping: [localhost] => (item=mysql-66cdf96976-9jg2v)
ok: [localhost] => (item=myui-557f994996-5vp8l) => {
"msg": "myui-557f994996-5vp8l"
}
PLAY RECAP *************************************************************************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
The condition when: item in pod_filter succeeds only when the exact pod name is specified in the pod_filter list. It doesn't work if i specify only a part (beginning) of the pod names in the pod_filter list.
Ansible docs regarding Tests mentions about match:
matchsucceeds if it finds the pattern at the beginning of the string
What condition should be specified as when for this purpose?
Should there be a nested loop iterate over the two lists?
CodePudding user response:
The condition should be : when: item is match(pod_filter|join('|')) which would effectively cat your regexes together into one.
Then task will look like this:
- name: Iterate over pod names and delete the filtered ones
# debug:
# msg: "{{ item }}"
command: kubectl delete pod "{{ item }}"
loop: "{{ pod_list.stdout_lines }}"
when: item is match(pod_filter|join('|'))
CodePudding user response:
In addition to AnjanaAK's solution, you could also use the Kubernetes collection
Then use kubectl-like filtering. One of the examples provided in the documentation:
- name: Search for all Pods labelled app=web
kubernetes.core.k8s_info:
kind: Pod
label_selectors:
- app = web
- tier in (dev, test)
