mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-26 14:41:23 -07:00
Add proper k8s *List kind support (#52529)
* Add proper k8s *List kind support * set defaults more intelligently * reimplement list support so that it will work in all versions of the client * clean up debugging code
This commit is contained in:
parent
cc9c72d6f8
commit
52ec80fbe9
3 changed files with 168 additions and 16 deletions
|
@ -130,17 +130,34 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
def flatten_list_kind(self, list_resource, definitions):
|
||||||
|
flattened = []
|
||||||
|
parent_api_version = list_resource.group_version if list_resource else None
|
||||||
|
parent_kind = list_resource.kind[:-4] if list_resource else None
|
||||||
|
for definition in definitions.get('items', []):
|
||||||
|
resource = self.find_resource(definition.get('kind', parent_kind), definition.get('apiVersion', parent_api_version), fail=True)
|
||||||
|
flattened.append((resource, self.set_defaults(resource, definition)))
|
||||||
|
return flattened
|
||||||
|
|
||||||
def execute_module(self):
|
def execute_module(self):
|
||||||
changed = False
|
changed = False
|
||||||
results = []
|
results = []
|
||||||
self.client = self.get_api_client()
|
self.client = self.get_api_client()
|
||||||
|
|
||||||
|
flattened_definitions = []
|
||||||
for definition in self.resource_definitions:
|
for definition in self.resource_definitions:
|
||||||
kind = definition.get('kind', self.kind)
|
kind = definition.get('kind', self.kind)
|
||||||
search_kind = kind
|
|
||||||
if kind.lower().endswith('list'):
|
|
||||||
search_kind = kind[:-4]
|
|
||||||
api_version = definition.get('apiVersion', self.api_version)
|
api_version = definition.get('apiVersion', self.api_version)
|
||||||
resource = self.find_resource(search_kind, api_version, fail=True)
|
if kind.endswith('List'):
|
||||||
|
resource = self.find_resource(kind, api_version, fail=False)
|
||||||
|
flattened_definitions.extend(self.flatten_list_kind(resource, definition))
|
||||||
|
else:
|
||||||
|
resource = self.find_resource(kind, api_version, fail=True)
|
||||||
|
flattened_definitions.append((resource, definition))
|
||||||
|
|
||||||
|
for (resource, definition) in flattened_definitions:
|
||||||
|
kind = definition.get('kind', self.kind)
|
||||||
|
api_version = definition.get('apiVersion', self.api_version)
|
||||||
definition = self.set_defaults(resource, definition)
|
definition = self.set_defaults(resource, definition)
|
||||||
self.warnings = []
|
self.warnings = []
|
||||||
if self.params['validate'] is not None:
|
if self.params['validate'] is not None:
|
||||||
|
@ -177,12 +194,12 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
||||||
def set_defaults(self, resource, definition):
|
def set_defaults(self, resource, definition):
|
||||||
definition['kind'] = resource.kind
|
definition['kind'] = resource.kind
|
||||||
definition['apiVersion'] = resource.group_version
|
definition['apiVersion'] = resource.group_version
|
||||||
if not definition.get('metadata'):
|
metadata = definition.get('metadata', {})
|
||||||
definition['metadata'] = {}
|
if self.name and not metadata.get('name'):
|
||||||
if self.name and not definition['metadata'].get('name'):
|
metadata['name'] = self.name
|
||||||
definition['metadata']['name'] = self.name
|
if resource.namespaced and self.namespace and not metadata.get('namespace'):
|
||||||
if resource.namespaced and self.namespace and not definition['metadata'].get('namespace'):
|
metadata['namespace'] = self.namespace
|
||||||
definition['metadata']['namespace'] = self.namespace
|
definition['metadata'] = metadata
|
||||||
return definition
|
return definition
|
||||||
|
|
||||||
def perform_action(self, resource, definition):
|
def perform_action(self, resource, definition):
|
||||||
|
@ -197,12 +214,6 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
||||||
|
|
||||||
self.remove_aliases()
|
self.remove_aliases()
|
||||||
|
|
||||||
if definition['kind'].endswith('List'):
|
|
||||||
result['result'] = resource.get(namespace=namespace).to_dict()
|
|
||||||
result['changed'] = False
|
|
||||||
result['method'] = 'get'
|
|
||||||
return result
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# ignore append_hash for resources other than ConfigMap and Secret
|
# ignore append_hash for resources other than ConfigMap and Secret
|
||||||
if self.append_hash and definition['kind'] in ['ConfigMap', 'Secret']:
|
if self.append_hash and definition['kind'] in ['ConfigMap', 'Secret']:
|
||||||
|
|
140
test/integration/targets/k8s/playbooks/roles/k8s/tasks/lists.yml
Normal file
140
test/integration/targets/k8s/playbooks/roles/k8s/tasks/lists.yml
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: Ensure testing1 namespace exists
|
||||||
|
k8s:
|
||||||
|
api_version: v1
|
||||||
|
kind: Namespace
|
||||||
|
name: testing1
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: Create configmaps
|
||||||
|
k8s:
|
||||||
|
namespace: testing1
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMapList
|
||||||
|
items: '{{ configmaps }}'
|
||||||
|
|
||||||
|
- name: Get ConfigMaps
|
||||||
|
k8s_facts:
|
||||||
|
api_version: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
namespace: testing1
|
||||||
|
label_selectors:
|
||||||
|
- app=test
|
||||||
|
register: cms
|
||||||
|
|
||||||
|
- name: All three configmaps should exist
|
||||||
|
assert:
|
||||||
|
that: item.data.a is defined
|
||||||
|
with_items: '{{ cms.resources }}'
|
||||||
|
|
||||||
|
- name: Delete configmaps
|
||||||
|
k8s:
|
||||||
|
state: absent
|
||||||
|
namespace: testing1
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMapList
|
||||||
|
items: '{{ configmaps }}'
|
||||||
|
|
||||||
|
- name: Get ConfigMaps
|
||||||
|
k8s_facts:
|
||||||
|
api_version: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
namespace: testing1
|
||||||
|
label_selectors:
|
||||||
|
- app=test
|
||||||
|
register: cms
|
||||||
|
|
||||||
|
- name: All three configmaps should not exist
|
||||||
|
assert:
|
||||||
|
that: not cms.resources
|
||||||
|
vars:
|
||||||
|
configmaps:
|
||||||
|
- metadata:
|
||||||
|
name: list-example-1
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
data:
|
||||||
|
a: first
|
||||||
|
- metadata:
|
||||||
|
name: list-example-2
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
data:
|
||||||
|
a: second
|
||||||
|
- metadata:
|
||||||
|
name: list-example-3
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
data:
|
||||||
|
a: third
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: Create list of arbitrary resources
|
||||||
|
k8s:
|
||||||
|
namespace: testing1
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: List
|
||||||
|
namespace: testing1
|
||||||
|
items: '{{ resources }}'
|
||||||
|
|
||||||
|
- name: Get the created resources
|
||||||
|
k8s_facts:
|
||||||
|
api_version: '{{ item.apiVersion }}'
|
||||||
|
kind: '{{ item.kind }}'
|
||||||
|
namespace: testing1
|
||||||
|
name: '{{ item.metadata.name }}'
|
||||||
|
register: list_resources
|
||||||
|
with_items: '{{ resources }}'
|
||||||
|
|
||||||
|
- name: All resources should exist
|
||||||
|
assert:
|
||||||
|
that: ((list_resources.results | sum(attribute="resources", start=[])) | length) == (resources | length)
|
||||||
|
|
||||||
|
- name: Delete list of arbitrary resources
|
||||||
|
k8s:
|
||||||
|
state: absent
|
||||||
|
namespace: testing1
|
||||||
|
definition:
|
||||||
|
apiVersion: v1
|
||||||
|
kind: List
|
||||||
|
namespace: testing1
|
||||||
|
items: '{{ resources }}'
|
||||||
|
|
||||||
|
- name: Get the resources
|
||||||
|
k8s_facts:
|
||||||
|
api_version: '{{ item.apiVersion }}'
|
||||||
|
kind: '{{ item.kind }}'
|
||||||
|
namespace: testing1
|
||||||
|
name: '{{ item.metadata.name }}'
|
||||||
|
register: list_resources
|
||||||
|
with_items: '{{ resources }}'
|
||||||
|
|
||||||
|
- name: The resources should not exist
|
||||||
|
assert:
|
||||||
|
that: not ((list_resources.results | sum(attribute="resources", start=[])) | length)
|
||||||
|
vars:
|
||||||
|
resources:
|
||||||
|
- apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: list-example-4
|
||||||
|
data:
|
||||||
|
key: value
|
||||||
|
- apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: list-example-svc
|
||||||
|
labels:
|
||||||
|
app: test
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: test
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
targetPort: 8000
|
||||||
|
name: port-8000-tcp
|
||||||
|
port: 8000
|
|
@ -285,6 +285,7 @@
|
||||||
loop: "{{ k8s_facts.results }}"
|
loop: "{{ k8s_facts.results }}"
|
||||||
|
|
||||||
- include_tasks: crd.yml
|
- include_tasks: crd.yml
|
||||||
|
- include_tasks: lists.yml
|
||||||
- include_tasks: append_hash.yml
|
- include_tasks: append_hash.yml
|
||||||
|
|
||||||
always:
|
always:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue