From ea33e223e34bb2b8efae6b165f3ac9729357cb46 Mon Sep 17 00:00:00 2001 From: Kenny Woodson Date: Fri, 13 Jan 2017 14:29:48 -0500 Subject: Adding oc_edit module to lib_openshift. --- roles/lib_openshift/src/ansible/oc_edit.py | 48 +++++++++ roles/lib_openshift/src/class/oc_edit.py | 94 +++++++++++++++++ roles/lib_openshift/src/class/oc_route.py | 1 + roles/lib_openshift/src/doc/edit | 116 +++++++++++++++++++++ roles/lib_openshift/src/doc/route | 6 +- roles/lib_openshift/src/generate.py | 3 +- roles/lib_openshift/src/generate_sources.yml | 10 -- roles/lib_openshift/src/lib/base.py | 66 ++++++------ roles/lib_openshift/src/lib/import.py | 5 +- roles/lib_openshift/src/lib/route.py | 1 + roles/lib_openshift/src/sources.yml | 18 ++++ roles/lib_openshift/src/test/integration/route.yml | 58 +++++++++++ 12 files changed, 376 insertions(+), 50 deletions(-) create mode 100644 roles/lib_openshift/src/ansible/oc_edit.py create mode 100644 roles/lib_openshift/src/class/oc_edit.py create mode 100644 roles/lib_openshift/src/doc/edit delete mode 100644 roles/lib_openshift/src/generate_sources.yml create mode 100644 roles/lib_openshift/src/sources.yml create mode 100644 roles/lib_openshift/src/test/integration/route.yml (limited to 'roles/lib_openshift/src') diff --git a/roles/lib_openshift/src/ansible/oc_edit.py b/roles/lib_openshift/src/ansible/oc_edit.py new file mode 100644 index 000000000..5c5954747 --- /dev/null +++ b/roles/lib_openshift/src/ansible/oc_edit.py @@ -0,0 +1,48 @@ +# pylint: skip-file +# flake8: noqa + + +def main(): + ''' + ansible oc module for editing objects + ''' + + 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', + 'rc', 'replicationcontroller', + 'svc', 'service', + 'scc', 'securitycontextconstraints', + 'ns', 'namespace', 'project', 'projects', + 'is', 'imagestream', + 'istag', 'imagestreamtag', + 'bc', 'buildconfig', + 'routes', + 'node', + 'secret', + 'pv', 'persistentvolume']), + 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'), + separator=dict(default='.', type='str'), + ), + supports_check_mode=True, + ) + + rval = Edit.run_ansible(module.params, module.check_mode) + if 'failed' in rval: + module.fail_json(**rval) + + module.exit_json(**rval) + +if __name__ == '__main__': + main() diff --git a/roles/lib_openshift/src/class/oc_edit.py b/roles/lib_openshift/src/class/oc_edit.py new file mode 100644 index 000000000..0734e2085 --- /dev/null +++ b/roles/lib_openshift/src/class/oc_edit.py @@ -0,0 +1,94 @@ +# pylint: skip-file +# flake8: noqa + +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', + separator='.', + 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.separator = separator + 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(filename=file_name, content=data, separator=self.separator) + 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, sep=self.separator) + + @staticmethod + def run_ansible(params, check_mode): + '''run the ansible idempotent code''' + + ocedit = Edit(params['kind'], + params['namespace'], + params['name'], + kubeconfig=params['kubeconfig'], + separator=params['separator'], + verbose=params['debug']) + + api_rval = ocedit.get() + + ######## + # Create + ######## + if not Utils.exists(api_rval['results'], params['name']): + return {"failed": True, 'msg': api_rval} + + ######## + # Update + ######## + if check_mode: + return {'changed': True, 'msg': 'CHECK_MODE: Would have performed edit'} + + api_rval = ocedit.update(params['file_name'], + params['content'], + params['force'], + params['file_format']) + + if api_rval['returncode'] != 0: + return {"failed": True, 'msg': api_rval} + + if 'updated' in api_rval and not api_rval['updated']: + return {"changed": False, 'results': api_rval, 'state': 'present'} + + # return the created object + api_rval = ocedit.get() + + if api_rval['returncode'] != 0: + return {"failed": True, 'msg': api_rval} + + return {"changed": True, 'results': api_rval, 'state': 'present'} diff --git a/roles/lib_openshift/src/class/oc_route.py b/roles/lib_openshift/src/class/oc_route.py index f0cfa5820..05b1be409 100644 --- a/roles/lib_openshift/src/class/oc_route.py +++ b/roles/lib_openshift/src/class/oc_route.py @@ -64,6 +64,7 @@ class OCRoute(OpenShiftCLI): skip = [] return not Utils.check_def_equal(self.config.data, self.route.yaml_dict, skip_keys=skip, debug=True) + # pylint: disable=too-many-return-statements,too-many-branches @staticmethod def run_ansible(params, files, check_mode=False): ''' run the idempotent asnible code diff --git a/roles/lib_openshift/src/doc/edit b/roles/lib_openshift/src/doc/edit new file mode 100644 index 000000000..212d88f65 --- /dev/null +++ b/roles/lib_openshift/src/doc/edit @@ -0,0 +1,116 @@ +# flake8: noqa +# pylint: skip-file + +DOCUMENTATION = ''' +--- +module: oc_edit +short_description: Modify, and idempotently manage openshift objects. +description: + - Modify openshift objects programmatically. +options: + state: + description: + - Currently present is only supported state. + required: true + default: present + choices: ["present"] + aliases: [] + kubeconfig: + description: + - The path for the kubeconfig file to use for authentication + required: false + default: /etc/origin/master/admin.kubeconfig + aliases: [] + debug: + description: + - Turn on debug output. + required: false + default: False + aliases: [] + name: + description: + - Name of the object that is being queried. + required: false + default: None + aliases: [] + namespace: + description: + - The namespace where the object lives. + required: false + default: str + aliases: [] + kind: + description: + - The kind attribute of the object. + required: True + default: None + choices: + - bc + - buildconfig + - configmaps + - dc + - deploymentconfig + - imagestream + - imagestreamtag + - is + - istag + - namespace + - project + - projects + - node + - ns + - persistentvolume + - pv + - rc + - replicationcontroller + - routes + - scc + - secret + - securitycontextconstraints + - service + - svc + aliases: [] + file_name: + description: + - The file name in which to edit + required: false + default: None + aliases: [] + file_format: + description: + - The format of the file being edited. + required: false + default: yaml + aliases: [] + content: + description: + - Content of the file + required: false + default: None + aliases: [] + force: + description: + - Whether or not to force the operation + required: false + default: None + aliases: [] + separator: + description: + - The separator format for the edit. + required: false + default: '.' + aliases: [] +author: +- "Kenny Woodson " +extends_documentation_fragment: [] +''' + +EXAMPLES = ''' +oc_edit: + kind: rc + name: hawkular-cassandra-rc + namespace: openshift-infra + content: + spec.template.spec.containers[0].resources.limits.memory: 512 + spec.template.spec.containers[0].resources.requests.memory: 256 +''' diff --git a/roles/lib_openshift/src/doc/route b/roles/lib_openshift/src/doc/route index 256f6b8f3..1797d4d33 100644 --- a/roles/lib_openshift/src/doc/route +++ b/roles/lib_openshift/src/doc/route @@ -3,10 +3,10 @@ DOCUMENTATION = ''' --- -module: yedit -short_description: Create, modify, and idempotently manage yaml files. +module: oc_route +short_description: Create, modify, and idempotently manage openshift routes. description: - - Modify yaml files programmatically. + - Manage openshift route objects programmatically. options: state: description: diff --git a/roles/lib_openshift/src/generate.py b/roles/lib_openshift/src/generate.py index f4b46aa91..003136833 100755 --- a/roles/lib_openshift/src/generate.py +++ b/roles/lib_openshift/src/generate.py @@ -9,6 +9,7 @@ import yaml # pylint: disable=anomalous-backslash-in-string GEN_STR = "#!/usr/bin/env python\n" + \ "# pylint: disable=missing-docstring\n" + \ + "# flake8: noqa: T001\n" + \ "# ___ ___ _ _ ___ ___ _ _____ ___ ___\n" + \ "# / __| __| \| | __| _ \ /_\_ _| __| \\\n" + \ "# | (_ | _|| .` | _|| / / _ \| | | _|| |) |\n" + \ @@ -18,7 +19,7 @@ GEN_STR = "#!/usr/bin/env python\n" + \ "# |___/ \___/ |_|\_|\___/ |_| |___|___/___| |_|\n" OPENSHIFT_ANSIBLE_PATH = os.path.dirname(os.path.realpath(__file__)) -OPENSHIFT_ANSIBLE_SOURCES_PATH = os.path.join(OPENSHIFT_ANSIBLE_PATH, 'generate_sources.yml') # noqa: E501 +OPENSHIFT_ANSIBLE_SOURCES_PATH = os.path.join(OPENSHIFT_ANSIBLE_PATH, 'sources.yml') # noqa: E501 def main(): diff --git a/roles/lib_openshift/src/generate_sources.yml b/roles/lib_openshift/src/generate_sources.yml deleted file mode 100644 index d8fcc6141..000000000 --- a/roles/lib_openshift/src/generate_sources.yml +++ /dev/null @@ -1,10 +0,0 @@ ---- -oc_route.py: -- doc/license -- lib/import.py -- doc/route -- lib/base.py -- ../../lib_utils/src/class/yedit.py -- lib/route.py -- class/oc_route.py -- ansible/oc_route.py diff --git a/roles/lib_openshift/src/lib/base.py b/roles/lib_openshift/src/lib/base.py index 9830150be..4e9aa4461 100644 --- a/roles/lib_openshift/src/lib/base.py +++ b/roles/lib_openshift/src/lib/base.py @@ -1,9 +1,7 @@ # pylint: skip-file # flake8: noqa -''' - OpenShiftCLI class that wraps the oc commands in a subprocess -''' # pylint: disable=too-many-lines +# noqa: E301,E302,E303,T001 class OpenShiftCLIError(Exception): @@ -213,7 +211,7 @@ class OpenShiftCLI(object): err = None if self.verbose: - print ' '.join(cmds) + print(' '.join(cmds)) proc = subprocess.Popen(cmds, stdin=subprocess.PIPE, @@ -232,14 +230,14 @@ class OpenShiftCLI(object): try: rval['results'] = json.loads(stdout) except ValueError as err: - if "No JSON object could be decoded" in err.message: - err = err.message + if "No JSON object could be decoded" in str(err): + err = str(err) elif output_type == 'raw': rval['results'] = stdout if self.verbose: - print stdout - print stderr + print(stdout) + print(stderr) if err: rval.update({"err": err, @@ -350,50 +348,50 @@ class Utils(object): if isinstance(value, list): if key not in user_def: if debug: - print 'User data does not have key [%s]' % key - print 'User data: %s' % user_def + print('User data does not have key [%s]' % key) + print('User data: %s' % user_def) return False if not isinstance(user_def[key], list): if debug: - print 'user_def[key] is not a list key=[%s] user_def[key]=%s' % (key, user_def[key]) + print('user_def[key] is not a list key=[%s] user_def[key]=%s' % (key, user_def[key])) return False if len(user_def[key]) != len(value): if debug: - print "List lengths are not equal." - print "key=[%s]: user_def[%s] != value[%s]" % (key, len(user_def[key]), len(value)) - print "user_def: %s" % user_def[key] - print "value: %s" % value + print("List lengths are not equal.") + print("key=[%s]: user_def[%s] != value[%s]" % (key, len(user_def[key]), len(value))) + print("user_def: %s" % user_def[key]) + print("value: %s" % value) 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]) + 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' + 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] + print('value should be identical') + print(value) + print(user_def[key]) return False # recurse on a dictionary elif isinstance(value, dict): if key not in user_def: if debug: - print "user_def does not have key [%s]" % key + print("user_def does not have key [%s]" % key) return False if not isinstance(user_def[key], dict): if debug: - print "dict returned false: not instance of dict" + print("dict returned false: not instance of dict") return False # before passing ensure keys match @@ -401,31 +399,31 @@ class Utils(object): user_values = set(user_def[key].keys()) - set(skip) if api_values != user_values: if debug: - print "keys are not equal in dict" - print api_values - print user_values + print("keys are not equal in dict") + print(api_values) + print(user_values) 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 + print("dict returned false") + print(result) return False # Verify each key, value pair is the same else: if key not in user_def or value != user_def[key]: if debug: - print "value not equal; user_def does not have key" - print key - print value + print("value not equal; user_def does not have key") + print(key) + print(value) if key in user_def: - print user_def[key] + print(user_def[key]) return False if debug: - print 'returning true' + print('returning true') return True diff --git a/roles/lib_openshift/src/lib/import.py b/roles/lib_openshift/src/lib/import.py index 1fc75f466..c2b30e019 100644 --- a/roles/lib_openshift/src/lib/import.py +++ b/roles/lib_openshift/src/lib/import.py @@ -5,12 +5,13 @@ ''' # pylint: disable=too-many-lines - +from __future__ import print_function import atexit import json import os import re -import ruamel.yaml as yaml import shutil import subprocess +# pylint: disable=import-error +import ruamel.yaml as yaml from ansible.module_utils.basic import AnsibleModule diff --git a/roles/lib_openshift/src/lib/route.py b/roles/lib_openshift/src/lib/route.py index 11dc1dfbf..df062b0dd 100644 --- a/roles/lib_openshift/src/lib/route.py +++ b/roles/lib_openshift/src/lib/route.py @@ -1,5 +1,6 @@ # pylint: skip-file # flake8: noqa +# noqa: E302,E301 # pylint: disable=too-many-instance-attributes diff --git a/roles/lib_openshift/src/sources.yml b/roles/lib_openshift/src/sources.yml new file mode 100644 index 000000000..945d4d13f --- /dev/null +++ b/roles/lib_openshift/src/sources.yml @@ -0,0 +1,18 @@ +--- +oc_route.py: +- doc/license +- lib/import.py +- doc/route +- ../../lib_utils/src/class/yedit.py +- lib/base.py +- lib/route.py +- class/oc_route.py +- ansible/oc_route.py +oc_edit.py: +- doc/license +- lib/import.py +- doc/edit +- ../../lib_utils/src/class/yedit.py +- lib/base.py +- class/oc_edit.py +- ansible/oc_edit.py diff --git a/roles/lib_openshift/src/test/integration/route.yml b/roles/lib_openshift/src/test/integration/route.yml new file mode 100644 index 000000000..6a96b334f --- /dev/null +++ b/roles/lib_openshift/src/test/integration/route.yml @@ -0,0 +1,58 @@ +#!/usr/bin/ansible-playbook +# ./route.yml -M ../../../library -e "cli_master_test=$OPENSHIFT_MASTER +--- +- hosts: "{{ cli_master_test }}" + gather_facts: no + user: root + tasks: + - name: create route + oc_route: + name: test + namespace: test + tls_termination: edge + cert_content: testing cert + cacert_content: testing cacert + service_name: test + host: test.example + register: routeout + - debug: var=routeout + + - name: get route + oc_route: + state: list + name: test + namespace: default + register: routeout + - debug: var=routeout + + - name: delete route + oc_route: + state: absent + name: test + namespace: default + register: routeout + - debug: var=routeout + + - name: create route + oc_route: + name: test + namespace: test + tls_termination: edge + cert_content: testing cert + cacert_content: testing cacert + service_name: test + host: test.example + register: routeout + - debug: var=routeout + + - name: create route noop + oc_route: + name: test + namespace: test + tls_termination: edge + cert_content: testing cert + cacert_content: testing cacert + service_name: test + host: test.example + register: routeout + - debug: var=routeout -- cgit v1.2.3