kube Module Enhancements

* Multiple files are now supported across operations.
  * Can be specified as a list or a comma separated string.
  * Single item per task params will still work without changes.
* Added `files`, `filenames`, and `file`, as aliases for the `filename` param.
* Improved output of error message to always include stderr
* `exists` now supports checking files

Follow up PRs encouraged across roles to start converting `with_items` loops on `kube` tasks into `files` param lists so we can improve performance.
This commit is contained in:
Chad Swenson 2018-03-07 14:50:09 -06:00
parent cc182ea2f3
commit 8960d5bcfa

View file

@ -18,7 +18,9 @@ options:
required: false required: false
default: null default: null
description: description:
- The path and filename of the resource(s) definition file. - The path and filename of the resource(s) definition file(s).
- To operate on several files this can accept a comma separated list of files or a list of files.
aliases: [ 'files', 'file', 'filenames' ]
kubectl: kubectl:
required: false required: false
default: null default: null
@ -86,6 +88,15 @@ EXAMPLES = """
- name: test nginx is present - name: test nginx is present
kube: filename=/tmp/nginx.yml kube: filename=/tmp/nginx.yml
- name: test nginx and postgresql are present
kube: files=/tmp/nginx.yml,/tmp/postgresql.yml
- name: test nginx and postgresql are present
kube:
files:
- /tmp/nginx.yml
- /tmp/postgresql.yml
""" """
@ -112,7 +123,7 @@ class KubeManager(object):
self.all = module.params.get('all') self.all = module.params.get('all')
self.force = module.params.get('force') self.force = module.params.get('force')
self.name = module.params.get('name') self.name = module.params.get('name')
self.filename = module.params.get('filename') self.filename = [f.strip() for f in module.params.get('filename') or []]
self.resource = module.params.get('resource') self.resource = module.params.get('resource')
self.label = module.params.get('label') self.label = module.params.get('label')
@ -122,7 +133,7 @@ class KubeManager(object):
rc, out, err = self.module.run_command(args) rc, out, err = self.module.run_command(args)
if rc != 0: if rc != 0:
self.module.fail_json( self.module.fail_json(
msg='error running kubectl (%s) command (rc=%d): %s' % (' '.join(args), rc, out or err)) msg='error running kubectl (%s) command (rc=%d), out=\'%s\', err=\'%s\'' % (' '.join(args), rc, out, err))
except Exception as exc: except Exception as exc:
self.module.fail_json( self.module.fail_json(
msg='error running kubectl (%s) command: %s' % (' '.join(args), str(exc))) msg='error running kubectl (%s) command: %s' % (' '.join(args), str(exc)))
@ -147,7 +158,7 @@ class KubeManager(object):
if not self.filename: if not self.filename:
self.module.fail_json(msg='filename required to create') self.module.fail_json(msg='filename required to create')
cmd.append('--filename=' + self.filename) cmd.append('--filename=' + ','.join(self.filename))
return self._execute(cmd) return self._execute(cmd)
@ -161,7 +172,7 @@ class KubeManager(object):
if not self.filename: if not self.filename:
self.module.fail_json(msg='filename required to reload') self.module.fail_json(msg='filename required to reload')
cmd.append('--filename=' + self.filename) cmd.append('--filename=' + ','.join(self.filename))
return self._execute(cmd) return self._execute(cmd)
@ -173,7 +184,7 @@ class KubeManager(object):
cmd = ['delete'] cmd = ['delete']
if self.filename: if self.filename:
cmd.append('--filename=' + self.filename) cmd.append('--filename=' + ','.join(self.filename))
else: else:
if not self.resource: if not self.resource:
self.module.fail_json(msg='resource required to delete without filename') self.module.fail_json(msg='resource required to delete without filename')
@ -197,27 +208,31 @@ class KubeManager(object):
def exists(self): def exists(self):
cmd = ['get'] cmd = ['get']
if not self.resource: if self.filename:
return False cmd.append('--filename=' + ','.join(self.filename))
else:
if not self.resource:
self.module.fail_json(msg='resource required without filename')
cmd.append(self.resource) cmd.append(self.resource)
if self.name: if self.name:
cmd.append(self.name) cmd.append(self.name)
if self.label:
cmd.append('--selector=' + self.label)
if self.all:
cmd.append('--all-namespaces')
cmd.append('--no-headers') cmd.append('--no-headers')
if self.label:
cmd.append('--selector=' + self.label)
if self.all:
cmd.append('--all-namespaces')
result = self._execute_nofail(cmd) result = self._execute_nofail(cmd)
if not result: if not result:
return False return False
return True return True
# TODO: This is currently unused, perhaps convert to 'scale' with a replicas param?
def stop(self): def stop(self):
if not self.force and not self.exists(): if not self.force and not self.exists():
@ -226,7 +241,7 @@ class KubeManager(object):
cmd = ['stop'] cmd = ['stop']
if self.filename: if self.filename:
cmd.append('--filename=' + self.filename) cmd.append('--filename=' + ','.join(self.filename))
else: else:
if not self.resource: if not self.resource:
self.module.fail_json(msg='resource required to stop without filename') self.module.fail_json(msg='resource required to stop without filename')
@ -253,7 +268,7 @@ def main():
module = AnsibleModule( module = AnsibleModule(
argument_spec=dict( argument_spec=dict(
name=dict(), name=dict(),
filename=dict(), filename=dict(type='list', aliases=['files', 'file', 'filenames']),
namespace=dict(), namespace=dict(),
resource=dict(), resource=dict(),
label=dict(), label=dict(),
@ -263,7 +278,8 @@ def main():
all=dict(default=False, type='bool'), all=dict(default=False, type='bool'),
log_level=dict(default=0, type='int'), log_level=dict(default=0, type='int'),
state=dict(default='present', choices=['present', 'absent', 'latest', 'reloaded', 'stopped']), state=dict(default='present', choices=['present', 'absent', 'latest', 'reloaded', 'stopped']),
) ),
mutually_exclusive=[['filename', 'list']]
) )
changed = False changed = False