mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
[k8s] allow user to pass list of resources in to definition parameter (#42377)
* allow user to pass list of resources in to definition parameter * Add new validator for list|dict|string * use string_types instead of string * state/force information is lost after the first item in the list * Add tests * Appease ansibot
This commit is contained in:
parent
dfb2b3fdd5
commit
e9c7b513a1
4 changed files with 125 additions and 5 deletions
|
@ -22,8 +22,8 @@ import os
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
|
|
||||||
from ansible.module_utils.six import iteritems
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
|
from ansible.module_utils.six import iteritems, string_types
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import kubernetes
|
import kubernetes
|
||||||
|
@ -51,6 +51,16 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def list_dict_str(value):
|
||||||
|
if isinstance(value, list):
|
||||||
|
return value
|
||||||
|
elif isinstance(value, dict):
|
||||||
|
return value
|
||||||
|
elif isinstance(value, string_types):
|
||||||
|
return value
|
||||||
|
raise TypeError
|
||||||
|
|
||||||
ARG_ATTRIBUTES_BLACKLIST = ('property_path',)
|
ARG_ATTRIBUTES_BLACKLIST = ('property_path',)
|
||||||
|
|
||||||
COMMON_ARG_SPEC = {
|
COMMON_ARG_SPEC = {
|
||||||
|
@ -63,6 +73,7 @@ COMMON_ARG_SPEC = {
|
||||||
'default': False,
|
'default': False,
|
||||||
},
|
},
|
||||||
'resource_definition': {
|
'resource_definition': {
|
||||||
|
'type': list_dict_str,
|
||||||
'aliases': ['definition', 'inline']
|
'aliases': ['definition', 'inline']
|
||||||
},
|
},
|
||||||
'src': {
|
'src': {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
from __future__ import absolute_import, division, print_function
|
from __future__ import absolute_import, division, print_function
|
||||||
|
|
||||||
|
|
||||||
|
from ansible.module_utils.six import string_types
|
||||||
from ansible.module_utils.k8s.common import KubernetesAnsibleModule
|
from ansible.module_utils.k8s.common import KubernetesAnsibleModule
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,11 +51,13 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
||||||
namespace = self.params.pop('namespace')
|
namespace = self.params.pop('namespace')
|
||||||
resource_definition = self.params.pop('resource_definition')
|
resource_definition = self.params.pop('resource_definition')
|
||||||
if resource_definition:
|
if resource_definition:
|
||||||
if isinstance(resource_definition, str):
|
if isinstance(resource_definition, string_types):
|
||||||
try:
|
try:
|
||||||
self.resource_definitions = yaml.safe_load_all(resource_definition)
|
self.resource_definitions = yaml.safe_load_all(resource_definition)
|
||||||
except (IOError, yaml.YAMLError) as exc:
|
except (IOError, yaml.YAMLError) as exc:
|
||||||
self.fail(msg="Error loading resource_definition: {0}".format(exc))
|
self.fail(msg="Error loading resource_definition: {0}".format(exc))
|
||||||
|
elif isinstance(resource_definition, list):
|
||||||
|
self.resource_definitions = resource_definition
|
||||||
else:
|
else:
|
||||||
self.resource_definitions = [resource_definition]
|
self.resource_definitions = [resource_definition]
|
||||||
src = self.params.pop('src')
|
src = self.params.pop('src')
|
||||||
|
@ -100,8 +103,8 @@ class KubernetesRawModule(KubernetesAnsibleModule):
|
||||||
|
|
||||||
def perform_action(self, resource, definition):
|
def perform_action(self, resource, definition):
|
||||||
result = {'changed': False, 'result': {}}
|
result = {'changed': False, 'result': {}}
|
||||||
state = self.params.pop('state', None)
|
state = self.params.get('state', None)
|
||||||
force = self.params.pop('force', False)
|
force = self.params.get('force', False)
|
||||||
name = definition.get('metadata', {}).get('name')
|
name = definition.get('metadata', {}).get('name')
|
||||||
namespace = definition.get('metadata', {}).get('namespace')
|
namespace = definition.get('metadata', {}).get('namespace')
|
||||||
existing = None
|
existing = None
|
||||||
|
|
|
@ -25,7 +25,7 @@ class ModuleDocFragment(object):
|
||||||
options:
|
options:
|
||||||
resource_definition:
|
resource_definition:
|
||||||
description:
|
description:
|
||||||
- "Provide a valid YAML definition (either as a string or a dict) for an object when creating or updating. NOTE: I(kind), I(api_version), I(name),
|
- "Provide a valid YAML definition (either as a string, list, or dict) for an object when creating or updating. NOTE: I(kind), I(api_version), I(name),
|
||||||
and I(namespace) will be overwritten by corresponding values found in the provided I(resource_definition)."
|
and I(namespace) will be overwritten by corresponding values found in the provided I(resource_definition)."
|
||||||
aliases:
|
aliases:
|
||||||
- definition
|
- definition
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
pip:
|
pip:
|
||||||
name: openshift
|
name: openshift
|
||||||
|
|
||||||
|
# TODO: This is the only way I could get the kubeconfig, I don't know why. Running the lookup outside of debug seems to return an empty string
|
||||||
|
- debug: msg={{ lookup('env', 'K8S_AUTH_KUBECONFIG') }}
|
||||||
|
register: kubeconfig
|
||||||
|
|
||||||
# Kubernetes resources
|
# Kubernetes resources
|
||||||
- name: Create a namespace
|
- name: Create a namespace
|
||||||
k8s:
|
k8s:
|
||||||
|
@ -9,6 +13,8 @@
|
||||||
kind: namespace
|
kind: namespace
|
||||||
register: output
|
register: output
|
||||||
|
|
||||||
|
- debug: msg={{ lookup("k8s", kind="Namespace", api_version="v1", resource_name='testing', kubeconfig=kubeconfig.msg) }}
|
||||||
|
|
||||||
- name: show output
|
- name: show output
|
||||||
debug:
|
debug:
|
||||||
var: output
|
var: output
|
||||||
|
@ -188,3 +194,103 @@
|
||||||
- name: DC creation should be idempotent
|
- name: DC creation should be idempotent
|
||||||
assert:
|
assert:
|
||||||
that: not output.changed
|
that: not output.changed
|
||||||
|
|
||||||
|
### Type tests
|
||||||
|
- name: Create a namespace from a string
|
||||||
|
k8s:
|
||||||
|
definition: |+
|
||||||
|
---
|
||||||
|
kind: Namespace
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: testing1
|
||||||
|
|
||||||
|
- name: Namespace should exist
|
||||||
|
assert:
|
||||||
|
that: '{{ lookup("k8s", kind="Namespace", api_version="v1", resource_name="testing1", kubeconfig=kubeconfig.msg).status.phase == "Active" }}'
|
||||||
|
|
||||||
|
- name: Create resources from a multidocument yaml string
|
||||||
|
k8s:
|
||||||
|
definition: |+
|
||||||
|
---
|
||||||
|
kind: Namespace
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: testing2
|
||||||
|
---
|
||||||
|
kind: Namespace
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: testing3
|
||||||
|
|
||||||
|
- name: Resources should exist
|
||||||
|
assert:
|
||||||
|
that: lookup("k8s", kind="Namespace", api_version="v1", resource_name=item, kubeconfig=kubeconfig.msg).status.phase == "Active"
|
||||||
|
loop:
|
||||||
|
- testing2
|
||||||
|
- testing3
|
||||||
|
|
||||||
|
- name: Delete resources from a multidocument yaml string
|
||||||
|
k8s:
|
||||||
|
state: absent
|
||||||
|
definition: |+
|
||||||
|
---
|
||||||
|
kind: Namespace
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: testing2
|
||||||
|
---
|
||||||
|
kind: Namespace
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: testing3
|
||||||
|
|
||||||
|
- name: Resources should not exist
|
||||||
|
assert:
|
||||||
|
that: not ns or ns.status.phase == "Terminating"
|
||||||
|
loop:
|
||||||
|
- testing2
|
||||||
|
- testing3
|
||||||
|
vars:
|
||||||
|
ns: '{{ lookup("k8s", kind="Namespace", api_version="v1", resource_name=item, kubeconfig=kubeconfig.msg) }}'
|
||||||
|
|
||||||
|
- name: Create resources from a list
|
||||||
|
k8s:
|
||||||
|
definition:
|
||||||
|
- kind: Namespace
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: testing4
|
||||||
|
- kind: Namespace
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: testing5
|
||||||
|
|
||||||
|
- name: Resources should exist
|
||||||
|
assert:
|
||||||
|
that: lookup("k8s", kind="Namespace", api_version="v1", resource_name=item, kubeconfig=kubeconfig.msg).status.phase == "Active"
|
||||||
|
loop:
|
||||||
|
- testing4
|
||||||
|
- testing5
|
||||||
|
|
||||||
|
- name: Delete resources from a list
|
||||||
|
k8s:
|
||||||
|
state: absent
|
||||||
|
definition:
|
||||||
|
- kind: Namespace
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: testing4
|
||||||
|
- kind: Namespace
|
||||||
|
apiVersion: v1
|
||||||
|
metadata:
|
||||||
|
name: testing5
|
||||||
|
|
||||||
|
- name: Resources should not exist
|
||||||
|
assert:
|
||||||
|
that: not ns or ns.status.phase == "Terminating"
|
||||||
|
loop:
|
||||||
|
- testing4
|
||||||
|
- testing5
|
||||||
|
vars:
|
||||||
|
ns: '{{ lookup("k8s", kind="Namespace", api_version="v1", resource_name=item, kubeconfig=kubeconfig.msg) }}'
|
||||||
|
|
Loading…
Reference in a new issue