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):
|
||||
changed = False
|
||||
results = []
|
||||
self.client = self.get_api_client()
|
||||
|
||||
flattened_definitions = []
|
||||
for definition in self.resource_definitions:
|
||||
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)
|
||||
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)
|
||||
self.warnings = []
|
||||
if self.params['validate'] is not None:
|
||||
|
@ -177,12 +194,12 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
|||
def set_defaults(self, resource, definition):
|
||||
definition['kind'] = resource.kind
|
||||
definition['apiVersion'] = resource.group_version
|
||||
if not definition.get('metadata'):
|
||||
definition['metadata'] = {}
|
||||
if self.name and not definition['metadata'].get('name'):
|
||||
definition['metadata']['name'] = self.name
|
||||
if resource.namespaced and self.namespace and not definition['metadata'].get('namespace'):
|
||||
definition['metadata']['namespace'] = self.namespace
|
||||
metadata = definition.get('metadata', {})
|
||||
if self.name and not metadata.get('name'):
|
||||
metadata['name'] = self.name
|
||||
if resource.namespaced and self.namespace and not metadata.get('namespace'):
|
||||
metadata['namespace'] = self.namespace
|
||||
definition['metadata'] = metadata
|
||||
return definition
|
||||
|
||||
def perform_action(self, resource, definition):
|
||||
|
@ -197,12 +214,6 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
|||
|
||||
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:
|
||||
# ignore append_hash for resources other than ConfigMap and 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 }}"
|
||||
|
||||
- include_tasks: crd.yml
|
||||
- include_tasks: lists.yml
|
||||
- include_tasks: append_hash.yml
|
||||
|
||||
always:
|
||||
|
|
Loading…
Reference in a new issue