mirror of
https://github.com/ansible-collections/kubernetes.core.git
synced 2026-07-28 02:14:41 +00:00
k8s - add label_selectors options (#158)
k8s - add label_selectors options SUMMARY k8s now support label_selectors options same as k8s_info Resolves #43 ISSUE TYPE Feature Pull Request COMPONENT NAME k8s Reviewed-by: Mike Graves <mgraves@redhat.com> Reviewed-by: None <None>
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
minor_changes:
|
||||||
|
- k8s - add support for label_selectors options (https://github.com/ansible-collections/kubernetes.core/issues/43).
|
||||||
@@ -164,6 +164,14 @@
|
|||||||
tags:
|
tags:
|
||||||
- always
|
- always
|
||||||
|
|
||||||
|
- name: Include label_selectors.yml
|
||||||
|
include_tasks:
|
||||||
|
file: tasks/label_selectors.yml
|
||||||
|
apply:
|
||||||
|
tags: [ label_selectors, k8s ]
|
||||||
|
tags:
|
||||||
|
- always
|
||||||
|
|
||||||
- name: Include diff.yml
|
- name: Include diff.yml
|
||||||
include_tasks:
|
include_tasks:
|
||||||
file: tasks/diff.yml
|
file: tasks/diff.yml
|
||||||
|
|||||||
657
molecule/default/tasks/label_selectors.yml
Normal file
657
molecule/default/tasks/label_selectors.yml
Normal file
@@ -0,0 +1,657 @@
|
|||||||
|
---
|
||||||
|
- block:
|
||||||
|
- set_fact:
|
||||||
|
selector_namespace: "selector"
|
||||||
|
selector_pod_delete: "pod-selector-delete"
|
||||||
|
selector_pod_apply: "pod-selector-apply"
|
||||||
|
selector_pod_create:
|
||||||
|
- "pod-selector-apply-00"
|
||||||
|
- "pod-selector-apply-01"
|
||||||
|
- "pod-selector-apply-02"
|
||||||
|
- "pod-selector-apply-03"
|
||||||
|
|
||||||
|
- name: Ensure namespace selector
|
||||||
|
k8s:
|
||||||
|
kind: namespace
|
||||||
|
name: '{{ selector_namespace }}'
|
||||||
|
|
||||||
|
# Resource deletion using label selector (equality-based requirement)
|
||||||
|
- name: Create simple pod
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_delete }}-00'
|
||||||
|
labels:
|
||||||
|
ansible.dev/team: "cloud"
|
||||||
|
ansible.release/version: upstream
|
||||||
|
ansible.dev/test: "true"
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
|
||||||
|
- name: Delete all resource using selector
|
||||||
|
k8s:
|
||||||
|
state: absent
|
||||||
|
kind: Pod
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- ansible.dev/team=cloud
|
||||||
|
wait: yes
|
||||||
|
wait_timeout: 180
|
||||||
|
|
||||||
|
- name: Ensure resources have been deleted
|
||||||
|
k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- ansible.dev/team=cloud
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result.resources == []
|
||||||
|
|
||||||
|
# Resource deletion using label selector (set-based requirement)
|
||||||
|
- name: Create simple pod
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_delete }}-01'
|
||||||
|
labels:
|
||||||
|
environment: production
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: alpine:3.14.0
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
|
||||||
|
- name: Delete all resource using selector
|
||||||
|
k8s:
|
||||||
|
state: absent
|
||||||
|
kind: Pod
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- environment in (test, qa)
|
||||||
|
wait: yes
|
||||||
|
wait_timeout: 180
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check that no resources were deleted
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is not changed
|
||||||
|
|
||||||
|
- name: Ensure resources have not been deleted
|
||||||
|
k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- environment in (production)
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result.resources | list | length > 0
|
||||||
|
|
||||||
|
- name: Delete all resource using selector
|
||||||
|
k8s:
|
||||||
|
state: absent
|
||||||
|
kind: Pod
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- environment in (production)
|
||||||
|
wait: yes
|
||||||
|
wait_timeout: 180
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check result is changed
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: Ensure resources have not been deleted
|
||||||
|
k8s_info:
|
||||||
|
kind: Pod
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- environment in (production)
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result.resources | list | length == 0
|
||||||
|
|
||||||
|
# Resource creation using label selector
|
||||||
|
- name: Create simple pod using label_selectors option (equality-based requirement)
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- container.image=fedora
|
||||||
|
definition: |
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[0] }}'
|
||||||
|
labels:
|
||||||
|
container.image: busybox
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[1] }}'
|
||||||
|
labels:
|
||||||
|
container.image: alpine
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: alpine
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[2] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
release: dev
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[3] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
release: dev
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is not changed
|
||||||
|
|
||||||
|
- name: Create simple pod using label_selectors option
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- container.image==alpine
|
||||||
|
definition: |
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[0] }}'
|
||||||
|
labels:
|
||||||
|
container.image: busybox
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[1] }}'
|
||||||
|
labels:
|
||||||
|
container.image: alpine
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: alpine
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[2] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: test
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[3] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: production
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: list pod created
|
||||||
|
k8s_info:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
kind: Pod
|
||||||
|
label_selectors:
|
||||||
|
- container.image
|
||||||
|
register: pod_created
|
||||||
|
|
||||||
|
- name: Validate that pod with matching label was created
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- pods_created | length == 1
|
||||||
|
- selector_pod_create[1] in pods_created
|
||||||
|
vars:
|
||||||
|
pods_created: '{{ pod_created.resources | map(attribute="metadata.name") | list }}'
|
||||||
|
|
||||||
|
- name: Create simple pod using label_selectors option (set-based requirement)
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- "!environment"
|
||||||
|
definition: |
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[0] }}'
|
||||||
|
labels:
|
||||||
|
container.image: busybox
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[1] }}'
|
||||||
|
labels:
|
||||||
|
container.image: alpine
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: alpine
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[2] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: test
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[3] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: production
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: list pod created
|
||||||
|
k8s_info:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
kind: Pod
|
||||||
|
label_selectors:
|
||||||
|
- container.image
|
||||||
|
register: pod_created
|
||||||
|
|
||||||
|
- name: Validate that pod with matching label was created
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- pods_created | length == 2
|
||||||
|
- selector_pod_create[0] in pods_created
|
||||||
|
vars:
|
||||||
|
pods_created: '{{ pod_created.resources | map(attribute="metadata.name") | list }}'
|
||||||
|
|
||||||
|
- name: Create simple pod using label_selectors option (set-based requirement)
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- environment in (test)
|
||||||
|
definition: |
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[0] }}'
|
||||||
|
labels:
|
||||||
|
container.image: busybox
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[1] }}'
|
||||||
|
labels:
|
||||||
|
container.image: alpine
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: alpine
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[2] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: test
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[3] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: production
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: list pod created
|
||||||
|
k8s_info:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
kind: Pod
|
||||||
|
label_selectors:
|
||||||
|
- container.image
|
||||||
|
register: pod_created
|
||||||
|
|
||||||
|
- name: Validate that pod with matching label was created
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- pods_created | length == 3
|
||||||
|
- selector_pod_create[2] in pods_created
|
||||||
|
vars:
|
||||||
|
pods_created: '{{ pod_created.resources | map(attribute="metadata.name") | list }}'
|
||||||
|
|
||||||
|
- name: Create simple pod using label_selectors option (set-based requirement)
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
label_selectors:
|
||||||
|
- environment notin (test)
|
||||||
|
definition: |
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[0] }}'
|
||||||
|
labels:
|
||||||
|
container.image: busybox
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[1] }}'
|
||||||
|
labels:
|
||||||
|
container.image: alpine
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: alpine
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[2] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: test
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_create[3] }}'
|
||||||
|
labels:
|
||||||
|
container.image: python
|
||||||
|
environment: production
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: python
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
- name: list pod created
|
||||||
|
k8s_info:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
kind: Pod
|
||||||
|
label_selectors:
|
||||||
|
- container.image
|
||||||
|
register: pod_created
|
||||||
|
|
||||||
|
- name: Validate that pod with matching label was created
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- pods_created | length == 4
|
||||||
|
- selector_pod_create[3] in pods_created
|
||||||
|
vars:
|
||||||
|
pods_created: '{{ pod_created.resources | map(attribute="metadata.name") | list }}'
|
||||||
|
|
||||||
|
# Resource update using apply
|
||||||
|
- name: Create simple pod using apply
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
apply: yes
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_apply }}'
|
||||||
|
labels:
|
||||||
|
environment: test
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox:1.31.0
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
|
||||||
|
- name: Apply new pod definition using label_selectors (no match)
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
apply: yes
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_apply }}'
|
||||||
|
labels:
|
||||||
|
environment: test
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox:1.33.0
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
label_selectors:
|
||||||
|
- environment=qa
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check task output
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is not changed
|
||||||
|
- '"filtered by label_selectors" in result.msg'
|
||||||
|
|
||||||
|
- name: Apply new pod definition using label_selectors
|
||||||
|
k8s:
|
||||||
|
namespace: '{{ selector_namespace }}'
|
||||||
|
apply: yes
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: '{{ selector_pod_apply }}'
|
||||||
|
labels:
|
||||||
|
environment: test
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: c0
|
||||||
|
image: busybox:1.33.0
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- while true;do date;sleep 5; done
|
||||||
|
label_selectors:
|
||||||
|
- environment!=qa
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: check task output
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- result is changed
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Ensure namespace is deleted
|
||||||
|
k8s:
|
||||||
|
kind: Namespace
|
||||||
|
name: '{{ selector_namespace }}'
|
||||||
|
state: absent
|
||||||
|
ignore_errors: true
|
||||||
@@ -29,6 +29,7 @@ from distutils.version import LooseVersion
|
|||||||
|
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (AUTH_ARG_MAP, AUTH_ARG_SPEC, AUTH_PROXY_HEADERS_SPEC)
|
from ansible_collections.kubernetes.core.plugins.module_utils.args_common import (AUTH_ARG_MAP, AUTH_ARG_SPEC, AUTH_PROXY_HEADERS_SPEC)
|
||||||
from ansible_collections.kubernetes.core.plugins.module_utils.hashes import generate_hash
|
from ansible_collections.kubernetes.core.plugins.module_utils.hashes import generate_hash
|
||||||
|
from ansible_collections.kubernetes.core.plugins.module_utils.selector import LabelSelectorFilter
|
||||||
|
|
||||||
from ansible.module_utils.basic import missing_required_lib
|
from ansible.module_utils.basic import missing_required_lib
|
||||||
from ansible.module_utils.six import iteritems, string_types
|
from ansible.module_utils.six import iteritems, string_types
|
||||||
@@ -349,7 +350,7 @@ class K8sAnsibleMixin(object):
|
|||||||
def fail(self, msg=None):
|
def fail(self, msg=None):
|
||||||
self.fail_json(msg=msg)
|
self.fail_json(msg=msg)
|
||||||
|
|
||||||
def _wait_for(self, resource, name, namespace, predicate, sleep, timeout, state):
|
def _wait_for(self, resource, name, namespace, predicate, sleep, timeout, state, label_selectors):
|
||||||
start = datetime.now()
|
start = datetime.now()
|
||||||
|
|
||||||
def _wait_for_elapsed():
|
def _wait_for_elapsed():
|
||||||
@@ -358,7 +359,10 @@ class K8sAnsibleMixin(object):
|
|||||||
response = None
|
response = None
|
||||||
while _wait_for_elapsed() < timeout:
|
while _wait_for_elapsed() < timeout:
|
||||||
try:
|
try:
|
||||||
response = resource.get(name=name, namespace=namespace)
|
params = dict(name=name, namespace=namespace)
|
||||||
|
if label_selectors:
|
||||||
|
params['label_selector'] = ','.join(label_selectors)
|
||||||
|
response = resource.get(**params)
|
||||||
if predicate(response):
|
if predicate(response):
|
||||||
if response:
|
if response:
|
||||||
return True, response.to_dict(), _wait_for_elapsed()
|
return True, response.to_dict(), _wait_for_elapsed()
|
||||||
@@ -371,7 +375,7 @@ class K8sAnsibleMixin(object):
|
|||||||
response = response.to_dict()
|
response = response.to_dict()
|
||||||
return False, response, _wait_for_elapsed()
|
return False, response, _wait_for_elapsed()
|
||||||
|
|
||||||
def wait(self, resource, definition, sleep, timeout, state='present', condition=None):
|
def wait(self, resource, definition, sleep, timeout, state='present', condition=None, label_selectors=None):
|
||||||
|
|
||||||
def _deployment_ready(deployment):
|
def _deployment_ready(deployment):
|
||||||
# FIXME: frustratingly bool(deployment.status) is True even if status is empty
|
# FIXME: frustratingly bool(deployment.status) is True even if status is empty
|
||||||
@@ -420,7 +424,7 @@ class K8sAnsibleMixin(object):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def _resource_absent(resource):
|
def _resource_absent(resource):
|
||||||
return not resource
|
return not resource or (resource.kind.endswith('List') and resource.items == [])
|
||||||
|
|
||||||
waiter = dict(
|
waiter = dict(
|
||||||
Deployment=_deployment_ready,
|
Deployment=_deployment_ready,
|
||||||
@@ -428,13 +432,13 @@ class K8sAnsibleMixin(object):
|
|||||||
Pod=_pod_ready
|
Pod=_pod_ready
|
||||||
)
|
)
|
||||||
kind = definition['kind']
|
kind = definition['kind']
|
||||||
if state == 'present' and not condition:
|
if state == 'present':
|
||||||
predicate = waiter.get(kind, lambda x: x)
|
predicate = waiter.get(kind, lambda x: x) if not condition else _custom_condition
|
||||||
elif state == 'present' and condition:
|
|
||||||
predicate = _custom_condition
|
|
||||||
else:
|
else:
|
||||||
predicate = _resource_absent
|
predicate = _resource_absent
|
||||||
return self._wait_for(resource, definition['metadata']['name'], definition['metadata'].get('namespace'), predicate, sleep, timeout, state)
|
name = definition['metadata']['name']
|
||||||
|
namespace = definition['metadata'].get('namespace')
|
||||||
|
return self._wait_for(resource, name, namespace, predicate, sleep, timeout, state, label_selectors)
|
||||||
|
|
||||||
def set_resource_definitions(self, module):
|
def set_resource_definitions(self, module):
|
||||||
resource_definition = module.params.get('resource_definition')
|
resource_definition = module.params.get('resource_definition')
|
||||||
@@ -575,6 +579,7 @@ class K8sAnsibleMixin(object):
|
|||||||
wait_timeout = self.params.get('wait_timeout')
|
wait_timeout = self.params.get('wait_timeout')
|
||||||
wait_condition = None
|
wait_condition = None
|
||||||
continue_on_error = self.params.get('continue_on_error')
|
continue_on_error = self.params.get('continue_on_error')
|
||||||
|
label_selectors = self.params.get('label_selectors')
|
||||||
if self.params.get('wait_condition') and self.params['wait_condition'].get('type'):
|
if self.params.get('wait_condition') and self.params['wait_condition'].get('type'):
|
||||||
wait_condition = self.params['wait_condition']
|
wait_condition = self.params['wait_condition']
|
||||||
|
|
||||||
@@ -591,6 +596,8 @@ class K8sAnsibleMixin(object):
|
|||||||
params = dict(name=name)
|
params = dict(name=name)
|
||||||
if namespace:
|
if namespace:
|
||||||
params['namespace'] = namespace
|
params['namespace'] = namespace
|
||||||
|
if label_selectors:
|
||||||
|
params['label_selector'] = ','.join(label_selectors)
|
||||||
existing = resource.get(**params)
|
existing = resource.get(**params)
|
||||||
except (NotFoundError, MethodNotAllowedError):
|
except (NotFoundError, MethodNotAllowedError):
|
||||||
# Remove traceback so that it doesn't show up in later failures
|
# Remove traceback so that it doesn't show up in later failures
|
||||||
@@ -625,7 +632,13 @@ class K8sAnsibleMixin(object):
|
|||||||
|
|
||||||
if state == 'absent':
|
if state == 'absent':
|
||||||
result['method'] = "delete"
|
result['method'] = "delete"
|
||||||
if not existing:
|
|
||||||
|
def _empty_resource_list():
|
||||||
|
if existing and existing.kind.endswith('List'):
|
||||||
|
return existing.items == []
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not existing or _empty_resource_list():
|
||||||
# The object already does not exist
|
# The object already does not exist
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
@@ -651,7 +664,7 @@ class K8sAnsibleMixin(object):
|
|||||||
else:
|
else:
|
||||||
self.fail_json(msg=build_error_msg(definition['kind'], origin_name, msg), error=exc.status, status=exc.status, reason=exc.reason)
|
self.fail_json(msg=build_error_msg(definition['kind'], origin_name, msg), error=exc.status, status=exc.status, reason=exc.reason)
|
||||||
if wait:
|
if wait:
|
||||||
success, resource, duration = self.wait(resource, definition, wait_sleep, wait_timeout, 'absent')
|
success, resource, duration = self.wait(resource, definition, wait_sleep, wait_timeout, 'absent', label_selectors=label_selectors)
|
||||||
result['duration'] = duration
|
result['duration'] = duration
|
||||||
if not success:
|
if not success:
|
||||||
msg = "Resource deletion timed out"
|
msg = "Resource deletion timed out"
|
||||||
@@ -663,6 +676,13 @@ class K8sAnsibleMixin(object):
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
if label_selectors:
|
||||||
|
filter_selector = LabelSelectorFilter(label_selectors)
|
||||||
|
if not filter_selector.isMatching(definition):
|
||||||
|
result['changed'] = False
|
||||||
|
result['msg'] = "resource 'kind={kind},name={name},namespace={namespace}' filtered by label_selectors.".format(
|
||||||
|
kind=definition['kind'], name=origin_name, namespace=namespace)
|
||||||
|
return result
|
||||||
if apply:
|
if apply:
|
||||||
if self.check_mode:
|
if self.check_mode:
|
||||||
ignored, patch = apply_object(resource, _encode_stringdata(definition))
|
ignored, patch = apply_object(resource, _encode_stringdata(definition))
|
||||||
|
|||||||
71
plugins/module_utils/selector.py
Normal file
71
plugins/module_utils/selector.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# Copyright [2021] [Red Hat, Inc.]
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
class Selector(object):
|
||||||
|
|
||||||
|
equality_based_operators = ('==', '!=', '=')
|
||||||
|
|
||||||
|
def __init__(self, data):
|
||||||
|
self._operator = None
|
||||||
|
self._data = None
|
||||||
|
if not self.parse_set_based_requirement(data):
|
||||||
|
no_whitespace_data = data.replace(" ", "")
|
||||||
|
for op in self.equality_based_operators:
|
||||||
|
idx = no_whitespace_data.find(op)
|
||||||
|
if idx != -1:
|
||||||
|
self._operator = "in" if op == '==' or op == '=' else "notin"
|
||||||
|
self._key = no_whitespace_data[0:idx]
|
||||||
|
self._data = [no_whitespace_data[idx + len(op):]]
|
||||||
|
break
|
||||||
|
|
||||||
|
def parse_set_based_requirement(self, data):
|
||||||
|
m = re.match(r'( *)([a-z0-9A-Z][a-z0-9A-Z\._-]*[a-z0-9A-Z])( +)(notin|in)( +)\((.*)\)( *)', data)
|
||||||
|
if m:
|
||||||
|
self._set_based_requirement = True
|
||||||
|
self._key = m.group(2)
|
||||||
|
self._operator = m.group(4)
|
||||||
|
self._data = [x.replace(' ', '') for x in m.group(6).split(',') if x != '']
|
||||||
|
return True
|
||||||
|
elif all([x not in data for x in self.equality_based_operators]):
|
||||||
|
self._key = data.rstrip(" ").lstrip(" ")
|
||||||
|
if self._key.startswith("!"):
|
||||||
|
self._key = self._key[1:].lstrip(" ")
|
||||||
|
self._operator = "!"
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def isMatch(self, labels):
|
||||||
|
if self._operator == "in":
|
||||||
|
return self._key in labels and labels.get(self._key) in self._data
|
||||||
|
elif self._operator == "notin":
|
||||||
|
return self._key not in labels or labels.get(self._key) not in self._data
|
||||||
|
else:
|
||||||
|
return self._key not in labels if self._operator == "!" else self._key in labels
|
||||||
|
|
||||||
|
|
||||||
|
class LabelSelectorFilter(object):
|
||||||
|
|
||||||
|
def __init__(self, label_selectors):
|
||||||
|
self.selectors = [Selector(data) for data in label_selectors]
|
||||||
|
|
||||||
|
def isMatching(self, definition):
|
||||||
|
if "metadata" not in definition or "labels" not in definition['metadata']:
|
||||||
|
return False
|
||||||
|
labels = definition['metadata']['labels']
|
||||||
|
if not isinstance(labels, dict):
|
||||||
|
return None
|
||||||
|
return all([sel.isMatch(labels) for sel in self.selectors])
|
||||||
@@ -135,6 +135,12 @@ options:
|
|||||||
type: bool
|
type: bool
|
||||||
default: False
|
default: False
|
||||||
version_added: 2.0.0
|
version_added: 2.0.0
|
||||||
|
label_selectors:
|
||||||
|
description:
|
||||||
|
- Selector (label query) to filter on.
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
version_added: 2.2.0
|
||||||
|
|
||||||
requirements:
|
requirements:
|
||||||
- "python >= 3.6"
|
- "python >= 3.6"
|
||||||
@@ -335,6 +341,7 @@ def argspec():
|
|||||||
argument_spec['continue_on_error'] = dict(type='bool', default=False)
|
argument_spec['continue_on_error'] = dict(type='bool', default=False)
|
||||||
argument_spec['state'] = dict(default='present', choices=['present', 'absent', 'patched'])
|
argument_spec['state'] = dict(default='present', choices=['present', 'absent', 'patched'])
|
||||||
argument_spec['force'] = dict(type='bool', default=False)
|
argument_spec['force'] = dict(type='bool', default=False)
|
||||||
|
argument_spec['label_selectors'] = dict(type='list', elements='str')
|
||||||
|
|
||||||
return argument_spec
|
return argument_spec
|
||||||
|
|
||||||
|
|||||||
@@ -241,3 +241,7 @@ plugins/modules/k8s_cp.py import-2.7!skip
|
|||||||
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.6!skip
|
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.6!skip
|
||||||
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.7!skip
|
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.7!skip
|
||||||
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-3.5!skip
|
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-3.5!skip
|
||||||
|
tests/unit/module_utils/test_selector.py future-import-boilerplate!skip
|
||||||
|
tests/unit/module_utils/test_selector.py metaclass-boilerplate!skip
|
||||||
|
plugins/module_utils/selector.py future-import-boilerplate!skip
|
||||||
|
plugins/module_utils/selector.py metaclass-boilerplate!skip
|
||||||
@@ -241,3 +241,7 @@ plugins/modules/k8s_cp.py import-2.7!skip
|
|||||||
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.6!skip
|
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.6!skip
|
||||||
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.7!skip
|
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.7!skip
|
||||||
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-3.5!skip
|
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-3.5!skip
|
||||||
|
tests/unit/module_utils/test_selector.py future-import-boilerplate!skip
|
||||||
|
tests/unit/module_utils/test_selector.py metaclass-boilerplate!skip
|
||||||
|
plugins/module_utils/selector.py future-import-boilerplate!skip
|
||||||
|
plugins/module_utils/selector.py metaclass-boilerplate!skip
|
||||||
@@ -239,3 +239,5 @@ plugins/modules/k8s_cp.py compile-2.6!skip
|
|||||||
plugins/modules/k8s_cp.py compile-2.7!skip
|
plugins/modules/k8s_cp.py compile-2.7!skip
|
||||||
plugins/modules/k8s_cp.py import-2.6!skip
|
plugins/modules/k8s_cp.py import-2.6!skip
|
||||||
plugins/modules/k8s_cp.py import-2.7!skip
|
plugins/modules/k8s_cp.py import-2.7!skip
|
||||||
|
plugins/module_utils/selector.py future-import-boilerplate!skip
|
||||||
|
plugins/module_utils/selector.py metaclass-boilerplate!skip
|
||||||
@@ -235,3 +235,7 @@ plugins/modules/k8s_cp.py import-2.7!skip
|
|||||||
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.6!skip
|
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.6!skip
|
||||||
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.7!skip
|
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-2.7!skip
|
||||||
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-3.5!skip
|
molecule/default/roles/k8scopy/library/kubectl_file_compare.py compile-3.5!skip
|
||||||
|
tests/unit/module_utils/test_selector.py future-import-boilerplate!skip
|
||||||
|
tests/unit/module_utils/test_selector.py metaclass-boilerplate!skip
|
||||||
|
plugins/module_utils/selector.py future-import-boilerplate!skip
|
||||||
|
plugins/module_utils/selector.py metaclass-boilerplate!skip
|
||||||
187
tests/unit/module_utils/test_selector.py
Normal file
187
tests/unit/module_utils/test_selector.py
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
# Copyright [2021] [Red Hat, Inc.]
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
from ansible_collections.kubernetes.core.plugins.module_utils.selector import LabelSelectorFilter, Selector
|
||||||
|
|
||||||
|
prod_definition = {
|
||||||
|
'apiVersion': 'v1',
|
||||||
|
'kind': 'Pod',
|
||||||
|
'metadata': {
|
||||||
|
'name': 'test',
|
||||||
|
'labels': {
|
||||||
|
'environment': 'production',
|
||||||
|
'app': 'nginx',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'spec': {
|
||||||
|
'containers': [
|
||||||
|
{'name': 'nginx', 'image': 'nginx:1.14.2', 'command': ['/bin/sh', '-c', 'sleep 10']}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
no_label_definition = {
|
||||||
|
'apiVersion': 'v1',
|
||||||
|
'kind': 'Pod',
|
||||||
|
'metadata': {
|
||||||
|
'name': 'test',
|
||||||
|
'labels': {}
|
||||||
|
},
|
||||||
|
'spec': {
|
||||||
|
'containers': [
|
||||||
|
{'name': 'nginx', 'image': 'nginx:1.14.2', 'command': ['/bin/sh', '-c', 'sleep 10']}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test_definition = {
|
||||||
|
'apiVersion': 'v1',
|
||||||
|
'kind': 'Pod',
|
||||||
|
'metadata': {
|
||||||
|
'name': 'test',
|
||||||
|
'labels': {
|
||||||
|
'environment': 'test',
|
||||||
|
'app': 'nginx',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'spec': {
|
||||||
|
'containers': [
|
||||||
|
{'name': 'nginx', 'image': 'nginx:1.15.2', 'command': ['/bin/sh', '-c', 'sleep 10']}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_selector_parser():
|
||||||
|
f_selector = "environment==true"
|
||||||
|
sel = Selector(f_selector)
|
||||||
|
assert sel._operator == "in" and sel._data == ["true"] and sel._key == "environment"
|
||||||
|
f_selector = "environment=true"
|
||||||
|
sel = Selector(f_selector)
|
||||||
|
assert sel._operator == "in" and sel._data == ["true"] and sel._key == "environment"
|
||||||
|
f_selector = " environment == true "
|
||||||
|
sel = Selector(f_selector)
|
||||||
|
assert sel._operator == "in" and sel._data == ["true"] and sel._key == "environment"
|
||||||
|
f_selector = "environment!=false"
|
||||||
|
sel = Selector(f_selector)
|
||||||
|
assert sel._operator == "notin" and sel._data == ["false"] and sel._key == "environment"
|
||||||
|
f_selector = "environment notin (true, false)"
|
||||||
|
sel = Selector(f_selector)
|
||||||
|
assert sel._operator == "notin" and "true" in sel._data and "false" in sel._data and sel._key == "environment"
|
||||||
|
f_selector = "environment in (true, false)"
|
||||||
|
sel = Selector(f_selector)
|
||||||
|
assert sel._operator == "in" and "true" in sel._data and "false" in sel._data and sel._key == "environment"
|
||||||
|
f_selector = "environmentin(true, false)"
|
||||||
|
sel = Selector(f_selector)
|
||||||
|
assert not sel._operator and not sel._data and sel._key == f_selector
|
||||||
|
f_selector = "environment notin (true, false"
|
||||||
|
sel = Selector(f_selector)
|
||||||
|
assert not sel._operator and not sel._data and sel._key == f_selector
|
||||||
|
f_selector = "!environment"
|
||||||
|
sel = Selector(f_selector)
|
||||||
|
assert sel._operator == "!" and not sel._data and sel._key == "environment"
|
||||||
|
f_selector = "! environment "
|
||||||
|
sel = Selector(f_selector)
|
||||||
|
assert sel._operator == "!" and not sel._data and sel._key == "environment"
|
||||||
|
|
||||||
|
|
||||||
|
def test_label_selector_without_operator():
|
||||||
|
label_selector = ['environment', 'app']
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
|
||||||
|
|
||||||
|
def test_label_selector_equal_operator():
|
||||||
|
label_selector = ['environment==test']
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
label_selector = ['environment=production']
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
label_selector = ['environment=production', 'app==mongodb']
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
label_selector = ['environment=production', 'app==nginx']
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
label_selector = ['environment', 'app==nginx']
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
|
||||||
|
|
||||||
|
def test_label_selector_notequal_operator():
|
||||||
|
label_selector = ['environment!=test']
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
label_selector = ['environment!=production']
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
label_selector = ['environment=production', 'app!=mongodb']
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
label_selector = ['environment=production', 'app!=nginx']
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
label_selector = ['environment', 'app!=nginx']
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
|
||||||
|
|
||||||
|
def test_label_selector_conflicting_definition():
|
||||||
|
label_selector = ['environment==test', 'environment!=test']
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
label_selector = ['environment==test', 'environment==production']
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_based_requirement():
|
||||||
|
label_selector = ['environment in (production)']
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
label_selector = ['environment in (production, test)']
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
label_selector = ['environment notin (production)']
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
label_selector = ['environment notin (production, test)']
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
label_selector = ['environment']
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
|
label_selector = ['!environment']
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(prod_definition)
|
||||||
|
assert LabelSelectorFilter(label_selector).isMatching(no_label_definition)
|
||||||
|
assert not LabelSelectorFilter(label_selector).isMatching(test_definition)
|
||||||
Reference in New Issue
Block a user