summaryrefslogtreecommitdiffstats
path: root/roles/lib_openshift_api/build
diff options
context:
space:
mode:
authorKenny Woodson <kwoodson@redhat.com>2016-03-28 17:44:48 -0400
committerKenny Woodson <kwoodson@redhat.com>2016-03-30 12:19:31 -0400
commit15d730f3aec1f579dbd3cc5310264c68eb78e242 (patch)
treeb32f0efa16101b1f47d70514d7a318c46fe3d76b /roles/lib_openshift_api/build
parente1f6415cbcc4145402011fb4183a5dead2f22124 (diff)
downloadopenshift-15d730f3aec1f579dbd3cc5310264c68eb78e242.tar.gz
openshift-15d730f3aec1f579dbd3cc5310264c68eb78e242.tar.bz2
openshift-15d730f3aec1f579dbd3cc5310264c68eb78e242.tar.xz
openshift-15d730f3aec1f579dbd3cc5310264c68eb78e242.zip
Moving generation of ansible module side by side with module.
Diffstat (limited to 'roles/lib_openshift_api/build')
-rw-r--r--roles/lib_openshift_api/build/ansible/obj.py132
-rw-r--r--roles/lib_openshift_api/build/ansible/secret.py121
-rwxr-xr-xroles/lib_openshift_api/build/generate.py53
-rw-r--r--roles/lib_openshift_api/build/src/base.py242
-rw-r--r--roles/lib_openshift_api/build/src/obj.py78
-rw-r--r--roles/lib_openshift_api/build/src/secret.py68
-rw-r--r--roles/lib_openshift_api/build/test/README5
-rwxr-xr-xroles/lib_openshift_api/build/test/deploymentconfig.yml120
-rw-r--r--roles/lib_openshift_api/build/test/files/config.yml1
-rw-r--r--roles/lib_openshift_api/build/test/files/dc-mod.yml124
-rw-r--r--roles/lib_openshift_api/build/test/files/dc.yml121
-rw-r--r--roles/lib_openshift_api/build/test/files/passwords.yml4
-rw-r--r--roles/lib_openshift_api/build/test/files/router-mod.json30
-rw-r--r--roles/lib_openshift_api/build/test/files/router.json29
l---------roles/lib_openshift_api/build/test/roles1
-rwxr-xr-xroles/lib_openshift_api/build/test/secrets.yml81
-rwxr-xr-xroles/lib_openshift_api/build/test/services.yml133
17 files changed, 1343 insertions, 0 deletions
diff --git a/roles/lib_openshift_api/build/ansible/obj.py b/roles/lib_openshift_api/build/ansible/obj.py
new file mode 100644
index 000000000..0796d807e
--- /dev/null
+++ b/roles/lib_openshift_api/build/ansible/obj.py
@@ -0,0 +1,132 @@
+# pylint: skip-file
+
+# pylint: disable=too-many-branches
+def main():
+ '''
+ ansible oc module for services
+ '''
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ kubeconfig=dict(default='/etc/origin/master/admin.kubeconfig', type='str'),
+ state=dict(default='present', type='str',
+ choices=['present', 'absent', 'list']),
+ debug=dict(default=False, type='bool'),
+ namespace=dict(default='default', type='str'),
+ name=dict(default=None, type='str'),
+ files=dict(default=None, type='list'),
+ kind=dict(required=True,
+ type='str',
+ choices=['dc', 'deploymentconfig',
+ 'svc', 'service',
+ 'secret',
+ ]),
+ delete_after=dict(default=False, type='bool'),
+ content=dict(default=None, type='dict'),
+ force=dict(default=False, type='bool'),
+ ),
+ mutually_exclusive=[["content", "files"]],
+
+ supports_check_mode=True,
+ )
+ ocobj = OCObject(module.params['kind'],
+ module.params['namespace'],
+ module.params['name'],
+ kubeconfig=module.params['kubeconfig'],
+ verbose=module.params['debug'])
+
+ state = module.params['state']
+
+ api_rval = ocobj.get()
+
+ #####
+ # Get
+ #####
+ if state == 'list':
+ module.exit_json(changed=False, results=api_rval['results'], state="list")
+
+ if not module.params['name']:
+ module.fail_json(msg='Please specify a name when state is absent|present.')
+ ########
+ # Delete
+ ########
+ if state == 'absent':
+ if not Utils.exists(api_rval['results'], module.params['name']):
+ module.exit_json(changed=False, state="absent")
+
+ if module.check_mode:
+ module.exit_json(change=False, msg='Would have performed a delete.')
+
+ api_rval = ocobj.delete()
+ module.exit_json(changed=True, results=api_rval, state="absent")
+
+ if state == 'present':
+ ########
+ # Create
+ ########
+ if not Utils.exists(api_rval['results'], module.params['name']):
+
+ if module.check_mode:
+ module.exit_json(change=False, msg='Would have performed a create.')
+
+ # Create it here
+ api_rval = ocobj.create(module.params['files'], module.params['content'])
+ if api_rval['returncode'] != 0:
+ module.fail_json(msg=api_rval)
+
+ # return the created object
+ api_rval = ocobj.get()
+
+ if api_rval['returncode'] != 0:
+ module.fail_json(msg=api_rval)
+
+ # Remove files
+ if module.params['files'] and module.params['delete_after']:
+ Utils.cleanup(module.params['files'])
+
+ module.exit_json(changed=True, results=api_rval, state="present")
+
+ ########
+ # Update
+ ########
+ # if a file path is passed, use it.
+ update = ocobj.needs_update(module.params['files'], module.params['content'])
+ if not isinstance(update, bool):
+ module.fail_json(msg=update)
+
+ # No changes
+ if not update:
+ if module.params['files'] and module.params['delete_after']:
+ Utils.cleanup(module.params['files'])
+
+ module.exit_json(changed=False, results=api_rval['results'][0], state="present")
+
+ if module.check_mode:
+ module.exit_json(change=False, msg='Would have performed an update.')
+
+ api_rval = ocobj.update(module.params['files'],
+ module.params['content'],
+ module.params['force'])
+
+
+ if api_rval['returncode'] != 0:
+ module.fail_json(msg=api_rval)
+
+ # return the created object
+ api_rval = ocobj.get()
+
+ if api_rval['returncode'] != 0:
+ module.fail_json(msg=api_rval)
+
+ module.exit_json(changed=True, results=api_rval, state="present")
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_openshift_api/build/ansible/secret.py b/roles/lib_openshift_api/build/ansible/secret.py
new file mode 100644
index 000000000..8df7bbc64
--- /dev/null
+++ b/roles/lib_openshift_api/build/ansible/secret.py
@@ -0,0 +1,121 @@
+# pylint: skip-file
+
+# pylint: disable=too-many-branches
+def main():
+ '''
+ ansible oc module for secrets
+ '''
+
+ module = AnsibleModule(
+ argument_spec=dict(
+ kubeconfig=dict(default='/etc/origin/master/admin.kubeconfig', type='str'),
+ state=dict(default='present', type='str',
+ choices=['present', 'absent', 'list']),
+ debug=dict(default=False, type='bool'),
+ namespace=dict(default='default', type='str'),
+ name=dict(default=None, type='str'),
+ files=dict(default=None, type='list'),
+ delete_after=dict(default=False, type='bool'),
+ contents=dict(default=None, type='list'),
+ force=dict(default=False, type='bool'),
+ ),
+ mutually_exclusive=[["contents", "files"]],
+
+ supports_check_mode=True,
+ )
+ occmd = Secret(module.params['namespace'],
+ module.params['name'],
+ kubeconfig=module.params['kubeconfig'],
+ verbose=module.params['debug'])
+
+ state = module.params['state']
+
+ api_rval = occmd.get()
+
+ #####
+ # Get
+ #####
+ if state == 'list':
+ module.exit_json(changed=False, results=api_rval['results'], state="list")
+
+ if not module.params['name']:
+ module.fail_json(msg='Please specify a name when state is absent|present.')
+ ########
+ # Delete
+ ########
+ if state == 'absent':
+ if not Utils.exists(api_rval['results'], module.params['name']):
+ module.exit_json(changed=False, state="absent")
+
+ if module.check_mode:
+ module.exit_json(change=False, msg='Would have performed a delete.')
+
+ api_rval = occmd.delete()
+ module.exit_json(changed=True, results=api_rval, state="absent")
+
+
+ if state == 'present':
+ if module.params['files']:
+ files = module.params['files']
+ elif module.params['contents']:
+ files = Utils.create_files_from_contents(module.params['contents'])
+ else:
+ module.fail_json(msg='Either specify files or contents.')
+
+ ########
+ # Create
+ ########
+ if not Utils.exists(api_rval['results'], module.params['name']):
+
+ if module.check_mode:
+ module.exit_json(change=False, msg='Would have performed a create.')
+
+ api_rval = occmd.create(module.params['files'], module.params['contents'])
+
+ # Remove files
+ if files and module.params['delete_after']:
+ Utils.cleanup(files)
+
+ module.exit_json(changed=True, results=api_rval, state="present")
+
+ ########
+ # Update
+ ########
+ secret = occmd.prep_secret(module.params['files'], module.params['contents'])
+
+ if secret['returncode'] != 0:
+ module.fail_json(msg=secret)
+
+ if Utils.check_def_equal(secret['results'], api_rval['results'][0]):
+
+ # Remove files
+ if files and module.params['delete_after']:
+ Utils.cleanup(files)
+
+ module.exit_json(changed=False, results=secret['results'], state="present")
+
+ if module.check_mode:
+ module.exit_json(change=False, msg='Would have performed an update.')
+
+ api_rval = occmd.update(files, force=module.params['force'])
+
+ # Remove files
+ if secret and module.params['delete_after']:
+ Utils.cleanup(files)
+
+ if api_rval['returncode'] != 0:
+ module.fail_json(msg=api_rval)
+
+
+ module.exit_json(changed=True, results=api_rval, state="present")
+
+ module.exit_json(failed=True,
+ changed=False,
+ results='Unknown state passed. %s' % state,
+ state="unknown")
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import, locally-disabled
+# import module snippets. This are required
+from ansible.module_utils.basic import *
+
+main()
diff --git a/roles/lib_openshift_api/build/generate.py b/roles/lib_openshift_api/build/generate.py
new file mode 100755
index 000000000..ab70dd7f3
--- /dev/null
+++ b/roles/lib_openshift_api/build/generate.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+'''
+ Generate the openshift-ansible/roles/lib_openshift_cli/library/ modules.
+'''
+
+import os
+
+# pylint: disable=anomalous-backslash-in-string
+GEN_STR = "#!usr/bin/env python\n" + \
+ "# ___ ___ _ _ ___ ___ _ _____ ___ ___\n" + \
+ "# / __| __| \| | __| _ \ /_\_ _| __| \\\n" + \
+ "# | (_ | _|| .` | _|| / / _ \| | | _|| |) |\n" + \
+ "# \___|___|_|\_|___|_|_\/_/_\_\_|_|___|___/_ _____\n" + \
+ "# | \ / _ \ | \| |/ _ \_ _| | __| \_ _|_ _|\n" + \
+ "# | |) | (_) | | .` | (_) || | | _|| |) | | | |\n" + \
+ "# |___/ \___/ |_|\_|\___/ |_| |___|___/___| |_|\n"
+
+
+
+FILES = {'oc_obj.py': ['src/base.py',
+ '../../lib_yaml_editor/build/src/yedit.py',
+ 'src/obj.py',
+ 'ansible/obj.py',
+ ],
+ 'oc_secret.py': ['src/base.py',
+ '../../lib_yaml_editor/build/src/yedit.py',
+ 'src/secret.py',
+ 'ansible/secret.py',
+ ],
+ }
+
+
+def main():
+ ''' combine the necessary files to create the ansible module '''
+ openshift_ansible = ('../library/')
+ for fname, parts in FILES.items():
+ with open(os.path.join(openshift_ansible, fname), 'w') as afd:
+ afd.seek(0)
+ afd.write(GEN_STR)
+ for fpart in parts:
+ with open(fpart) as pfd:
+ # first line is pylint disable so skip it
+ for idx, line in enumerate(pfd):
+ if idx == 0 and 'skip-file' in line:
+ continue
+
+ afd.write(line)
+
+
+if __name__ == '__main__':
+ main()
+
+
diff --git a/roles/lib_openshift_api/build/src/base.py b/roles/lib_openshift_api/build/src/base.py
new file mode 100644
index 000000000..31c102e5d
--- /dev/null
+++ b/roles/lib_openshift_api/build/src/base.py
@@ -0,0 +1,242 @@
+# pylint: skip-file
+'''
+ OpenShiftCLI class that wraps the oc commands in a subprocess
+'''
+
+import atexit
+import json
+import os
+import shutil
+import subprocess
+import yaml
+
+# pylint: disable=too-few-public-methods
+class OpenShiftCLI(object):
+ ''' Class to wrap the oc command line tools '''
+ def __init__(self,
+ namespace,
+ kubeconfig='/etc/origin/master/admin.kubeconfig',
+ verbose=False):
+ ''' Constructor for OpenshiftOC '''
+ self.namespace = namespace
+ self.verbose = verbose
+ self.kubeconfig = kubeconfig
+
+ # Pylint allows only 5 arguments to be passed.
+ # pylint: disable=too-many-arguments
+ def _replace_content(self, resource, rname, content, force=False):
+ ''' replace the current object with the content '''
+ res = self._get(resource, rname)
+ if not res['results']:
+ return res
+
+ fname = '/tmp/%s' % rname
+ yed = Yedit(fname, res['results'][0])
+ for key, value in content.items():
+ yed.put(key, value)
+
+ atexit.register(Utils.cleanup, [fname])
+
+ return self._replace(fname, force)
+
+ def _replace(self, fname, force=False):
+ '''return all pods '''
+ cmd = ['-n', self.namespace, 'replace', '-f', fname]
+ if force:
+ cmd.append('--force')
+ return self.oc_cmd(cmd)
+
+ def _create(self, fname):
+ '''return all pods '''
+ return self.oc_cmd(['create', '-f', fname, '-n', self.namespace])
+
+ def _delete(self, resource, rname):
+ '''return all pods '''
+ return self.oc_cmd(['delete', resource, rname, '-n', self.namespace])
+
+ def _get(self, resource, rname=None):
+ '''return a secret by name '''
+ cmd = ['get', resource, '-o', 'json', '-n', self.namespace]
+ if rname:
+ cmd.append(rname)
+
+ rval = self.oc_cmd(cmd, output=True)
+
+ # Ensure results are retuned in an array
+ if rval.has_key('items'):
+ rval['results'] = rval['items']
+ elif not isinstance(rval['results'], list):
+ rval['results'] = [rval['results']]
+
+ return rval
+
+ def oc_cmd(self, cmd, output=False):
+ '''Base command for oc '''
+ #cmds = ['/usr/bin/oc', '--config', self.kubeconfig]
+ cmds = ['/usr/bin/oc']
+ cmds.extend(cmd)
+
+ results = ''
+
+ if self.verbose:
+ print ' '.join(cmds)
+
+ proc = subprocess.Popen(cmds,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ env={'KUBECONFIG': self.kubeconfig})
+ proc.wait()
+ if proc.returncode == 0:
+ if output:
+ try:
+ results = json.loads(proc.stdout.read())
+ except ValueError as err:
+ if "No JSON object could be decoded" in err.message:
+ results = err.message
+
+ if self.verbose:
+ print proc.stderr.read()
+ print results
+ print
+
+ return {"returncode": proc.returncode, "results": results}
+
+ return {"returncode": proc.returncode,
+ "stderr": proc.stderr.read(),
+ "stdout": proc.stdout.read(),
+ "results": {}
+ }
+
+class Utils(object):
+ ''' utilities for openshiftcli modules '''
+ @staticmethod
+ def create_file(rname, data, ftype=None):
+ ''' create a file in tmp with name and contents'''
+ path = os.path.join('/tmp', rname)
+ with open(path, 'w') as fds:
+ if ftype == 'yaml':
+ fds.write(yaml.safe_dump(data, default_flow_style=False))
+
+ elif ftype == 'json':
+ fds.write(json.dumps(data))
+ else:
+ fds.write(data)
+
+ # Register cleanup when module is done
+ atexit.register(Utils.cleanup, [path])
+ return path
+
+ @staticmethod
+ def create_files_from_contents(data):
+ '''Turn an array of dict: filename, content into a files array'''
+ files = []
+
+ for sfile in data:
+ path = Utils.create_file(sfile['path'], sfile['content'])
+ files.append(path)
+
+ return files
+
+ @staticmethod
+ def cleanup(files):
+ '''Clean up on exit '''
+ for sfile in files:
+ if os.path.exists(sfile):
+ if os.path.isdir(sfile):
+ shutil.rmtree(sfile)
+ elif os.path.isfile(sfile):
+ os.remove(sfile)
+
+
+ @staticmethod
+ def exists(results, _name):
+ ''' Check to see if the results include the name '''
+ if not results:
+ return False
+
+
+ if Utils.find_result(results, _name):
+ return True
+
+ return False
+
+ @staticmethod
+ def find_result(results, _name):
+ ''' Find the specified result by name'''
+ rval = None
+ for result in results:
+ if result.has_key('metadata') and result['metadata']['name'] == _name:
+ rval = result
+ break
+
+ return rval
+
+ @staticmethod
+ def get_resource_file(sfile, sfile_type='yaml'):
+ ''' return the service file '''
+ contents = None
+ with open(sfile) as sfd:
+ contents = sfd.read()
+
+ if sfile_type == 'yaml':
+ contents = yaml.load(contents)
+ elif sfile_type == 'json':
+ contents = json.loads(contents)
+
+ return contents
+
+ # Disabling too-many-branches. This is a yaml dictionary comparison function
+ # pylint: disable=too-many-branches,too-many-return-statements
+ @staticmethod
+ def check_def_equal(user_def, result_def, debug=False):
+ ''' Given a user defined definition, compare it with the results given back by our query. '''
+
+ # Currently these values are autogenerated and we do not need to check them
+ skip = ['metadata', 'status']
+
+ for key, value in result_def.items():
+ if key in skip:
+ continue
+
+ # Both are lists
+ if isinstance(value, list):
+ if not isinstance(user_def[key], list):
+ return False
+
+ # lists should be identical
+ if value != user_def[key]:
+ return False
+
+ # recurse on a dictionary
+ elif isinstance(value, dict):
+ if not isinstance(user_def[key], dict):
+ if debug:
+ print "dict returned false not instance of dict"
+ return False
+
+ # before passing ensure keys match
+ api_values = set(value.keys()) - set(skip)
+ user_values = set(user_def[key].keys()) - set(skip)
+ if api_values != user_values:
+ if debug:
+ print api_values
+ print user_values
+ print "keys are not equal in dict"
+ return False
+
+ result = Utils.check_def_equal(user_def[key], value, debug=debug)
+ if not result:
+ if debug:
+ print "dict returned false"
+ return False
+
+ # Verify each key, value pair is the same
+ else:
+ if not user_def.has_key(key) or value != user_def[key]:
+ if debug:
+ print "value not equal; user_def does not have key"
+ print value
+ print user_def[key]
+ return False
+
+ return True
diff --git a/roles/lib_openshift_api/build/src/obj.py b/roles/lib_openshift_api/build/src/obj.py
new file mode 100644
index 000000000..a3ad4b3c4
--- /dev/null
+++ b/roles/lib_openshift_api/build/src/obj.py
@@ -0,0 +1,78 @@
+# pylint: skip-file
+
+class OCObject(OpenShiftCLI):
+ ''' Class to wrap the oc command line tools '''
+
+ # pylint allows 5. we need 6
+ # pylint: disable=too-many-arguments
+ def __init__(self,
+ kind,
+ namespace,
+ rname=None,
+ kubeconfig='/etc/origin/master/admin.kubeconfig',
+ verbose=False):
+ ''' Constructor for OpenshiftOC '''
+ super(OCObject, self).__init__(namespace, kubeconfig)
+ self.kind = kind
+ self.namespace = namespace
+ self.name = rname
+ self.kubeconfig = kubeconfig
+ self.verbose = verbose
+
+ def get(self):
+ '''return a deploymentconfig by name '''
+ return self._get(self.kind, rname=self.name)
+
+ def delete(self):
+ '''return all pods '''
+ return self._delete(self.kind, self.name)
+
+ def create(self, files=None, content=None):
+ '''Create a deploymentconfig '''
+ if files:
+ return self._create(files[0])
+
+ return self._create(Utils.create_files_from_contents(content))
+
+
+ # pylint: disable=too-many-function-args
+ def update(self, files=None, content=None, force=False):
+ '''run update dc
+
+ This receives a list of file names and takes the first filename and calls replace.
+ '''
+ if files:
+ return self._replace(files[0], force)
+
+ return self.update_content(content, force)
+
+ def update_content(self, content, force=False):
+ '''update the dc with the content'''
+ return self._replace_content(self.kind, self.name, content, force=force)
+
+ def needs_update(self, files=None, content=None, content_type='yaml'):
+ ''' check to see if we need to update '''
+ objects = self.get()
+ if objects['returncode'] != 0:
+ return objects
+
+ # pylint: disable=no-member
+ data = None
+ if files:
+ data = Utils.get_resource_file(files[0], content_type)
+
+ # if equal then no need. So not equal is True
+ return not Utils.check_def_equal(data, objects['results'][0], True)
+ else:
+ data = content
+
+ for key, value in data.items():
+ if key == 'metadata':
+ continue
+ if not objects['results'][0].has_key(key):
+ return True
+ if value != objects['results'][0][key]:
+ return True
+
+ return False
+
diff --git a/roles/lib_openshift_api/build/src/secret.py b/roles/lib_openshift_api/build/src/secret.py
new file mode 100644
index 000000000..af61dfa01
--- /dev/null
+++ b/roles/lib_openshift_api/build/src/secret.py
@@ -0,0 +1,68 @@
+# pylint: skip-file
+
+class Secret(OpenShiftCLI):
+ ''' Class to wrap the oc command line tools
+ '''
+ def __init__(self,
+ namespace,
+ secret_name=None,
+ kubeconfig='/etc/origin/master/admin.kubeconfig',
+ verbose=False):
+ ''' Constructor for OpenshiftOC '''
+ super(Secret, self).__init__(namespace, kubeconfig)
+ self.namespace = namespace
+ self.name = secret_name
+ self.kubeconfig = kubeconfig
+ self.verbose = verbose
+
+ def get(self):
+ '''return a secret by name '''
+ return self._get('secrets', self.name)
+
+ def delete(self):
+ '''delete a secret by name'''
+ return self._delete('secrets', self.name)
+
+ def create(self, files=None, contents=None):
+ '''Create a secret '''
+ if not files:
+ files = Utils.create_files_from_contents(contents)
+
+ secrets = ["%s=%s" % (os.path.basename(sfile), sfile) for sfile in files]
+ cmd = ['-n%s' % self.namespace, 'secrets', 'new', self.name]
+ cmd.extend(secrets)
+
+ return self.oc_cmd(cmd)
+
+ def update(self, files, force=False):
+ '''run update secret
+
+ This receives a list of file names and converts it into a secret.
+ The secret is then written to disk and passed into the `oc replace` command.
+ '''
+ secret = self.prep_secret(files)
+ if secret['returncode'] != 0:
+ return secret
+
+ sfile_path = '/tmp/%s' % self.name
+ with open(sfile_path, 'w') as sfd:
+ sfd.write(json.dumps(secret['results']))
+
+ atexit.register(Utils.cleanup, [sfile_path])
+
+ return self._replace(sfile_path, force=force)
+
+ def prep_secret(self, files=None, contents=None):
+ ''' return what the secret would look like if created
+ This is accomplished by passing -ojson. This will most likely change in the future
+ '''
+ if not files:
+ files = Utils.create_files_from_contents(contents)
+
+ secrets = ["%s=%s" % (os.path.basename(sfile), sfile) for sfile in files]
+ cmd = ['-ojson', '-n%s' % self.namespace, 'secrets', 'new', self.name]
+ cmd.extend(secrets)
+
+ return self.oc_cmd(cmd, output=True)
+
+
diff --git a/roles/lib_openshift_api/build/test/README b/roles/lib_openshift_api/build/test/README
new file mode 100644
index 000000000..af9f05b3d
--- /dev/null
+++ b/roles/lib_openshift_api/build/test/README
@@ -0,0 +1,5 @@
+After generate.py has run, the ansible modules will be placed under ../../../openshift-ansible/roles/lib_openshift_api/library.
+
+
+To run the tests you need to run them like this:
+./services.yml -M ../../library
diff --git a/roles/lib_openshift_api/build/test/deploymentconfig.yml b/roles/lib_openshift_api/build/test/deploymentconfig.yml
new file mode 100755
index 000000000..d041ab22a
--- /dev/null
+++ b/roles/lib_openshift_api/build/test/deploymentconfig.yml
@@ -0,0 +1,120 @@
+#!/usr/bin/ansible-playbook
+---
+- hosts: "oo_clusterid_mwoodson:&oo_version_3:&oo_master_primary"
+ gather_facts: no
+ user: root
+
+ post_tasks:
+ - copy:
+ dest: "/tmp/{{ item }}"
+ src: "files/{{ item }}"
+ with_items:
+ - dc.yml
+
+ - name: list dc
+ oc_obj:
+ kind: dc
+ state: list
+ namespace: default
+ name: router
+ register: dcout
+
+ - debug:
+ var: dcout
+
+ - name: absent dc
+ oc_obj:
+ kind: dc
+ state: absent
+ namespace: default
+ name: router
+ register: dcout
+
+ - debug:
+ var: dcout
+
+ - name: present dc
+ oc_obj:
+ kind: dc
+ state: present
+ namespace: default
+ name: router
+ files:
+ - /tmp/dc.yml
+ register: dcout
+
+ - debug:
+ var: dcout
+
+ - name: dump router
+ oc_obj:
+ kind: dc
+ state: list
+ name: router
+ register: routerout
+
+ - name: write router file
+ copy:
+ dest: /tmp/dc-mod.json
+ content: "{{ routerout.results[0] }}"
+
+ - command: cat /tmp/dc-mod.json
+ register: catout
+
+ - debug:
+ msg: "{{ catout }}"
+
+ - command: "sed -i 's/: 80/: 81/g' /tmp/dc-mod.json"
+ register: catout
+
+ - name: present dc update
+ oc_obj:
+ kind: dc
+ state: present
+ namespace: default
+ name: router
+ files:
+ - /tmp/dc-mod.json
+ delete_after: True
+ register: dcout
+
+ - debug:
+ var: dcout
+
+ - include_vars: "files/dc-mod.yml"
+
+ - name: absent dc
+ oc_obj:
+ kind: dc
+ state: absent
+ namespace: default
+ name: router
+ register: dcout
+
+ - debug:
+ var: dcout
+
+ - name: present dc
+ oc_obj:
+ kind: dc
+ state: present
+ namespace: default
+ name: router
+ files:
+ - /tmp/dc.yml
+ delete_after: True
+ register: dcout
+
+ - name: present dc
+ oc_obj:
+ kind: dc
+ state: present
+ namespace: default
+ name: router
+ content: "{{ dc }}"
+ delete_after: True
+ register: dcout
+
+ - debug:
+ var: dcout
+
diff --git a/roles/lib_openshift_api/build/test/files/config.yml b/roles/lib_openshift_api/build/test/files/config.yml
new file mode 100644
index 000000000..c544c6fd4
--- /dev/null
+++ b/roles/lib_openshift_api/build/test/files/config.yml
@@ -0,0 +1 @@
+value: True
diff --git a/roles/lib_openshift_api/build/test/files/dc-mod.yml b/roles/lib_openshift_api/build/test/files/dc-mod.yml
new file mode 100644
index 000000000..6c700d6c7
--- /dev/null
+++ b/roles/lib_openshift_api/build/test/files/dc-mod.yml
@@ -0,0 +1,124 @@
+dc:
+ path:
+ dc-mod.yml
+ content:
+ apiVersion: v1
+ kind: DeploymentConfig
+ metadata:
+ labels:
+ router: router
+ name: router
+ namespace: default
+ resourceVersion: "84016"
+ selfLink: /oapi/v1/namespaces/default/deploymentconfigs/router
+ uid: 48f8b9d9-ed42-11e5-9903-0a9a9d4e7f2b
+ spec:
+ replicas: 2
+ selector:
+ router: router
+ strategy:
+ resources: {}
+ rollingParams:
+ intervalSeconds: 1
+ maxSurge: 0
+ maxUnavailable: 25%
+ timeoutSeconds: 600
+ updatePercent: -25
+ updatePeriodSeconds: 1
+ type: Rolling
+ template:
+ metadata:
+ creationTimestamp: null
+ labels:
+ router: router
+ spec:
+ containers:
+ - env:
+ - name: DEFAULT_CERTIFICATE
+ - name: OPENSHIFT_CA_DATA
+ value: |
+ -----BEGIN CERTIFICATE-----
+ MIIC5jCCAdCgAwIBAgIBATALBgkqhkiG9w0BAQswJjEkMCIGA1UEAwwbb3BlbnNo
+ -----END CERTIFICATE-----
+ - name: OPENSHIFT_CERT_DATA
+ value: |
+ -----BEGIN CERTIFICATE-----
+ MIIDDTCCAfegAwIBAgIBCDALBgkqhkiG9w0BAQswJjEkMCIGA1UEAwwbb3BlbnNo
+ -----END CERTIFICATE-----
+ - name: OPENSHIFT_INSECURE
+ value: "false"
+ - name: OPENSHIFT_KEY_DATA
+ value: |
+ -----BEGIN RSA PRIVATE KEY-----
+ MIIEogIBAAKCAQEA2lf49DrPHfCdCORcnIbmDVrx8yos7trjWdBvuledijyslRVR
+ -----END RSA PRIVATE KEY-----
+ - name: OPENSHIFT_MASTER
+ value: https://internal.api.mwoodson.openshift.com
+ - name: ROUTER_EXTERNAL_HOST_HOSTNAME
+ - name: ROUTER_EXTERNAL_HOST_HTTPS_VSERVER
+ - name: ROUTER_EXTERNAL_HOST_HTTP_VSERVER
+ - name: ROUTER_EXTERNAL_HOST_INSECURE
+ value: "false"
+ - name: ROUTER_EXTERNAL_HOST_PARTITION_PATH
+ - name: ROUTER_EXTERNAL_HOST_PASSWORD
+ - name: ROUTER_EXTERNAL_HOST_PRIVKEY
+ value: /etc/secret-volume/router.pem
+ - name: ROUTER_EXTERNAL_HOST_USERNAME
+ - name: ROUTER_SERVICE_NAME
+ value: router
+ - name: ROUTER_SERVICE_NAMESPACE
+ value: default
+ - name: STATS_PASSWORD
+ value: ugCk6YBm4q
+ - name: STATS_PORT
+ value: "1936"
+ - name: STATS_USERNAME
+ value: admin
+ image: openshift3/ose-haproxy-router:v3.1.1.6
+ imagePullPolicy: IfNotPresent
+ livenessProbe:
+ httpGet:
+ host: localhost
+ path: /healthz
+ port: 1936
+ scheme: HTTP
+ initialDelaySeconds: 10
+ timeoutSeconds: 1
+ name: router
+ ports:
+ - containerPort: 81
+ hostPort: 81
+ protocol: TCP
+ - containerPort: 443
+ hostPort: 443
+ protocol: TCP
+ - containerPort: 1936
+ hostPort: 1936
+ name: stats
+ protocol: TCP
+ readinessProbe:
+ httpGet:
+ host: localhost
+ path: /healthz
+ port: 1937
+ scheme: HTTP
+ timeoutSeconds: 1
+ resources: {}
+ terminationMessagePath: /dev/termination-log
+ dnsPolicy: ClusterFirst
+ hostNetwork: true
+ nodeSelector:
+ type: infra
+ restartPolicy: Always
+ securityContext: {}
+ serviceAccount: router
+ serviceAccountName: router
+ terminationGracePeriodSeconds: 30
+ triggers:
+ - type: ConfigChange
+ status:
+ details:
+ causes:
+ - type: ConfigChange
+ latestVersion: 1
+
diff --git a/roles/lib_openshift_api/build/test/files/dc.yml b/roles/lib_openshift_api/build/test/files/dc.yml
new file mode 100644
index 000000000..7992c90dd
--- /dev/null
+++ b/roles/lib_openshift_api/build/test/files/dc.yml
@@ -0,0 +1,121 @@
+apiVersion: v1
+kind: DeploymentConfig
+metadata:
+ creationTimestamp: 2016-03-18T19:47:45Z
+ labels:
+ router: router
+ name: router
+ namespace: default
+ resourceVersion: "84016"
+ selfLink: /oapi/v1/namespaces/default/deploymentconfigs/router
+ uid: 48f8b9d9-ed42-11e5-9903-0a9a9d4e7f2b
+spec:
+ replicas: 2
+ selector:
+ router: router
+ strategy:
+ resources: {}
+ rollingParams:
+ intervalSeconds: 1
+ maxSurge: 0
+ maxUnavailable: 25%
+ timeoutSeconds: 600
+ updatePercent: -25
+ updatePeriodSeconds: 1
+ type: Rolling
+ template:
+ metadata:
+ creationTimestamp: null
+ labels:
+ router: router
+ spec:
+ containers:
+ - env:
+ - name: DEFAULT_CERTIFICATE
+ - name: OPENSHIFT_CA_DATA
+ value: |
+ -----BEGIN CERTIFICATE-----
+ MIIC5jCCAdCgAwIBAgIBATALBgkqhkiG9w0BAQswJjEkMCIGA1UEAwwbb3BlbnNo
+ -----END CERTIFICATE-----
+ - name: OPENSHIFT_CERT_DATA
+ value: |
+ -----BEGIN CERTIFICATE-----
+ MIIDDTCCAfegAwIBAgIBCDALBgkqhkiG9w0BAQswJjEkMCIGA1UEAwwbb3BlbnNo
+ -----END CERTIFICATE-----
+ - name: OPENSHIFT_INSECURE
+ value: "false"
+ - name: OPENSHIFT_KEY_DATA
+ value: |
+ -----BEGIN RSA PRIVATE KEY-----
+ MIIEogIBAAKCAQEA2lf49DrPHfCdCORcnIbmDVrx8yos7trjWdBvuledijyslRVR
+ -----END RSA PRIVATE KEY-----
+ - name: OPENSHIFT_MASTER
+ value: https://internal.api.mwoodson.openshift.com
+ - name: ROUTER_EXTERNAL_HOST_HOSTNAME
+ - name: ROUTER_EXTERNAL_HOST_HTTPS_VSERVER
+ - name: ROUTER_EXTERNAL_HOST_HTTP_VSERVER
+ - name: ROUTER_EXTERNAL_HOST_INSECURE
+ value: "false"
+ - name: ROUTER_EXTERNAL_HOST_PARTITION_PATH
+ - name: ROUTER_EXTERNAL_HOST_PASSWORD
+ - name: ROUTER_EXTERNAL_HOST_PRIVKEY
+ value: /etc/secret-volume/router.pem
+ - name: ROUTER_EXTERNAL_HOST_USERNAME
+ - name: ROUTER_SERVICE_NAME
+ value: router
+ - name: ROUTER_SERVICE_NAMESPACE
+ value: default
+ - name: STATS_PASSWORD
+ value: ugCk6YBm4q
+ - name: STATS_PORT
+ value: "1936"
+ - name: STATS_USERNAME
+ value: admin
+ image: openshift3/ose-haproxy-router:v3.1.1.6
+ imagePullPolicy: IfNotPresent
+ livenessProbe:
+ httpGet:
+ host: localhost
+ path: /healthz
+ port: 1936
+ scheme: HTTP
+ initialDelaySeconds: 10
+ timeoutSeconds: 1
+ name: router
+ ports:
+ - containerPort: 80
+ hostPort: 80
+ protocol: TCP
+ - containerPort: 443
+ hostPort: 443
+ protocol: TCP
+ - containerPort: 1936
+ hostPort: 1936
+ name: stats
+ protocol: TCP
+ readinessProbe:
+ httpGet:
+ host: localhost
+ path: /healthz
+ port: 1936
+ scheme: HTTP
+ timeoutSeconds: 1
+ resources: {}
+ terminationMessagePath: /dev/termination-log
+ dnsPolicy: ClusterFirst
+ hostNetwork: true
+ nodeSelector:
+ type: infra
+ restartPolicy: Always
+ securityContext: {}
+ serviceAccount: router
+ serviceAccountName: router
+ terminationGracePeriodSeconds: 30
+ triggers:
+ - type: ConfigChange
+status:
+ details:
+ causes:
+ - type: ConfigChange
+ latestVersion: 1
+
diff --git a/roles/lib_openshift_api/build/test/files/passwords.yml b/roles/lib_openshift_api/build/test/files/passwords.yml
new file mode 100644
index 000000000..fadbf1d85
--- /dev/null
+++ b/roles/lib_openshift_api/build/test/files/passwords.yml
@@ -0,0 +1,4 @@
+test1
+test2
+test3
+test4
diff --git a/roles/lib_openshift_api/build/test/files/router-mod.json b/roles/lib_openshift_api/build/test/files/router-mod.json
new file mode 100644
index 000000000..45e2e7c8d
--- /dev/null
+++ b/roles/lib_openshift_api/build/test/files/router-mod.json
@@ -0,0 +1,30 @@
+{
+ "kind": "Service",
+ "apiVersion": "v1",
+ "metadata": {
+ "name": "router",
+ "namespace": "default",
+ "labels": {
+ "router": "router"
+ }
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "81-tcp",
+ "protocol": "TCP",
+ "port": 81,
+ "targetPort": 81
+ }
+ ],
+ "selector": {
+ "router": "router"
+ },
+ "type": "ClusterIP",
+ "sessionAffinity": "None"
+ },
+ "status": {
+ "loadBalancer": {}
+ }
+}
+
diff --git a/roles/lib_openshift_api/build/test/files/router.json b/roles/lib_openshift_api/build/test/files/router.json
new file mode 100644
index 000000000..cad3c6f53
--- /dev/null
+++ b/roles/lib_openshift_api/build/test/files/router.json
@@ -0,0 +1,29 @@
+{
+ "apiVersion": "v1",
+ "kind": "Service",
+ "metadata": {
+ "labels": {
+ "router": "router"
+ },
+ "name": "router",
+ "namespace": "default"
+ },
+ "spec": {
+ "ports": [
+ {
+ "name": "80-tcp",
+ "port": 80,
+ "protocol": "TCP",
+ "targetPort": 80
+ }
+ ],
+ "selector": {
+ "router": "router"
+ },
+ "sessionAffinity": "None",
+ "type": "ClusterIP"
+ },
+ "status": {
+ "loadBalancer": {}
+ }
+}
diff --git a/roles/lib_openshift_api/build/test/roles b/roles/lib_openshift_api/build/test/roles
new file mode 120000
index 000000000..ae82aa9bb
--- /dev/null
+++ b/roles/lib_openshift_api/build/test/roles
@@ -0,0 +1 @@
+../../../../roles/ \ No newline at end of file
diff --git a/roles/lib_openshift_api/build/test/secrets.yml b/roles/lib_openshift_api/build/test/secrets.yml
new file mode 100755
index 000000000..dddc05c4d
--- /dev/null
+++ b/roles/lib_openshift_api/build/test/secrets.yml
@@ -0,0 +1,81 @@
+#!/usr/bin/ansible-playbook
+---
+- hosts: "oo_clusterid_mwoodson:&oo_version_3:&oo_master_primary"
+ gather_facts: no
+ user: root
+
+ post_tasks:
+ - copy:
+ dest: "/tmp/{{ item }}"
+ src: "files/{{ item }}"
+ with_items:
+ - config.yml
+ - passwords.yml
+
+ - name: list secrets
+ oc_secret:
+ state: list
+ namespace: default
+ name: kenny
+ register: secret_out
+
+ - debug:
+ var: secret_out
+
+ - name: absent secrets
+ oc_secret:
+ state: absent
+ namespace: default
+ name: kenny
+ register: secret_out
+
+ - debug:
+ var: secret_out
+
+ - name: present secrets
+ oc_secret:
+ state: present
+ namespace: default
+ name: kenny
+ files:
+ - /tmp/config.yml
+ - /tmp/passwords.yml
+ delete_after: True
+ register: secret_out
+
+ - debug:
+ var: secret_out
+
+ - name: present secrets
+ oc_secret:
+ state: present
+ namespace: default
+ name: kenny
+ contents:
+ - path: config.yml
+ content: "value: True\n"
+ - path: passwords.yml
+ content: "test1\ntest2\ntest3\ntest4\n"
+ delete_after: True
+ register: secret_out
+
+ - debug:
+ var: secret_out
+
+ - name: present secrets update
+ oc_secret:
+ state: present
+ namespace: default
+ name: kenny
+ contents:
+ - path: config.yml
+ content: "value: True\n"
+ - path: passwords.yml
+ content: "test1\ntest2\ntest3\ntest4\ntest5\n"
+ delete_after: True
+ force: True
+ register: secret_out
+
+ - debug:
+ var: secret_out
+
diff --git a/roles/lib_openshift_api/build/test/services.yml b/roles/lib_openshift_api/build/test/services.yml
new file mode 100755
index 000000000..a32e8d012
--- /dev/null
+++ b/roles/lib_openshift_api/build/test/services.yml
@@ -0,0 +1,133 @@
+#!/usr/bin/ansible-playbook
+---
+- hosts: "oo_clusterid_mwoodson:&oo_master_primary"
+ gather_facts: no
+ user: root
+
+ roles:
+ - roles/lib_yaml_editor
+
+ tasks:
+ - copy:
+ dest: "/tmp/{{ item }}"
+ src: "files/{{ item }}"
+ with_items:
+ - router.json
+ - router-mod.json
+
+ - name: list services
+ oc_obj:
+ kind: service
+ state: list
+ namespace: default
+ name: router
+ register: service_out
+
+ - debug:
+ var: service_out.results
+
+ - name: absent service
+ oc_obj:
+ kind: service
+ state: absent
+ namespace: default
+ name: router
+ register: service_out
+
+ - debug:
+ var: service_out
+
+ - name: present service create
+ oc_obj:
+ kind: service
+ state: present
+ namespace: default
+ name: router
+ files:
+ - /tmp/router.json
+ delete_after: True
+ register: service_out
+
+ - debug:
+ var: service_out
+
+ - name: dump router
+ oc_obj:
+ kind: service
+ state: list
+ name: router
+ namespace: default
+ register: routerout
+
+ - name: write router file
+ copy:
+ dest: /tmp/router-mod.json
+ content: "{{ routerout.results[0] }}"
+
+ - command: cat /tmp/router-mod.json
+ register: catout
+
+ - debug:
+ msg: "{{ catout }}"
+
+ - command: "sed -i 's/80-tcp/81-tcp/g' /tmp/router-mod.json"
+ register: catout
+
+ - name: present service replace
+ oc_obj:
+ kind: service
+ state: present
+ namespace: default
+ name: router
+ files:
+ - /tmp/router-mod.json
+ #delete_after: True
+ register: service_out
+
+ - debug:
+ var: service_out
+
+ - name: list services
+ oc_obj:
+ kind: service
+ state: list
+ namespace: default
+ name: router
+ register: service_out
+
+ - debug:
+ var: service_out.results
+
+ - set_fact:
+ new_service: "{{ service_out.results[0] }}"
+
+ - yedit:
+ src: /tmp/routeryedit
+ content: "{{ new_service }}"
+ key: spec.ports
+ value:
+ - name: 80-tcp
+ port: 80
+ protocol: TCP
+ targetPort: 80
+
+ - yedit:
+ src: /tmp/routeryedit
+ state: list
+ register: yeditout
+
+ - debug:
+ var: yeditout
+
+ - name: present service replace
+ oc_obj:
+ kind: service
+ state: present
+ namespace: default
+ name: router
+ content: "{{ yeditout.results }}"
+ delete_after: True
+ register: service_out
+
+ - debug:
+ var: service_out