Skip to content

Commit

Permalink
[k8s] allow user to pass list of resources in to definition parameter (
Browse files Browse the repository at this point in the history
…#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
  • Loading branch information
fabianvf authored and jimi-c committed Jul 9, 2018
1 parent dfb2b3f commit e9c7b51
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 5 deletions.
13 changes: 12 additions & 1 deletion lib/ansible/module_utils/k8s/common.py
Expand Up @@ -22,8 +22,8 @@
import copy


from ansible.module_utils.six import iteritems
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six import iteritems, string_types

try:
import kubernetes
Expand Down Expand Up @@ -51,6 +51,16 @@
except ImportError:
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',)

COMMON_ARG_SPEC = {
Expand All @@ -63,6 +73,7 @@
'default': False,
},
'resource_definition': {
'type': list_dict_str,
'aliases': ['definition', 'inline']
},
'src': {
Expand Down
9 changes: 6 additions & 3 deletions lib/ansible/module_utils/k8s/raw.py
Expand Up @@ -19,6 +19,7 @@
from __future__ import absolute_import, division, print_function


from ansible.module_utils.six import string_types
from ansible.module_utils.k8s.common import KubernetesAnsibleModule


Expand Down Expand Up @@ -50,11 +51,13 @@ def __init__(self, *args, **kwargs):
namespace = self.params.pop('namespace')
resource_definition = self.params.pop('resource_definition')
if resource_definition:
if isinstance(resource_definition, str):
if isinstance(resource_definition, string_types):
try:
self.resource_definitions = yaml.safe_load_all(resource_definition)
except (IOError, yaml.YAMLError) as exc:
self.fail(msg="Error loading resource_definition: {0}".format(exc))
elif isinstance(resource_definition, list):
self.resource_definitions = resource_definition
else:
self.resource_definitions = [resource_definition]
src = self.params.pop('src')
Expand Down Expand Up @@ -100,8 +103,8 @@ def execute_module(self):

def perform_action(self, resource, definition):
result = {'changed': False, 'result': {}}
state = self.params.pop('state', None)
force = self.params.pop('force', False)
state = self.params.get('state', None)
force = self.params.get('force', False)
name = definition.get('metadata', {}).get('name')
namespace = definition.get('metadata', {}).get('namespace')
existing = None
Expand Down
Expand Up @@ -25,7 +25,7 @@ class ModuleDocFragment(object):
options:
resource_definition:
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)."
aliases:
- definition
Expand Down
106 changes: 106 additions & 0 deletions test/integration/targets/k8s/tasks/main.yml
Expand Up @@ -2,13 +2,19 @@
pip:
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
- name: Create a namespace
k8s:
name: testing
kind: namespace
register: output

- debug: msg={{ lookup("k8s", kind="Namespace", api_version="v1", resource_name='testing', kubeconfig=kubeconfig.msg) }}

- name: show output
debug:
var: output
Expand Down Expand Up @@ -188,3 +194,103 @@
- name: DC creation should be idempotent
assert:
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) }}'

0 comments on commit e9c7b51

Please sign in to comment.