summaryrefslogtreecommitdiffstats
path: root/roles/lib_openshift_api
diff options
context:
space:
mode:
authorJoel Diaz <jdiaz@redhat.com>2016-04-08 13:48:13 -0400
committerJoel Diaz <jdiaz@redhat.com>2016-04-15 09:35:54 -0400
commit3681ab5fb2a39ccb06024e6ad514ad50df21f9d2 (patch)
tree5d1dd7da5404f431a60241a419155204a7784dcc /roles/lib_openshift_api
parent51e390459d7eda90c44d9ffd7f1199a3590beac1 (diff)
downloadopenshift-3681ab5fb2a39ccb06024e6ad514ad50df21f9d2.tar.gz
openshift-3681ab5fb2a39ccb06024e6ad514ad50df21f9d2.tar.bz2
openshift-3681ab5fb2a39ccb06024e6ad514ad50df21f9d2.tar.xz
openshift-3681ab5fb2a39ccb06024e6ad514ad50df21f9d2.zip
cleanup roles after roles move to openshift-tools
also removing inventory/multi_inventory* things left behind unchanged even though they were copied: playbooks/adhoc/* roles/dns roles/kube_nfs_volumes roles/os_update_latest
Diffstat (limited to 'roles/lib_openshift_api')
-rw-r--r--roles/lib_openshift_api/build/ansible/edit.py84
-rw-r--r--roles/lib_openshift_api/build/ansible/obj.py139
-rw-r--r--roles/lib_openshift_api/build/ansible/router.py142
-rw-r--r--roles/lib_openshift_api/build/ansible/secret.py121
-rwxr-xr-xroles/lib_openshift_api/build/generate.py64
-rw-r--r--roles/lib_openshift_api/build/src/base.py300
-rw-r--r--roles/lib_openshift_api/build/src/edit.py49
-rw-r--r--roles/lib_openshift_api/build/src/obj.py78
-rw-r--r--roles/lib_openshift_api/build/src/router.py152
-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
-rwxr-xr-xroles/lib_openshift_api/build/test/edit.yml53
-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.yml120
-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/router.yml79
-rwxr-xr-xroles/lib_openshift_api/build/test/secrets.yml81
-rwxr-xr-xroles/lib_openshift_api/build/test/services.yml133
-rw-r--r--roles/lib_openshift_api/library/oadm_router.py807
-rw-r--r--roles/lib_openshift_api/library/oc_edit.py646
-rw-r--r--roles/lib_openshift_api/library/oc_obj.py730
-rw-r--r--roles/lib_openshift_api/library/oc_secret.py702
27 files changed, 0 insertions, 4862 deletions
diff --git a/roles/lib_openshift_api/build/ansible/edit.py b/roles/lib_openshift_api/build/ansible/edit.py
deleted file mode 100644
index 943fa47a6..000000000
--- a/roles/lib_openshift_api/build/ansible/edit.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# pylint: skip-file
-
-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']),
- debug=dict(default=False, type='bool'),
- namespace=dict(default='default', type='str'),
- name=dict(default=None, required=True, type='str'),
- kind=dict(required=True,
- type='str',
- choices=['dc', 'deploymentconfig',
- 'svc', 'service',
- 'scc', 'securitycontextconstraints',
- 'ns', 'namespace', 'project', 'projects',
- 'is', 'imagestream',
- 'istag', 'imagestreamtag',
- 'bc', 'buildconfig',
- 'routes',
- 'node',
- 'secret',
- ]),
- file_name=dict(default=None, type='str'),
- file_format=dict(default='yaml', type='str'),
- content=dict(default=None, required=True, type='dict'),
- force=dict(default=False, type='bool'),
- ),
- supports_check_mode=True,
- )
- ocedit = Edit(module.params['kind'],
- module.params['namespace'],
- module.params['name'],
- kubeconfig=module.params['kubeconfig'],
- verbose=module.params['debug'])
-
- state = module.params['state']
-
- api_rval = ocedit.get()
-
- ########
- # Create
- ########
- if not Utils.exists(api_rval['results'], module.params['name']):
- module.fail_json(msg=api_rval)
-
- ########
- # Update
- ########
- api_rval = ocedit.update(module.params['file_name'],
- module.params['content'],
- module.params['force'],
- module.params['file_format'])
-
-
- if api_rval['returncode'] != 0:
- module.fail_json(msg=api_rval)
-
- if api_rval.has_key('updated') and not api_rval['updated']:
- module.exit_json(changed=False, results=api_rval, state="present")
-
- # return the created object
- api_rval = ocedit.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/obj.py b/roles/lib_openshift_api/build/ansible/obj.py
deleted file mode 100644
index a14ac0e43..000000000
--- a/roles/lib_openshift_api/build/ansible/obj.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# 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',
- 'scc', 'securitycontextconstraints',
- 'ns', 'namespace', 'project', 'projects',
- 'is', 'imagestream',
- 'istag', 'imagestreamtag',
- 'bc', 'buildconfig',
- 'routes',
- 'node',
- '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/router.py b/roles/lib_openshift_api/build/ansible/router.py
deleted file mode 100644
index 3b24c7b5e..000000000
--- a/roles/lib_openshift_api/build/ansible/router.py
+++ /dev/null
@@ -1,142 +0,0 @@
-# pylint: skip-file
-
-def main():
- '''
- ansible oc module for secrets
- '''
-
- module = AnsibleModule(
- argument_spec=dict(
- state=dict(default='present', type='str',
- choices=['present', 'absent']),
- debug=dict(default=False, type='bool'),
- namespace=dict(default='default', type='str'),
- name=dict(default='router', type='str'),
-
- kubeconfig=dict(default='/etc/origin/master/admin.kubeconfig', type='str'),
- credentials=dict(default='/etc/origin/master/openshift-router.kubeconfig', type='str'),
- cert_file=dict(default=None, type='str'),
- key_file=dict(default=None, type='str'),
- image=dict(default=None, type='str'), #'openshift3/ose-${component}:${version}'
- latest_image=dict(default=False, type='bool'),
- labels=dict(default=None, type='list'),
- ports=dict(default=['80:80', '443:443'], type='list'),
- replicas=dict(default=1, type='int'),
- selector=dict(default=None, type='str'),
- service_account=dict(default='router', type='str'),
- router_type=dict(default='haproxy-router', type='str'),
- host_network=dict(default=True, type='bool'),
- # external host options
- external_host=dict(default=None, type='str'),
- external_host_vserver=dict(default=None, type='str'),
- external_host_insecure=dict(default=False, type='bool'),
- external_host_partition_path=dict(default=None, type='str'),
- external_host_username=dict(default=None, type='str'),
- external_host_password=dict(default=None, type='str'),
- external_host_private_key=dict(default=None, type='str'),
- # Metrics
- expose_metrics=dict(default=False, type='bool'),
- metrics_image=dict(default=None, type='str'),
- # Stats
- stats_user=dict(default=None, type='str'),
- stats_password=dict(default=None, type='str'),
- stats_port=dict(default=1936, type='int'),
-
- ),
- mutually_exclusive=[["router_type", "images"]],
-
- supports_check_mode=True,
- )
-
- rconfig = RouterConfig(module.params['name'],
- module.params['kubeconfig'],
- {'credentials': {'value': module.params['credentials'], 'include': True},
- 'default_cert': {'value': None, 'include': True},
- 'cert_file': {'value': module.params['cert_file'], 'include': False},
- 'key_file': {'value': module.params['key_file'], 'include': False},
- 'image': {'value': module.params['image'], 'include': True},
- 'latest_image': {'value': module.params['latest_image'], 'include': True},
- 'labels': {'value': module.params['labels'], 'include': True},
- 'ports': {'value': ','.join(module.params['ports']), 'include': True},
- 'replicas': {'value': module.params['replicas'], 'include': True},
- 'selector': {'value': module.params['selector'], 'include': True},
- 'service_account': {'value': module.params['service_account'], 'include': True},
- 'router_type': {'value': module.params['router_type'], 'include': False},
- 'host_network': {'value': module.params['host_network'], 'include': True},
- 'external_host': {'value': module.params['external_host'], 'include': True},
- 'external_host_vserver': {'value': module.params['external_host_vserver'],
- 'include': True},
- 'external_host_insecure': {'value': module.params['external_host_insecure'],
- 'include': True},
- 'external_host_partition_path': {'value': module.params['external_host_partition_path'],
- 'include': True},
- 'external_host_username': {'value': module.params['external_host_username'],
- 'include': True},
- 'external_host_password': {'value': module.params['external_host_password'],
- 'include': True},
- 'external_host_private_key': {'value': module.params['external_host_private_key'],
- 'include': True},
- 'expose_metrics': {'value': module.params['expose_metrics'], 'include': True},
- 'metrics_image': {'value': module.params['metrics_image'], 'include': True},
- 'stats_user': {'value': module.params['stats_user'], 'include': True},
- 'stats_password': {'value': module.params['stats_password'], 'include': True},
- 'stats_port': {'value': module.params['stats_port'], 'include': True},
- })
-
-
- ocrouter = Router(rconfig)
-
- state = module.params['state']
-
- ########
- # Delete
- ########
- if state == 'absent':
- if not ocrouter.exists():
- module.exit_json(changed=False, state="absent")
-
- if module.check_mode:
- module.exit_json(change=False, msg='Would have performed a delete.')
-
- api_rval = ocrouter.delete()
- module.exit_json(changed=True, results=api_rval, state="absent")
-
-
- if state == 'present':
- ########
- # Create
- ########
- if not ocrouter.exists():
-
- if module.check_mode:
- module.exit_json(change=False, msg='Would have performed a create.')
-
- api_rval = ocrouter.create()
-
- module.exit_json(changed=True, results=api_rval, state="present")
-
- ########
- # Update
- ########
- if not ocrouter.needs_update():
- module.exit_json(changed=False, state="present")
-
- if module.check_mode:
- module.exit_json(change=False, msg='Would have performed an update.')
-
- api_rval = ocrouter.update()
-
- 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
deleted file mode 100644
index 8df7bbc64..000000000
--- a/roles/lib_openshift_api/build/ansible/secret.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# 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
deleted file mode 100755
index 9fc1986f1..000000000
--- a/roles/lib_openshift_api/build/generate.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/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"
-
-OPENSHIFT_ANSIBLE_PATH = os.path.dirname(os.path.realpath(__file__))
-
-
-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',
- ],
- 'oc_edit.py': ['src/base.py',
- '../../lib_yaml_editor/build/src/yedit.py',
- 'src/edit.py',
- 'ansible/edit.py',
- ],
- 'oadm_router.py': ['src/base.py',
- '../../lib_yaml_editor/build/src/yedit.py',
- 'src/router.py',
- 'ansible/router.py',
- ],
- }
-
-
-def main():
- ''' combine the necessary files to create the ansible module '''
- library = os.path.join(OPENSHIFT_ANSIBLE_PATH, '..', 'library/')
- for fname, parts in FILES.items():
- with open(os.path.join(library, fname), 'w') as afd:
- afd.seek(0)
- afd.write(GEN_STR)
- for fpart in parts:
- with open(os.path.join(OPENSHIFT_ANSIBLE_PATH, 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
deleted file mode 100644
index 257379d92..000000000
--- a/roles/lib_openshift_api/build/src/base.py
+++ /dev/null
@@ -1,300 +0,0 @@
-# pylint: skip-file
-'''
- OpenShiftCLI class that wraps the oc commands in a subprocess
-'''
-
-import atexit
-import json
-import os
-import shutil
-import subprocess
-import re
-
-import yaml
-# This is here because of a bug that causes yaml
-# to incorrectly handle timezone info on timestamps
-def timestamp_constructor(_, node):
- '''return timestamps as strings'''
- return str(node.value)
-yaml.add_constructor(u'tag:yaml.org,2002:timestamp', timestamp_constructor)
-
-# pylint: disable=too-few-public-methods
-class OpenShiftCLI(object):
- ''' Class to wrap the command line tools '''
- def __init__(self,
- namespace,
- kubeconfig='/etc/origin/master/admin.kubeconfig',
- verbose=False):
- ''' Constructor for OpenshiftCLI '''
- 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])
- changes = []
- for key, value in content.items():
- changes.append(yed.put(key, value))
-
- if any([not change[0] for change in changes]):
- return {'returncode': 0, 'updated': False}
-
- yed.write()
-
- 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.openshift_cmd(cmd)
-
- def _create(self, fname):
- '''return all pods '''
- return self.openshift_cmd(['create', '-f', fname, '-n', self.namespace])
-
- def _delete(self, resource, rname):
- '''return all pods '''
- return self.openshift_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.openshift_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 openshift_cmd(self, cmd, oadm=False, output=False, output_type='json'):
- '''Base command for oc '''
- #cmds = ['/usr/bin/oc', '--config', self.kubeconfig]
- cmds = []
- if oadm:
- cmds = ['/usr/bin/oadm']
- else:
- cmds = ['/usr/bin/oc']
-
- cmds.extend(cmd)
-
- rval = {}
- results = ''
- err = None
-
- if self.verbose:
- print ' '.join(cmds)
-
- proc = subprocess.Popen(cmds,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- env={'KUBECONFIG': self.kubeconfig})
-
- proc.wait()
- stdout = proc.stdout.read()
- stderr = proc.stderr.read()
- rval = {"returncode": proc.returncode,
- "results": results,
- "cmd": ' '.join(cmds),
- }
-
- if proc.returncode == 0:
- if output:
- if output_type == 'json':
- try:
- rval['results'] = json.loads(stdout)
- except ValueError as err:
- if "No JSON object could be decoded" in err.message:
- err = err.message
- elif output_type == 'raw':
- rval['results'] = stdout
-
- if self.verbose:
- print stdout
- print stderr
- print
-
- if err:
- rval.update({"err": err,
- "stderr": stderr,
- "stdout": stdout,
- "cmd": cmds
- })
-
- else:
- rval.update({"stderr": stderr,
- "stdout": stdout,
- "results": {},
- })
-
- return rval
-
-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.safe_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, skip_keys=None, 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']
- if skip_keys:
- skip.extend(skip_keys)
-
- 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):
- if debug:
- print 'user_def[key] is not a list'
- return False
-
- for values in zip(user_def[key], value):
- if isinstance(values[0], dict) and isinstance(values[1], dict):
- if debug:
- print 'sending list - list'
- print type(values[0])
- print type(values[1])
- result = Utils.check_def_equal(values[0], values[1], skip_keys=skip_keys, debug=debug)
- if not result:
- print 'list compare returned false'
- return False
-
- elif value != user_def[key]:
- if debug:
- print 'value should be identical'
- print value
- print 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, skip_keys=skip_keys, debug=debug)
- if not result:
- if debug:
- print "dict returned false"
- print result
- 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/edit.py b/roles/lib_openshift_api/build/src/edit.py
deleted file mode 100644
index 7020ace47..000000000
--- a/roles/lib_openshift_api/build/src/edit.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# pylint: skip-file
-
-class Edit(OpenShiftCLI):
- ''' Class to wrap the oc command line tools
- '''
- # pylint: disable=too-many-arguments
- def __init__(self,
- kind,
- namespace,
- resource_name=None,
- kubeconfig='/etc/origin/master/admin.kubeconfig',
- verbose=False):
- ''' Constructor for OpenshiftOC '''
- super(Edit, self).__init__(namespace, kubeconfig)
- self.namespace = namespace
- self.kind = kind
- self.name = resource_name
- self.kubeconfig = kubeconfig
- self.verbose = verbose
-
- def get(self):
- '''return a secret by name '''
- return self._get(self.kind, self.name)
-
- def update(self, file_name, content, force=False, content_type='yaml'):
- '''run update '''
- if file_name:
- if content_type == 'yaml':
- data = yaml.load(open(file_name))
- elif content_type == 'json':
- data = json.loads(open(file_name).read())
-
- changes = []
- yed = Yedit(file_name, data)
- for key, value in content.items():
- changes.append(yed.put(key, value))
-
- if any([not change[0] for change in changes]):
- return {'returncode': 0, 'updated': False}
-
- yed.write()
-
- atexit.register(Utils.cleanup, [file_name])
-
- return self._replace(file_name, force=force)
-
- return self._replace_content(self.kind, self.name, content, force=force)
-
-
diff --git a/roles/lib_openshift_api/build/src/obj.py b/roles/lib_openshift_api/build/src/obj.py
deleted file mode 100644
index 13aeba8e1..000000000
--- a/roles/lib_openshift_api/build/src/obj.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# 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], skip_keys=None, debug=False)
- 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/router.py b/roles/lib_openshift_api/build/src/router.py
deleted file mode 100644
index 69454d594..000000000
--- a/roles/lib_openshift_api/build/src/router.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# pylint: skip-file
-
-import time
-
-class RouterConfig(object):
- ''' RouterConfig is a DTO for the router. '''
- def __init__(self, rname, kubeconfig, router_options):
- self.name = rname
- self.kubeconfig = kubeconfig
- self._router_options = router_options
-
- @property
- def router_options(self):
- ''' return router options '''
- return self._router_options
-
- def to_option_list(self):
- ''' return all options as a string'''
- return RouterConfig.stringify(self.router_options)
-
- @staticmethod
- def stringify(options):
- ''' return hash as list of key value pairs '''
- rval = []
- for key, data in options.items():
- if data['include'] and data['value']:
- rval.append('--%s=%s' % (key.replace('_', '-'), data['value']))
-
- return rval
-
-class Router(OpenShiftCLI):
- ''' Class to wrap the oc command line tools '''
- def __init__(self,
- router_config,
- verbose=False):
- ''' Constructor for OpenshiftOC
-
- a router consists of 3 or more parts
- - dc/router
- - svc/router
- - endpoint/router
- '''
- super(Router, self).__init__('default', router_config.kubeconfig, verbose)
- self.rconfig = router_config
- self.verbose = verbose
- self.router_parts = [{'kind': 'dc', 'name': self.rconfig.name},
- {'kind': 'svc', 'name': self.rconfig.name},
- #{'kind': 'endpoints', 'name': self.rconfig.name},
- ]
- def get(self, filter_kind=None):
- ''' return the self.router_parts '''
- rparts = self.router_parts
- parts = []
- if filter_kind:
- rparts = [part for part in self.router_parts if filter_kind == part['kind']]
-
- for part in rparts:
- parts.append(self._get(part['kind'], rname=part['name']))
-
- return parts
-
- def exists(self):
- '''return a deploymentconfig by name '''
- parts = self.get()
- for part in parts:
- if part['returncode'] != 0:
- return False
-
- return True
-
- def delete(self):
- '''return all pods '''
- parts = []
- for part in self.router_parts:
- parts.append(self._delete(part['kind'], part['name']))
-
- return parts
-
- def create(self, dryrun=False, output=False, output_type='json'):
- '''Create a deploymentconfig '''
- # We need to create the pem file
- router_pem = '/tmp/router.pem'
- with open(router_pem, 'w') as rfd:
- rfd.write(open(self.rconfig.router_options['cert_file']['value']).read())
- rfd.write(open(self.rconfig.router_options['key_file']['value']).read())
-
- atexit.register(Utils.cleanup, [router_pem])
- self.rconfig.router_options['default_cert']['value'] = router_pem
-
- options = self.rconfig.to_option_list()
-
- cmd = ['router']
- cmd.extend(options)
- if dryrun:
- cmd.extend(['--dry-run=True', '-o', 'json'])
-
- results = self.openshift_cmd(cmd, oadm=True, output=output, output_type=output_type)
-
- return results
-
- def update(self):
- '''run update for the router. This performs a delete and then create '''
- parts = self.delete()
- if any([part['returncode'] != 0 for part in parts]):
- return parts
-
- # Ugly built in sleep here.
- time.sleep(15)
-
- return self.create()
-
- def needs_update(self, verbose=False):
- ''' check to see if we need to update '''
- dc_inmem = self.get(filter_kind='dc')[0]
- if dc_inmem['returncode'] != 0:
- return dc_inmem
-
- user_dc = self.create(dryrun=True, output=True, output_type='raw')
- if user_dc['returncode'] != 0:
- return user_dc
-
- # Since the output from oadm_router is returned as raw
- # we need to parse it. The first line is the stats_password
- user_dc_results = user_dc['results'].split('\n')
- # stats_password = user_dc_results[0]
-
- # Load the string back into json and get the newly created dc
- user_dc = json.loads('\n'.join(user_dc_results[1:]))['items'][0]
-
- # Router needs some exceptions.
- # We do not want to check the autogenerated password for stats admin
- if not self.rconfig.router_options['stats_password']['value']:
- for idx, env_var in enumerate(user_dc['spec']['template']['spec']['containers'][0]['env']):
- if env_var['name'] == 'STATS_PASSWORD':
- env_var['value'] = \
- dc_inmem['results'][0]['spec']['template']['spec']['containers'][0]['env'][idx]['value']
-
- # dry-run doesn't add the protocol to the ports section. We will manually do that.
- for idx, port in enumerate(user_dc['spec']['template']['spec']['containers'][0]['ports']):
- if not port.has_key('protocol'):
- port['protocol'] = 'TCP'
-
- # These are different when generating
- skip = ['dnsPolicy',
- 'terminationGracePeriodSeconds',
- 'restartPolicy', 'timeoutSeconds',
- 'livenessProbe', 'readinessProbe',
- 'terminationMessagePath',
- 'rollingParams',
- ]
-
- return not Utils.check_def_equal(user_dc, dc_inmem['results'][0], skip_keys=skip, debug=verbose)
diff --git a/roles/lib_openshift_api/build/src/secret.py b/roles/lib_openshift_api/build/src/secret.py
deleted file mode 100644
index 154716828..000000000
--- a/roles/lib_openshift_api/build/src/secret.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# 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.openshift_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.openshift_cmd(cmd, output=True)
-
-
diff --git a/roles/lib_openshift_api/build/test/README b/roles/lib_openshift_api/build/test/README
deleted file mode 100644
index af9f05b3d..000000000
--- a/roles/lib_openshift_api/build/test/README
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100755
index d041ab22a..000000000
--- a/roles/lib_openshift_api/build/test/deploymentconfig.yml
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/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/edit.yml b/roles/lib_openshift_api/build/test/edit.yml
deleted file mode 100755
index 9aa01303a..000000000
--- a/roles/lib_openshift_api/build/test/edit.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/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: present dc
- oc_edit:
- kind: dc
- namespace: default
- name: router
- content:
- spec.template.spec.containers[0].ports[0].containerPort: 80
- spec.template.spec.containers[0].ports[0].hostPort: 80
- register: dcout
-
- - debug:
- var: dcout
-
- - name: present dc
- oc_edit:
- kind: dc
- namespace: default
- name: router
- content:
- spec.template.spec.containers[0].ports[0].containerPort: 81
- spec.template.spec.containers[0].ports[0].hostPort: 81
- file_format: yaml
- register: dcout
-
- - debug:
- var: dcout
-
- - name: present dc
- oc_edit:
- kind: dc
- namespace: default
- name: router
- content:
- spec.template.spec.containers[0].ports[0].containerPort: 80
- spec.template.spec.containers[0].ports[0].hostPort: 80
- file_format: yaml
- 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
deleted file mode 100644
index c544c6fd4..000000000
--- a/roles/lib_openshift_api/build/test/files/config.yml
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 6c700d6c7..000000000
--- a/roles/lib_openshift_api/build/test/files/dc-mod.yml
+++ /dev/null
@@ -1,124 +0,0 @@
-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
deleted file mode 100644
index 24f690ef4..000000000
--- a/roles/lib_openshift_api/build/test/files/dc.yml
+++ /dev/null
@@ -1,120 +0,0 @@
-apiVersion: v1
-kind: DeploymentConfig
-metadata:
- creationTimestamp: 2016-04-01T15:23:29Z
- labels:
- router: router
- name: router
- namespace: default
- resourceVersion: "1338477"
- selfLink: /oapi/v1/namespaces/default/deploymentconfigs/router
- uid: b00c7eba-f81d-11e5-809b-0a581f893e3f
-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: 12
diff --git a/roles/lib_openshift_api/build/test/files/passwords.yml b/roles/lib_openshift_api/build/test/files/passwords.yml
deleted file mode 100644
index fadbf1d85..000000000
--- a/roles/lib_openshift_api/build/test/files/passwords.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-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
deleted file mode 100644
index 45e2e7c8d..000000000
--- a/roles/lib_openshift_api/build/test/files/router-mod.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "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
deleted file mode 100644
index cad3c6f53..000000000
--- a/roles/lib_openshift_api/build/test/files/router.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "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
deleted file mode 120000
index ae82aa9bb..000000000
--- a/roles/lib_openshift_api/build/test/roles
+++ /dev/null
@@ -1 +0,0 @@
-../../../../roles/ \ No newline at end of file
diff --git a/roles/lib_openshift_api/build/test/router.yml b/roles/lib_openshift_api/build/test/router.yml
deleted file mode 100755
index 7ab192b97..000000000
--- a/roles/lib_openshift_api/build/test/router.yml
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/ansible-playbook
----
-- hosts: "oo_clusterid_mwoodson:&oo_master_primary"
- gather_facts: no
- user: root
-
- tasks:
- - oadm_router:
- state: absent
- credentials: /etc/origin/master/openshift-router.kubeconfig
- service_account: router
- replicas: 2
- namespace: default
- selector: type=infra
- cert_file: /etc/origin/master/named_certificates/12ab.mwoodson.openshiftapps.com.crt
- key_file: /etc/origin/master/named_certificates/12ab.mwoodson.openshiftapps.com.key
- register: routerout
-
- - debug: var=routerout
-
- - pause:
- seconds: 10
-
- - oadm_router:
- credentials: /etc/origin/master/openshift-router.kubeconfig
- service_account: router
- replicas: 2
- namespace: default
- selector: type=infra
- cert_file: /etc/origin/master/named_certificates/12ab.mwoodson.openshiftapps.com.crt
- key_file: /etc/origin/master/named_certificates/12ab.mwoodson.openshiftapps.com.key
- register: routerout
-
- - debug: var=routerout
-
- - pause:
- seconds: 10
-
- - oadm_router:
- credentials: /etc/origin/master/openshift-router.kubeconfig
- service_account: router
- replicas: 2
- namespace: default
- selector: type=infra
- cert_file: /etc/origin/master/named_certificates/12ab.mwoodson.openshiftapps.com.crt
- key_file: /etc/origin/master/named_certificates/12ab.mwoodson.openshiftapps.com.key
- register: routerout
-
- - debug: var=routerout
-
- - pause:
- seconds: 10
-
- - oadm_router:
- credentials: /etc/origin/master/openshift-router.kubeconfig
- service_account: router
- replicas: 3
- namespace: default
- selector: type=test
- cert_file: /etc/origin/master/named_certificates/12ab.mwoodson.openshiftapps.com.crt
- key_file: /etc/origin/master/named_certificates/12ab.mwoodson.openshiftapps.com.key
- register: routerout
-
- - debug: var=routerout
-
- - pause:
- seconds: 10
-
- - oadm_router:
- credentials: /etc/origin/master/openshift-router.kubeconfig
- service_account: router
- replicas: 2
- namespace: default
- selector: type=infra
- cert_file: /etc/origin/master/named_certificates/12ab.mwoodson.openshiftapps.com.crt
- key_file: /etc/origin/master/named_certificates/12ab.mwoodson.openshiftapps.com.key
- register: routerout
-
- - debug: var=routerout
diff --git a/roles/lib_openshift_api/build/test/secrets.yml b/roles/lib_openshift_api/build/test/secrets.yml
deleted file mode 100755
index dddc05c4d..000000000
--- a/roles/lib_openshift_api/build/test/secrets.yml
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/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
deleted file mode 100755
index a32e8d012..000000000
--- a/roles/lib_openshift_api/build/test/services.yml
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/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
diff --git a/roles/lib_openshift_api/library/oadm_router.py b/roles/lib_openshift_api/library/oadm_router.py
deleted file mode 100644
index c6b45c14e..000000000
--- a/roles/lib_openshift_api/library/oadm_router.py
+++ /dev/null
@@ -1,807 +0,0 @@
-#!/usr/bin/env python
-# ___ ___ _ _ ___ ___ _ _____ ___ ___
-# / __| __| \| | __| _ \ /_\_ _| __| \
-# | (_ | _|| .` | _|| / / _ \| | | _|| |) |
-# \___|___|_|\_|___|_|_\/_/_\_\_|_|___|___/_ _____
-# | \ / _ \ | \| |/ _ \_ _| | __| \_ _|_ _|
-# | |) | (_) | | .` | (_) || | | _|| |) | | | |
-# |___/ \___/ |_|\_|\___/ |_| |___|___/___| |_|
-'''
- OpenShiftCLI class that wraps the oc commands in a subprocess
-'''
-
-import atexit
-import json
-import os
-import shutil
-import subprocess
-import re
-
-import yaml
-# This is here because of a bug that causes yaml
-# to incorrectly handle timezone info on timestamps
-def timestamp_constructor(_, node):
- '''return timestamps as strings'''
- return str(node.value)
-yaml.add_constructor(u'tag:yaml.org,2002:timestamp', timestamp_constructor)
-
-# pylint: disable=too-few-public-methods
-class OpenShiftCLI(object):
- ''' Class to wrap the command line tools '''
- def __init__(self,
- namespace,
- kubeconfig='/etc/origin/master/admin.kubeconfig',
- verbose=False):
- ''' Constructor for OpenshiftCLI '''
- 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])
- changes = []
- for key, value in content.items():
- changes.append(yed.put(key, value))
-
- if any([not change[0] for change in changes]):
- return {'returncode': 0, 'updated': False}
-
- yed.write()
-
- 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.openshift_cmd(cmd)
-
- def _create(self, fname):
- '''return all pods '''
- return self.openshift_cmd(['create', '-f', fname, '-n', self.namespace])
-
- def _delete(self, resource, rname):
- '''return all pods '''
- return self.openshift_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.openshift_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 openshift_cmd(self, cmd, oadm=False, output=False, output_type='json'):
- '''Base command for oc '''
- #cmds = ['/usr/bin/oc', '--config', self.kubeconfig]
- cmds = []
- if oadm:
- cmds = ['/usr/bin/oadm']
- else:
- cmds = ['/usr/bin/oc']
-
- cmds.extend(cmd)
-
- rval = {}
- results = ''
- err = None
-
- if self.verbose:
- print ' '.join(cmds)
-
- proc = subprocess.Popen(cmds,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- env={'KUBECONFIG': self.kubeconfig})
-
- proc.wait()
- stdout = proc.stdout.read()
- stderr = proc.stderr.read()
- rval = {"returncode": proc.returncode,
- "results": results,
- "cmd": ' '.join(cmds),
- }
-
- if proc.returncode == 0:
- if output:
- if output_type == 'json':
- try:
- rval['results'] = json.loads(stdout)
- except ValueError as err:
- if "No JSON object could be decoded" in err.message:
- err = err.message
- elif output_type == 'raw':
- rval['results'] = stdout
-
- if self.verbose:
- print stdout
- print stderr
- print
-
- if err:
- rval.update({"err": err,
- "stderr": stderr,
- "stdout": stdout,
- "cmd": cmds
- })
-
- else:
- rval.update({"stderr": stderr,
- "stdout": stdout,
- "results": {},
- })
-
- return rval
-
-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.safe_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, skip_keys=None, 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']
- if skip_keys:
- skip.extend(skip_keys)
-
- 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):
- if debug:
- print 'user_def[key] is not a list'
- return False
-
- for values in zip(user_def[key], value):
- if isinstance(values[0], dict) and isinstance(values[1], dict):
- if debug:
- print 'sending list - list'
- print type(values[0])
- print type(values[1])
- result = Utils.check_def_equal(values[0], values[1], skip_keys=skip_keys, debug=debug)
- if not result:
- print 'list compare returned false'
- return False
-
- elif value != user_def[key]:
- if debug:
- print 'value should be identical'
- print value
- print 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, skip_keys=skip_keys, debug=debug)
- if not result:
- if debug:
- print "dict returned false"
- print result
- 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
-
-class YeditException(Exception):
- ''' Exception class for Yedit '''
- pass
-
-class Yedit(object):
- ''' Class to modify yaml files '''
- re_valid_key = r"(((\[-?\d+\])|([a-zA-Z-./]+)).?)+$"
- re_key = r"(?:\[(-?\d+)\])|([a-zA-Z-./]+)"
-
- def __init__(self, filename=None, content=None, content_type='yaml'):
- self.content = content
- self.filename = filename
- self.__yaml_dict = content
- self.content_type = content_type
- if self.filename and not self.content:
- self.load(content_type=self.content_type)
-
- @property
- def yaml_dict(self):
- ''' getter method for yaml_dict '''
- return self.__yaml_dict
-
- @yaml_dict.setter
- def yaml_dict(self, value):
- ''' setter method for yaml_dict '''
- self.__yaml_dict = value
-
- @staticmethod
- def remove_entry(data, key):
- ''' remove data at location key '''
- if not (key and re.match(Yedit.re_valid_key, key) and isinstance(data, (list, dict))):
- return None
-
- key_indexes = re.findall(Yedit.re_key, key)
- for arr_ind, dict_key in key_indexes[:-1]:
- if dict_key and isinstance(data, dict):
- data = data.get(dict_key, None)
- elif arr_ind and isinstance(data, list) and int(arr_ind) <= len(data) - 1:
- data = data[int(arr_ind)]
- else:
- return None
-
- # process last index for remove
- # expected list entry
- if key_indexes[-1][0]:
- if isinstance(data, list) and int(key_indexes[-1][0]) <= len(data) - 1:
- del data[int(key_indexes[-1][0])]
- return True
-
- # expected dict entry
- elif key_indexes[-1][1]:
- if isinstance(data, dict):
- del data[key_indexes[-1][1]]
- return True
-
- @staticmethod
- def add_entry(data, key, item=None):
- ''' Get an item from a dictionary with key notation a.b.c
- d = {'a': {'b': 'c'}}}
- key = a.b
- return c
- '''
- if not (key and re.match(Yedit.re_valid_key, key) and isinstance(data, (list, dict))):
- return None
-
- curr_data = data
-
- key_indexes = re.findall(Yedit.re_key, key)
- for arr_ind, dict_key in key_indexes[:-1]:
- if dict_key:
- if isinstance(data, dict) and data.has_key(dict_key):
- data = data[dict_key]
- continue
-
- data[dict_key] = {}
- data = data[dict_key]
-
- elif arr_ind and isinstance(data, list) and int(arr_ind) <= len(data) - 1:
- data = data[int(arr_ind)]
- else:
- return None
-
- # process last index for add
- # expected list entry
- if key_indexes[-1][0] and isinstance(data, list) and int(key_indexes[-1][0]) <= len(data) - 1:
- data[int(key_indexes[-1][0])] = item
-
- # expected dict entry
- elif key_indexes[-1][1] and isinstance(data, dict):
- data[key_indexes[-1][1]] = item
-
- return curr_data
-
- @staticmethod
- def get_entry(data, key):
- ''' Get an item from a dictionary with key notation a.b.c
- d = {'a': {'b': 'c'}}}
- key = a.b
- return c
- '''
- if not (key and re.match(Yedit.re_valid_key, key) and isinstance(data, (list, dict))):
- return None
-
- key_indexes = re.findall(Yedit.re_key, key)
- for arr_ind, dict_key in key_indexes:
- if dict_key and isinstance(data, dict):
- data = data.get(dict_key, None)
- elif arr_ind and isinstance(data, list) and int(arr_ind) <= len(data) - 1:
- data = data[int(arr_ind)]
- else:
- return None
-
- return data
-
- def write(self):
- ''' write to file '''
- if not self.filename:
- raise YeditException('Please specify a filename.')
-
- with open(self.filename, 'w') as yfd:
- yfd.write(yaml.safe_dump(self.yaml_dict, default_flow_style=False))
-
- def read(self):
- ''' write to file '''
- # check if it exists
- if not self.exists():
- return None
-
- contents = None
- with open(self.filename) as yfd:
- contents = yfd.read()
-
- return contents
-
- def exists(self):
- ''' return whether file exists '''
- if os.path.exists(self.filename):
- return True
-
- return False
-
- def load(self, content_type='yaml'):
- ''' return yaml file '''
- contents = self.read()
-
- if not contents:
- return None
-
- # check if it is yaml
- try:
- if content_type == 'yaml':
- self.yaml_dict = yaml.load(contents)
- elif content_type == 'json':
- self.yaml_dict = json.loads(contents)
- except yaml.YAMLError as _:
- # Error loading yaml or json
- return None
-
- return self.yaml_dict
-
- def get(self, key):
- ''' get a specified key'''
- try:
- entry = Yedit.get_entry(self.yaml_dict, key)
- except KeyError as _:
- entry = None
-
- return entry
-
- def delete(self, key):
- ''' remove key from a dict'''
- try:
- entry = Yedit.get_entry(self.yaml_dict, key)
- except KeyError as _:
- entry = None
- if not entry:
- return (False, self.yaml_dict)
-
- result = Yedit.remove_entry(self.yaml_dict, key)
- if not result:
- return (False, self.yaml_dict)
-
- return (True, self.yaml_dict)
-
- def put(self, key, value):
- ''' put key, value into a dict '''
- try:
- entry = Yedit.get_entry(self.yaml_dict, key)
- except KeyError as _:
- entry = None
-
- if entry == value:
- return (False, self.yaml_dict)
-
- result = Yedit.add_entry(self.yaml_dict, key, value)
- if not result:
- return (False, self.yaml_dict)
-
- return (True, self.yaml_dict)
-
- def create(self, key, value):
- ''' create a yaml file '''
- if not self.exists():
- self.yaml_dict = {key: value}
- return (True, self.yaml_dict)
-
- return (False, self.yaml_dict)
-
-import time
-
-class RouterConfig(object):
- ''' RouterConfig is a DTO for the router. '''
- def __init__(self, rname, kubeconfig, router_options):
- self.name = rname
- self.kubeconfig = kubeconfig
- self._router_options = router_options
-
- @property
- def router_options(self):
- ''' return router options '''
- return self._router_options
-
- def to_option_list(self):
- ''' return all options as a string'''
- return RouterConfig.stringify(self.router_options)
-
- @staticmethod
- def stringify(options):
- ''' return hash as list of key value pairs '''
- rval = []
- for key, data in options.items():
- if data['include'] and data['value']:
- rval.append('--%s=%s' % (key.replace('_', '-'), data['value']))
-
- return rval
-
-class Router(OpenShiftCLI):
- ''' Class to wrap the oc command line tools '''
- def __init__(self,
- router_config,
- verbose=False):
- ''' Constructor for OpenshiftOC
-
- a router consists of 3 or more parts
- - dc/router
- - svc/router
- - endpoint/router
- '''
- super(Router, self).__init__('default', router_config.kubeconfig, verbose)
- self.rconfig = router_config
- self.verbose = verbose
- self.router_parts = [{'kind': 'dc', 'name': self.rconfig.name},
- {'kind': 'svc', 'name': self.rconfig.name},
- #{'kind': 'endpoints', 'name': self.rconfig.name},
- ]
- def get(self, filter_kind=None):
- ''' return the self.router_parts '''
- rparts = self.router_parts
- parts = []
- if filter_kind:
- rparts = [part for part in self.router_parts if filter_kind == part['kind']]
-
- for part in rparts:
- parts.append(self._get(part['kind'], rname=part['name']))
-
- return parts
-
- def exists(self):
- '''return a deploymentconfig by name '''
- parts = self.get()
- for part in parts:
- if part['returncode'] != 0:
- return False
-
- return True
-
- def delete(self):
- '''return all pods '''
- parts = []
- for part in self.router_parts:
- parts.append(self._delete(part['kind'], part['name']))
-
- return parts
-
- def create(self, dryrun=False, output=False, output_type='json'):
- '''Create a deploymentconfig '''
- # We need to create the pem file
- router_pem = '/tmp/router.pem'
- with open(router_pem, 'w') as rfd:
- rfd.write(open(self.rconfig.router_options['cert_file']['value']).read())
- rfd.write(open(self.rconfig.router_options['key_file']['value']).read())
-
- atexit.register(Utils.cleanup, [router_pem])
- self.rconfig.router_options['default_cert']['value'] = router_pem
-
- options = self.rconfig.to_option_list()
-
- cmd = ['router']
- cmd.extend(options)
- if dryrun:
- cmd.extend(['--dry-run=True', '-o', 'json'])
-
- results = self.openshift_cmd(cmd, oadm=True, output=output, output_type=output_type)
-
- return results
-
- def update(self):
- '''run update for the router. This performs a delete and then create '''
- parts = self.delete()
- if any([part['returncode'] != 0 for part in parts]):
- return parts
-
- # Ugly built in sleep here.
- time.sleep(15)
-
- return self.create()
-
- def needs_update(self, verbose=False):
- ''' check to see if we need to update '''
- dc_inmem = self.get(filter_kind='dc')[0]
- if dc_inmem['returncode'] != 0:
- return dc_inmem
-
- user_dc = self.create(dryrun=True, output=True, output_type='raw')
- if user_dc['returncode'] != 0:
- return user_dc
-
- # Since the output from oadm_router is returned as raw
- # we need to parse it. The first line is the stats_password
- user_dc_results = user_dc['results'].split('\n')
- # stats_password = user_dc_results[0]
-
- # Load the string back into json and get the newly created dc
- user_dc = json.loads('\n'.join(user_dc_results[1:]))['items'][0]
-
- # Router needs some exceptions.
- # We do not want to check the autogenerated password for stats admin
- if not self.rconfig.router_options['stats_password']['value']:
- for idx, env_var in enumerate(user_dc['spec']['template']['spec']['containers'][0]['env']):
- if env_var['name'] == 'STATS_PASSWORD':
- env_var['value'] = \
- dc_inmem['results'][0]['spec']['template']['spec']['containers'][0]['env'][idx]['value']
-
- # dry-run doesn't add the protocol to the ports section. We will manually do that.
- for idx, port in enumerate(user_dc['spec']['template']['spec']['containers'][0]['ports']):
- if not port.has_key('protocol'):
- port['protocol'] = 'TCP'
-
- # These are different when generating
- skip = ['dnsPolicy',
- 'terminationGracePeriodSeconds',
- 'restartPolicy', 'timeoutSeconds',
- 'livenessProbe', 'readinessProbe',
- 'terminationMessagePath',
- 'rollingParams',
- ]
-
- return not Utils.check_def_equal(user_dc, dc_inmem['results'][0], skip_keys=skip, debug=verbose)
-
-def main():
- '''
- ansible oc module for secrets
- '''
-
- module = AnsibleModule(
- argument_spec=dict(
- state=dict(default='present', type='str',
- choices=['present', 'absent']),
- debug=dict(default=False, type='bool'),
- namespace=dict(default='default', type='str'),
- name=dict(default='router', type='str'),
-
- kubeconfig=dict(default='/etc/origin/master/admin.kubeconfig', type='str'),
- credentials=dict(default='/etc/origin/master/openshift-router.kubeconfig', type='str'),
- cert_file=dict(default=None, type='str'),
- key_file=dict(default=None, type='str'),
- image=dict(default=None, type='str'), #'openshift3/ose-${component}:${version}'
- latest_image=dict(default=False, type='bool'),
- labels=dict(default=None, type='list'),
- ports=dict(default=['80:80', '443:443'], type='list'),
- replicas=dict(default=1, type='int'),
- selector=dict(default=None, type='str'),
- service_account=dict(default='router', type='str'),
- router_type=dict(default='haproxy-router', type='str'),
- host_network=dict(default=True, type='bool'),
- # external host options
- external_host=dict(default=None, type='str'),
- external_host_vserver=dict(default=None, type='str'),
- external_host_insecure=dict(default=False, type='bool'),
- external_host_partition_path=dict(default=None, type='str'),
- external_host_username=dict(default=None, type='str'),
- external_host_password=dict(default=None, type='str'),
- external_host_private_key=dict(default=None, type='str'),
- # Metrics
- expose_metrics=dict(default=False, type='bool'),
- metrics_image=dict(default=None, type='str'),
- # Stats
- stats_user=dict(default=None, type='str'),
- stats_password=dict(default=None, type='str'),
- stats_port=dict(default=1936, type='int'),
-
- ),
- mutually_exclusive=[["router_type", "images"]],
-
- supports_check_mode=True,
- )
-
- rconfig = RouterConfig(module.params['name'],
- module.params['kubeconfig'],
- {'credentials': {'value': module.params['credentials'], 'include': True},
- 'default_cert': {'value': None, 'include': True},
- 'cert_file': {'value': module.params['cert_file'], 'include': False},
- 'key_file': {'value': module.params['key_file'], 'include': False},
- 'image': {'value': module.params['image'], 'include': True},
- 'latest_image': {'value': module.params['latest_image'], 'include': True},
- 'labels': {'value': module.params['labels'], 'include': True},
- 'ports': {'value': ','.join(module.params['ports']), 'include': True},
- 'replicas': {'value': module.params['replicas'], 'include': True},
- 'selector': {'value': module.params['selector'], 'include': True},
- 'service_account': {'value': module.params['service_account'], 'include': True},
- 'router_type': {'value': module.params['router_type'], 'include': False},
- 'host_network': {'value': module.params['host_network'], 'include': True},
- 'external_host': {'value': module.params['external_host'], 'include': True},
- 'external_host_vserver': {'value': module.params['external_host_vserver'],
- 'include': True},
- 'external_host_insecure': {'value': module.params['external_host_insecure'],
- 'include': True},
- 'external_host_partition_path': {'value': module.params['external_host_partition_path'],
- 'include': True},
- 'external_host_username': {'value': module.params['external_host_username'],
- 'include': True},
- 'external_host_password': {'value': module.params['external_host_password'],
- 'include': True},
- 'external_host_private_key': {'value': module.params['external_host_private_key'],
- 'include': True},
- 'expose_metrics': {'value': module.params['expose_metrics'], 'include': True},
- 'metrics_image': {'value': module.params['metrics_image'], 'include': True},
- 'stats_user': {'value': module.params['stats_user'], 'include': True},
- 'stats_password': {'value': module.params['stats_password'], 'include': True},
- 'stats_port': {'value': module.params['stats_port'], 'include': True},
- })
-
-
- ocrouter = Router(rconfig)
-
- state = module.params['state']
-
- ########
- # Delete
- ########
- if state == 'absent':
- if not ocrouter.exists():
- module.exit_json(changed=False, state="absent")
-
- if module.check_mode:
- module.exit_json(change=False, msg='Would have performed a delete.')
-
- api_rval = ocrouter.delete()
- module.exit_json(changed=True, results=api_rval, state="absent")
-
-
- if state == 'present':
- ########
- # Create
- ########
- if not ocrouter.exists():
-
- if module.check_mode:
- module.exit_json(change=False, msg='Would have performed a create.')
-
- api_rval = ocrouter.create()
-
- module.exit_json(changed=True, results=api_rval, state="present")
-
- ########
- # Update
- ########
- if not ocrouter.needs_update():
- module.exit_json(changed=False, state="present")
-
- if module.check_mode:
- module.exit_json(change=False, msg='Would have performed an update.')
-
- api_rval = ocrouter.update()
-
- 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/library/oc_edit.py b/roles/lib_openshift_api/library/oc_edit.py
deleted file mode 100644
index e43b6175a..000000000
--- a/roles/lib_openshift_api/library/oc_edit.py
+++ /dev/null
@@ -1,646 +0,0 @@
-#!/usr/bin/env python
-# ___ ___ _ _ ___ ___ _ _____ ___ ___
-# / __| __| \| | __| _ \ /_\_ _| __| \
-# | (_ | _|| .` | _|| / / _ \| | | _|| |) |
-# \___|___|_|\_|___|_|_\/_/_\_\_|_|___|___/_ _____
-# | \ / _ \ | \| |/ _ \_ _| | __| \_ _|_ _|
-# | |) | (_) | | .` | (_) || | | _|| |) | | | |
-# |___/ \___/ |_|\_|\___/ |_| |___|___/___| |_|
-'''
- OpenShiftCLI class that wraps the oc commands in a subprocess
-'''
-
-import atexit
-import json
-import os
-import shutil
-import subprocess
-import re
-
-import yaml
-# This is here because of a bug that causes yaml
-# to incorrectly handle timezone info on timestamps
-def timestamp_constructor(_, node):
- '''return timestamps as strings'''
- return str(node.value)
-yaml.add_constructor(u'tag:yaml.org,2002:timestamp', timestamp_constructor)
-
-# pylint: disable=too-few-public-methods
-class OpenShiftCLI(object):
- ''' Class to wrap the command line tools '''
- def __init__(self,
- namespace,
- kubeconfig='/etc/origin/master/admin.kubeconfig',
- verbose=False):
- ''' Constructor for OpenshiftCLI '''
- 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])
- changes = []
- for key, value in content.items():
- changes.append(yed.put(key, value))
-
- if any([not change[0] for change in changes]):
- return {'returncode': 0, 'updated': False}
-
- yed.write()
-
- 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.openshift_cmd(cmd)
-
- def _create(self, fname):
- '''return all pods '''
- return self.openshift_cmd(['create', '-f', fname, '-n', self.namespace])
-
- def _delete(self, resource, rname):
- '''return all pods '''
- return self.openshift_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.openshift_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 openshift_cmd(self, cmd, oadm=False, output=False, output_type='json'):
- '''Base command for oc '''
- #cmds = ['/usr/bin/oc', '--config', self.kubeconfig]
- cmds = []
- if oadm:
- cmds = ['/usr/bin/oadm']
- else:
- cmds = ['/usr/bin/oc']
-
- cmds.extend(cmd)
-
- rval = {}
- results = ''
- err = None
-
- if self.verbose:
- print ' '.join(cmds)
-
- proc = subprocess.Popen(cmds,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- env={'KUBECONFIG': self.kubeconfig})
-
- proc.wait()
- stdout = proc.stdout.read()
- stderr = proc.stderr.read()
- rval = {"returncode": proc.returncode,
- "results": results,
- "cmd": ' '.join(cmds),
- }
-
- if proc.returncode == 0:
- if output:
- if output_type == 'json':
- try:
- rval['results'] = json.loads(stdout)
- except ValueError as err:
- if "No JSON object could be decoded" in err.message:
- err = err.message
- elif output_type == 'raw':
- rval['results'] = stdout
-
- if self.verbose:
- print stdout
- print stderr
- print
-
- if err:
- rval.update({"err": err,
- "stderr": stderr,
- "stdout": stdout,
- "cmd": cmds
- })
-
- else:
- rval.update({"stderr": stderr,
- "stdout": stdout,
- "results": {},
- })
-
- return rval
-
-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.safe_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, skip_keys=None, 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']
- if skip_keys:
- skip.extend(skip_keys)
-
- 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):
- if debug:
- print 'user_def[key] is not a list'
- return False
-
- for values in zip(user_def[key], value):
- if isinstance(values[0], dict) and isinstance(values[1], dict):
- if debug:
- print 'sending list - list'
- print type(values[0])
- print type(values[1])
- result = Utils.check_def_equal(values[0], values[1], skip_keys=skip_keys, debug=debug)
- if not result:
- print 'list compare returned false'
- return False
-
- elif value != user_def[key]:
- if debug:
- print 'value should be identical'
- print value
- print 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, skip_keys=skip_keys, debug=debug)
- if not result:
- if debug:
- print "dict returned false"
- print result
- 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
-
-class YeditException(Exception):
- ''' Exception class for Yedit '''
- pass
-
-class Yedit(object):
- ''' Class to modify yaml files '''
- re_valid_key = r"(((\[-?\d+\])|([a-zA-Z-./]+)).?)+$"
- re_key = r"(?:\[(-?\d+)\])|([a-zA-Z-./]+)"
-
- def __init__(self, filename=None, content=None, content_type='yaml'):
- self.content = content
- self.filename = filename
- self.__yaml_dict = content
- self.content_type = content_type
- if self.filename and not self.content:
- self.load(content_type=self.content_type)
-
- @property
- def yaml_dict(self):
- ''' getter method for yaml_dict '''
- return self.__yaml_dict
-
- @yaml_dict.setter
- def yaml_dict(self, value):
- ''' setter method for yaml_dict '''
- self.__yaml_dict = value
-
- @staticmethod
- def remove_entry(data, key):
- ''' remove data at location key '''
- if not (key and re.match(Yedit.re_valid_key, key) and isinstance(data, (list, dict))):
- return None
-
- key_indexes = re.findall(Yedit.re_key, key)
- for arr_ind, dict_key in key_indexes[:-1]:
- if dict_key and isinstance(data, dict):
- data = data.get(dict_key, None)
- elif arr_ind and isinstance(data, list) and int(arr_ind) <= len(data) - 1:
- data = data[int(arr_ind)]
- else:
- return None
-
- # process last index for remove
- # expected list entry
- if key_indexes[-1][0]:
- if isinstance(data, list) and int(key_indexes[-1][0]) <= len(data) - 1:
- del data[int(key_indexes[-1][0])]
- return True
-
- # expected dict entry
- elif key_indexes[-1][1]:
- if isinstance(data, dict):
- del data[key_indexes[-1][1]]
- return True
-
- @staticmethod
- def add_entry(data, key, item=None):
- ''' Get an item from a dictionary with key notation a.b.c
- d = {'a': {'b': 'c'}}}
- key = a.b
- return c
- '''
- if not (key and re.match(Yedit.re_valid_key, key) and isinstance(data, (list, dict))):
- return None
-
- curr_data = data
-
- key_indexes = re.findall(Yedit.re_key, key)
- for arr_ind, dict_key in key_indexes[:-1]:
- if dict_key:
- if isinstance(data, dict) and data.has_key(dict_key):
- data = data[dict_key]
- continue
-
- data[dict_key] = {}
- data = data[dict_key]
-
- elif arr_ind and isinstance(data, list) and int(arr_ind) <= len(data) - 1:
- data = data[int(arr_ind)]
- else:
- return None
-
- # process last index for add
- # expected list entry
- if key_indexes[-1][0] and isinstance(data, list) and int(key_indexes[-1][0]) <= len(data) - 1:
- data[int(key_indexes[-1][0])] = item
-
- # expected dict entry
- elif key_indexes[-1][1] and isinstance(data, dict):
- data[key_indexes[-1][1]] = item
-
- return curr_data
-
- @staticmethod
- def get_entry(data, key):
- ''' Get an item from a dictionary with key notation a.b.c
- d = {'a': {'b': 'c'}}}
- key = a.b
- return c
- '''
- if not (key and re.match(Yedit.re_valid_key, key) and isinstance(data, (list, dict))):
- return None
-
- key_indexes = re.findall(Yedit.re_key, key)
- for arr_ind, dict_key in key_indexes:
- if dict_key and isinstance(data, dict):
- data = data.get(dict_key, None)
- elif arr_ind and isinstance(data, list) and int(arr_ind) <= len(data) - 1:
- data = data[int(arr_ind)]
- else:
- return None
-
- return data
-
- def write(self):
- ''' write to file '''
- if not self.filename:
- raise YeditException('Please specify a filename.')
-
- with open(self.filename, 'w') as yfd:
- yfd.write(yaml.safe_dump(self.yaml_dict, default_flow_style=False))
-
- def read(self):
- ''' write to file '''
- # check if it exists
- if not self.exists():
- return None
-
- contents = None
- with open(self.filename) as yfd:
- contents = yfd.read()
-
- return contents
-
- def exists(self):
- ''' return whether file exists '''
- if os.path.exists(self.filename):
- return True
-
- return False
-
- def load(self, content_type='yaml'):
- ''' return yaml file '''
- contents = self.read()
-
- if not contents:
- return None
-
- # check if it is yaml
- try:
- if content_type == 'yaml':
- self.yaml_dict = yaml.load(contents)
- elif content_type == 'json':
- self.yaml_dict = json.loads(contents)
- except yaml.YAMLError as _:
- # Error loading yaml or json
- return None
-
- return self.yaml_dict
-
- def get(self, key):
- ''' get a specified key'''
- try:
- entry = Yedit.get_entry(self.yaml_dict, key)
- except KeyError as _:
- entry = None
-
- return entry
-
- def delete(self, key):
- ''' remove key from a dict'''
- try:
- entry = Yedit.get_entry(self.yaml_dict, key)
- except KeyError as _:
- entry = None
- if not entry:
- return (False, self.yaml_dict)
-
- result = Yedit.remove_entry(self.yaml_dict, key)
- if not result:
- return (False, self.yaml_dict)
-
- return (True, self.yaml_dict)
-
- def put(self, key, value):
- ''' put key, value into a dict '''
- try:
- entry = Yedit.get_entry(self.yaml_dict, key)
- except KeyError as _:
- entry = None
-
- if entry == value:
- return (False, self.yaml_dict)
-
- result = Yedit.add_entry(self.yaml_dict, key, value)
- if not result:
- return (False, self.yaml_dict)
-
- return (True, self.yaml_dict)
-
- def create(self, key, value):
- ''' create a yaml file '''
- if not self.exists():
- self.yaml_dict = {key: value}
- return (True, self.yaml_dict)
-
- return (False, self.yaml_dict)
-
-class Edit(OpenShiftCLI):
- ''' Class to wrap the oc command line tools
- '''
- # pylint: disable=too-many-arguments
- def __init__(self,
- kind,
- namespace,
- resource_name=None,
- kubeconfig='/etc/origin/master/admin.kubeconfig',
- verbose=False):
- ''' Constructor for OpenshiftOC '''
- super(Edit, self).__init__(namespace, kubeconfig)
- self.namespace = namespace
- self.kind = kind
- self.name = resource_name
- self.kubeconfig = kubeconfig
- self.verbose = verbose
-
- def get(self):
- '''return a secret by name '''
- return self._get(self.kind, self.name)
-
- def update(self, file_name, content, force=False, content_type='yaml'):
- '''run update '''
- if file_name:
- if content_type == 'yaml':
- data = yaml.load(open(file_name))
- elif content_type == 'json':
- data = json.loads(open(file_name).read())
-
- changes = []
- yed = Yedit(file_name, data)
- for key, value in content.items():
- changes.append(yed.put(key, value))
-
- if any([not change[0] for change in changes]):
- return {'returncode': 0, 'updated': False}
-
- yed.write()
-
- atexit.register(Utils.cleanup, [file_name])
-
- return self._replace(file_name, force=force)
-
- return self._replace_content(self.kind, self.name, content, force=force)
-
-
-
-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']),
- debug=dict(default=False, type='bool'),
- namespace=dict(default='default', type='str'),
- name=dict(default=None, required=True, type='str'),
- kind=dict(required=True,
- type='str',
- choices=['dc', 'deploymentconfig',
- 'svc', 'service',
- 'scc', 'securitycontextconstraints',
- 'ns', 'namespace', 'project', 'projects',
- 'is', 'imagestream',
- 'istag', 'imagestreamtag',
- 'bc', 'buildconfig',
- 'routes',
- 'node',
- 'secret',
- ]),
- file_name=dict(default=None, type='str'),
- file_format=dict(default='yaml', type='str'),
- content=dict(default=None, required=True, type='dict'),
- force=dict(default=False, type='bool'),
- ),
- supports_check_mode=True,
- )
- ocedit = Edit(module.params['kind'],
- module.params['namespace'],
- module.params['name'],
- kubeconfig=module.params['kubeconfig'],
- verbose=module.params['debug'])
-
- state = module.params['state']
-
- api_rval = ocedit.get()
-
- ########
- # Create
- ########
- if not Utils.exists(api_rval['results'], module.params['name']):
- module.fail_json(msg=api_rval)
-
- ########
- # Update
- ########
- api_rval = ocedit.update(module.params['file_name'],
- module.params['content'],
- module.params['force'],
- module.params['file_format'])
-
-
- if api_rval['returncode'] != 0:
- module.fail_json(msg=api_rval)
-
- if api_rval.has_key('updated') and not api_rval['updated']:
- module.exit_json(changed=False, results=api_rval, state="present")
-
- # return the created object
- api_rval = ocedit.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/library/oc_obj.py b/roles/lib_openshift_api/library/oc_obj.py
deleted file mode 100644
index f0ea66aee..000000000
--- a/roles/lib_openshift_api/library/oc_obj.py
+++ /dev/null
@@ -1,730 +0,0 @@
-#!/usr/bin/env python
-# ___ ___ _ _ ___ ___ _ _____ ___ ___
-# / __| __| \| | __| _ \ /_\_ _| __| \
-# | (_ | _|| .` | _|| / / _ \| | | _|| |) |
-# \___|___|_|\_|___|_|_\/_/_\_\_|_|___|___/_ _____
-# | \ / _ \ | \| |/ _ \_ _| | __| \_ _|_ _|
-# | |) | (_) | | .` | (_) || | | _|| |) | | | |
-# |___/ \___/ |_|\_|\___/ |_| |___|___/___| |_|
-'''
- OpenShiftCLI class that wraps the oc commands in a subprocess
-'''
-
-import atexit
-import json
-import os
-import shutil
-import subprocess
-import re
-
-import yaml
-# This is here because of a bug that causes yaml
-# to incorrectly handle timezone info on timestamps
-def timestamp_constructor(_, node):
- '''return timestamps as strings'''
- return str(node.value)
-yaml.add_constructor(u'tag:yaml.org,2002:timestamp', timestamp_constructor)
-
-# pylint: disable=too-few-public-methods
-class OpenShiftCLI(object):
- ''' Class to wrap the command line tools '''
- def __init__(self,
- namespace,
- kubeconfig='/etc/origin/master/admin.kubeconfig',
- verbose=False):
- ''' Constructor for OpenshiftCLI '''
- 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])
- changes = []
- for key, value in content.items():
- changes.append(yed.put(key, value))
-
- if any([not change[0] for change in changes]):
- return {'returncode': 0, 'updated': False}
-
- yed.write()
-
- 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.openshift_cmd(cmd)
-
- def _create(self, fname):
- '''return all pods '''
- return self.openshift_cmd(['create', '-f', fname, '-n', self.namespace])
-
- def _delete(self, resource, rname):
- '''return all pods '''
- return self.openshift_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.openshift_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 openshift_cmd(self, cmd, oadm=False, output=False, output_type='json'):
- '''Base command for oc '''
- #cmds = ['/usr/bin/oc', '--config', self.kubeconfig]
- cmds = []
- if oadm:
- cmds = ['/usr/bin/oadm']
- else:
- cmds = ['/usr/bin/oc']
-
- cmds.extend(cmd)
-
- rval = {}
- results = ''
- err = None
-
- if self.verbose:
- print ' '.join(cmds)
-
- proc = subprocess.Popen(cmds,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- env={'KUBECONFIG': self.kubeconfig})
-
- proc.wait()
- stdout = proc.stdout.read()
- stderr = proc.stderr.read()
- rval = {"returncode": proc.returncode,
- "results": results,
- "cmd": ' '.join(cmds),
- }
-
- if proc.returncode == 0:
- if output:
- if output_type == 'json':
- try:
- rval['results'] = json.loads(stdout)
- except ValueError as err:
- if "No JSON object could be decoded" in err.message:
- err = err.message
- elif output_type == 'raw':
- rval['results'] = stdout
-
- if self.verbose:
- print stdout
- print stderr
- print
-
- if err:
- rval.update({"err": err,
- "stderr": stderr,
- "stdout": stdout,
- "cmd": cmds
- })
-
- else:
- rval.update({"stderr": stderr,
- "stdout": stdout,
- "results": {},
- })
-
- return rval
-
-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.safe_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, skip_keys=None, 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']
- if skip_keys:
- skip.extend(skip_keys)
-
- 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):
- if debug:
- print 'user_def[key] is not a list'
- return False
-
- for values in zip(user_def[key], value):
- if isinstance(values[0], dict) and isinstance(values[1], dict):
- if debug:
- print 'sending list - list'
- print type(values[0])
- print type(values[1])
- result = Utils.check_def_equal(values[0], values[1], skip_keys=skip_keys, debug=debug)
- if not result:
- print 'list compare returned false'
- return False
-
- elif value != user_def[key]:
- if debug:
- print 'value should be identical'
- print value
- print 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, skip_keys=skip_keys, debug=debug)
- if not result:
- if debug:
- print "dict returned false"
- print result
- 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
-
-class YeditException(Exception):
- ''' Exception class for Yedit '''
- pass
-
-class Yedit(object):
- ''' Class to modify yaml files '''
- re_valid_key = r"(((\[-?\d+\])|([a-zA-Z-./]+)).?)+$"
- re_key = r"(?:\[(-?\d+)\])|([a-zA-Z-./]+)"
-
- def __init__(self, filename=None, content=None, content_type='yaml'):
- self.content = content
- self.filename = filename
- self.__yaml_dict = content
- self.content_type = content_type
- if self.filename and not self.content:
- self.load(content_type=self.content_type)
-
- @property
- def yaml_dict(self):
- ''' getter method for yaml_dict '''
- return self.__yaml_dict
-
- @yaml_dict.setter
- def yaml_dict(self, value):
- ''' setter method for yaml_dict '''
- self.__yaml_dict = value
-
- @staticmethod
- def remove_entry(data, key):
- ''' remove data at location key '''
- if not (key and re.match(Yedit.re_valid_key, key) and isinstance(data, (list, dict))):
- return None
-
- key_indexes = re.findall(Yedit.re_key, key)
- for arr_ind, dict_key in key_indexes[:-1]:
- if dict_key and isinstance(data, dict):
- data = data.get(dict_key, None)
- elif arr_ind and isinstance(data, list) and int(arr_ind) <= len(data) - 1:
- data = data[int(arr_ind)]
- else:
- return None
-
- # process last index for remove
- # expected list entry
- if key_indexes[-1][0]:
- if isinstance(data, list) and int(key_indexes[-1][0]) <= len(data) - 1:
- del data[int(key_indexes[-1][0])]
- return True
-
- # expected dict entry
- elif key_indexes[-1][1]:
- if isinstance(data, dict):
- del data[key_indexes[-1][1]]
- return True
-
- @staticmethod
- def add_entry(data, key, item=None):
- ''' Get an item from a dictionary with key notation a.b.c
- d = {'a': {'b': 'c'}}}
- key = a.b
- return c
- '''
- if not (key and re.match(Yedit.re_valid_key, key) and isinstance(data, (list, dict))):
- return None
-
- curr_data = data
-
- key_indexes = re.findall(Yedit.re_key, key)
- for arr_ind, dict_key in key_indexes[:-1]:
- if dict_key:
- if isinstance(data, dict) and data.has_key(dict_key):
- data = data[dict_key]
- continue
-
- data[dict_key] = {}
- data = data[dict_key]
-
- elif arr_ind and isinstance(data, list) and int(arr_ind) <= len(data) - 1:
- data = data[int(arr_ind)]
- else:
- return None
-
- # process last index for add
- # expected list entry
- if key_indexes[-1][0] and isinstance(data, list) and int(key_indexes[-1][0]) <= len(data) - 1:
- data[int(key_indexes[-1][0])] = item
-
- # expected dict entry
- elif key_indexes[-1][1] and isinstance(data, dict):
- data[key_indexes[-1][1]] = item
-
- return curr_data
-
- @staticmethod
- def get_entry(data, key):
- ''' Get an item from a dictionary with key notation a.b.c
- d = {'a': {'b': 'c'}}}
- key = a.b
- return c
- '''
- if not (key and re.match(Yedit.re_valid_key, key) and isinstance(data, (list, dict))):
- return None
-
- key_indexes = re.findall(Yedit.re_key, key)
- for arr_ind, dict_key in key_indexes:
- if dict_key and isinstance(data, dict):
- data = data.get(dict_key, None)
- elif arr_ind and isinstance(data, list) and int(arr_ind) <= len(data) - 1:
- data = data[int(arr_ind)]
- else:
- return None
-
- return data
-
- def write(self):
- ''' write to file '''
- if not self.filename:
- raise YeditException('Please specify a filename.')
-
- with open(self.filename, 'w') as yfd:
- yfd.write(yaml.safe_dump(self.yaml_dict, default_flow_style=False))
-
- def read(self):
- ''' write to file '''
- # check if it exists
- if not self.exists():
- return None
-
- contents = None
- with open(self.filename) as yfd:
- contents = yfd.read()
-
- return contents
-
- def exists(self):
- ''' return whether file exists '''
- if os.path.exists(self.filename):
- return True
-
- return False
-
- def load(self, content_type='yaml'):
- ''' return yaml file '''
- contents = self.read()
-
- if not contents:
- return None
-
- # check if it is yaml
- try:
- if content_type == 'yaml':
- self.yaml_dict = yaml.load(contents)
- elif content_type == 'json':
- self.yaml_dict = json.loads(contents)
- except yaml.YAMLError as _:
- # Error loading yaml or json
- return None
-
- return self.yaml_dict
-
- def get(self, key):
- ''' get a specified key'''
- try:
- entry = Yedit.get_entry(self.yaml_dict, key)
- except KeyError as _:
- entry = None
-
- return entry
-
- def delete(self, key):
- ''' remove key from a dict'''
- try:
- entry = Yedit.get_entry(self.yaml_dict, key)
- except KeyError as _:
- entry = None
- if not entry:
- return (False, self.yaml_dict)
-
- result = Yedit.remove_entry(self.yaml_dict, key)
- if not result:
- return (False, self.yaml_dict)
-
- return (True, self.yaml_dict)
-
- def put(self, key, value):
- ''' put key, value into a dict '''
- try:
- entry = Yedit.get_entry(self.yaml_dict, key)
- except KeyError as _:
- entry = None
-
- if entry == value:
- return (False, self.yaml_dict)
-
- result = Yedit.add_entry(self.yaml_dict, key, value)
- if not result:
- return (False, self.yaml_dict)
-
- return (True, self.yaml_dict)
-
- def create(self, key, value):
- ''' create a yaml file '''
- if not self.exists():
- self.yaml_dict = {key: value}
- return (True, self.yaml_dict)
-
- return (False, self.yaml_dict)
-
-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], skip_keys=None, debug=False)
- 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
-
-
-# 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',
- 'scc', 'securitycontextconstraints',
- 'ns', 'namespace', 'project', 'projects',
- 'is', 'imagestream',
- 'istag', 'imagestreamtag',
- 'bc', 'buildconfig',
- 'routes',
- 'node',
- '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/library/oc_secret.py b/roles/lib_openshift_api/library/oc_secret.py
deleted file mode 100644
index ca58d7139..000000000
--- a/roles/lib_openshift_api/library/oc_secret.py
+++ /dev/null
@@ -1,702 +0,0 @@
-#!/usr/bin/env python
-# ___ ___ _ _ ___ ___ _ _____ ___ ___
-# / __| __| \| | __| _ \ /_\_ _| __| \
-# | (_ | _|| .` | _|| / / _ \| | | _|| |) |
-# \___|___|_|\_|___|_|_\/_/_\_\_|_|___|___/_ _____
-# | \ / _ \ | \| |/ _ \_ _| | __| \_ _|_ _|
-# | |) | (_) | | .` | (_) || | | _|| |) | | | |
-# |___/ \___/ |_|\_|\___/ |_| |___|___/___| |_|
-'''
- OpenShiftCLI class that wraps the oc commands in a subprocess
-'''
-
-import atexit
-import json
-import os
-import shutil
-import subprocess
-import re
-
-import yaml
-# This is here because of a bug that causes yaml
-# to incorrectly handle timezone info on timestamps
-def timestamp_constructor(_, node):
- '''return timestamps as strings'''
- return str(node.value)
-yaml.add_constructor(u'tag:yaml.org,2002:timestamp', timestamp_constructor)
-
-# pylint: disable=too-few-public-methods
-class OpenShiftCLI(object):
- ''' Class to wrap the command line tools '''
- def __init__(self,
- namespace,
- kubeconfig='/etc/origin/master/admin.kubeconfig',
- verbose=False):
- ''' Constructor for OpenshiftCLI '''
- 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])
- changes = []
- for key, value in content.items():
- changes.append(yed.put(key, value))
-
- if any([not change[0] for change in changes]):
- return {'returncode': 0, 'updated': False}
-
- yed.write()
-
- 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.openshift_cmd(cmd)
-
- def _create(self, fname):
- '''return all pods '''
- return self.openshift_cmd(['create', '-f', fname, '-n', self.namespace])
-
- def _delete(self, resource, rname):
- '''return all pods '''
- return self.openshift_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.openshift_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 openshift_cmd(self, cmd, oadm=False, output=False, output_type='json'):
- '''Base command for oc '''
- #cmds = ['/usr/bin/oc', '--config', self.kubeconfig]
- cmds = []
- if oadm:
- cmds = ['/usr/bin/oadm']
- else:
- cmds = ['/usr/bin/oc']
-
- cmds.extend(cmd)
-
- rval = {}
- results = ''
- err = None
-
- if self.verbose:
- print ' '.join(cmds)
-
- proc = subprocess.Popen(cmds,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- env={'KUBECONFIG': self.kubeconfig})
-
- proc.wait()
- stdout = proc.stdout.read()
- stderr = proc.stderr.read()
- rval = {"returncode": proc.returncode,
- "results": results,
- "cmd": ' '.join(cmds),
- }
-
- if proc.returncode == 0:
- if output:
- if output_type == 'json':
- try:
- rval['results'] = json.loads(stdout)
- except ValueError as err:
- if "No JSON object could be decoded" in err.message:
- err = err.message
- elif output_type == 'raw':
- rval['results'] = stdout
-
- if self.verbose:
- print stdout
- print stderr
- print
-
- if err:
- rval.update({"err": err,
- "stderr": stderr,
- "stdout": stdout,
- "cmd": cmds
- })
-
- else:
- rval.update({"stderr": stderr,
- "stdout": stdout,
- "results": {},
- })
-
- return rval
-
-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.safe_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, skip_keys=None, 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']
- if skip_keys:
- skip.extend(skip_keys)
-
- 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):
- if debug:
- print 'user_def[key] is not a list'
- return False
-
- for values in zip(user_def[key], value):
- if isinstance(values[0], dict) and isinstance(values[1], dict):
- if debug:
- print 'sending list - list'
- print type(values[0])
- print type(values[1])
- result = Utils.check_def_equal(values[0], values[1], skip_keys=skip_keys, debug=debug)
- if not result:
- print 'list compare returned false'
- return False
-
- elif value != user_def[key]:
- if debug:
- print 'value should be identical'
- print value
- print 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, skip_keys=skip_keys, debug=debug)
- if not result:
- if debug:
- print "dict returned false"
- print result
- 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
-
-class YeditException(Exception):
- ''' Exception class for Yedit '''
- pass
-
-class Yedit(object):
- ''' Class to modify yaml files '''
- re_valid_key = r"(((\[-?\d+\])|([a-zA-Z-./]+)).?)+$"
- re_key = r"(?:\[(-?\d+)\])|([a-zA-Z-./]+)"
-
- def __init__(self, filename=None, content=None, content_type='yaml'):
- self.content = content
- self.filename = filename
- self.__yaml_dict = content
- self.content_type = content_type
- if self.filename and not self.content:
- self.load(content_type=self.content_type)
-
- @property
- def yaml_dict(self):
- ''' getter method for yaml_dict '''
- return self.__yaml_dict
-
- @yaml_dict.setter
- def yaml_dict(self, value):
- ''' setter method for yaml_dict '''
- self.__yaml_dict = value
-
- @staticmethod
- def remove_entry(data, key):
- ''' remove data at location key '''
- if not (key and re.match(Yedit.re_valid_key, key) and isinstance(data, (list, dict))):
- return None
-
- key_indexes = re.findall(Yedit.re_key, key)
- for arr_ind, dict_key in key_indexes[:-1]:
- if dict_key and isinstance(data, dict):
- data = data.get(dict_key, None)
- elif arr_ind and isinstance(data, list) and int(arr_ind) <= len(data) - 1:
- data = data[int(arr_ind)]
- else:
- return None
-
- # process last index for remove
- # expected list entry
- if key_indexes[-1][0]:
- if isinstance(data, list) and int(key_indexes[-1][0]) <= len(data) - 1:
- del data[int(key_indexes[-1][0])]
- return True
-
- # expected dict entry
- elif key_indexes[-1][1]:
- if isinstance(data, dict):
- del data[key_indexes[-1][1]]
- return True
-
- @staticmethod
- def add_entry(data, key, item=None):
- ''' Get an item from a dictionary with key notation a.b.c
- d = {'a': {'b': 'c'}}}
- key = a.b
- return c
- '''
- if not (key and re.match(Yedit.re_valid_key, key) and isinstance(data, (list, dict))):
- return None
-
- curr_data = data
-
- key_indexes = re.findall(Yedit.re_key, key)
- for arr_ind, dict_key in key_indexes[:-1]:
- if dict_key:
- if isinstance(data, dict) and data.has_key(dict_key):
- data = data[dict_key]
- continue
-
- data[dict_key] = {}
- data = data[dict_key]
-
- elif arr_ind and isinstance(data, list) and int(arr_ind) <= len(data) - 1:
- data = data[int(arr_ind)]
- else:
- return None
-
- # process last index for add
- # expected list entry
- if key_indexes[-1][0] and isinstance(data, list) and int(key_indexes[-1][0]) <= len(data) - 1:
- data[int(key_indexes[-1][0])] = item
-
- # expected dict entry
- elif key_indexes[-1][1] and isinstance(data, dict):
- data[key_indexes[-1][1]] = item
-
- return curr_data
-
- @staticmethod
- def get_entry(data, key):
- ''' Get an item from a dictionary with key notation a.b.c
- d = {'a': {'b': 'c'}}}
- key = a.b
- return c
- '''
- if not (key and re.match(Yedit.re_valid_key, key) and isinstance(data, (list, dict))):
- return None
-
- key_indexes = re.findall(Yedit.re_key, key)
- for arr_ind, dict_key in key_indexes:
- if dict_key and isinstance(data, dict):
- data = data.get(dict_key, None)
- elif arr_ind and isinstance(data, list) and int(arr_ind) <= len(data) - 1:
- data = data[int(arr_ind)]
- else:
- return None
-
- return data
-
- def write(self):
- ''' write to file '''
- if not self.filename:
- raise YeditException('Please specify a filename.')
-
- with open(self.filename, 'w') as yfd:
- yfd.write(yaml.safe_dump(self.yaml_dict, default_flow_style=False))
-
- def read(self):
- ''' write to file '''
- # check if it exists
- if not self.exists():
- return None
-
- contents = None
- with open(self.filename) as yfd:
- contents = yfd.read()
-
- return contents
-
- def exists(self):
- ''' return whether file exists '''
- if os.path.exists(self.filename):
- return True
-
- return False
-
- def load(self, content_type='yaml'):
- ''' return yaml file '''
- contents = self.read()
-
- if not contents:
- return None
-
- # check if it is yaml
- try:
- if content_type == 'yaml':
- self.yaml_dict = yaml.load(contents)
- elif content_type == 'json':
- self.yaml_dict = json.loads(contents)
- except yaml.YAMLError as _:
- # Error loading yaml or json
- return None
-
- return self.yaml_dict
-
- def get(self, key):
- ''' get a specified key'''
- try:
- entry = Yedit.get_entry(self.yaml_dict, key)
- except KeyError as _:
- entry = None
-
- return entry
-
- def delete(self, key):
- ''' remove key from a dict'''
- try:
- entry = Yedit.get_entry(self.yaml_dict, key)
- except KeyError as _:
- entry = None
- if not entry:
- return (False, self.yaml_dict)
-
- result = Yedit.remove_entry(self.yaml_dict, key)
- if not result:
- return (False, self.yaml_dict)
-
- return (True, self.yaml_dict)
-
- def put(self, key, value):
- ''' put key, value into a dict '''
- try:
- entry = Yedit.get_entry(self.yaml_dict, key)
- except KeyError as _:
- entry = None
-
- if entry == value:
- return (False, self.yaml_dict)
-
- result = Yedit.add_entry(self.yaml_dict, key, value)
- if not result:
- return (False, self.yaml_dict)
-
- return (True, self.yaml_dict)
-
- def create(self, key, value):
- ''' create a yaml file '''
- if not self.exists():
- self.yaml_dict = {key: value}
- return (True, self.yaml_dict)
-
- return (False, self.yaml_dict)
-
-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.openshift_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.openshift_cmd(cmd, output=True)
-
-
-
-# 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()