From 486ac1556b93ab7e7ef91b273659f7847bbd704d Mon Sep 17 00:00:00 2001 From: Ivan Horvath Date: Tue, 24 Jan 2017 10:43:05 -0500 Subject: oc process --- roles/lib_openshift/src/ansible/oc_process.py | 33 +++++ roles/lib_openshift/src/class/oc_process.py | 182 ++++++++++++++++++++++++++ roles/lib_openshift/src/doc/process | 81 ++++++++++++ roles/lib_openshift/src/sources.yml | 10 ++ 4 files changed, 306 insertions(+) create mode 100644 roles/lib_openshift/src/ansible/oc_process.py create mode 100644 roles/lib_openshift/src/class/oc_process.py create mode 100644 roles/lib_openshift/src/doc/process (limited to 'roles/lib_openshift/src') diff --git a/roles/lib_openshift/src/ansible/oc_process.py b/roles/lib_openshift/src/ansible/oc_process.py new file mode 100644 index 000000000..b01c6aa86 --- /dev/null +++ b/roles/lib_openshift/src/ansible/oc_process.py @@ -0,0 +1,33 @@ +# pylint: skip-file +# flake8: noqa + + +def main(): + ''' + ansible oc module for processing templates + ''' + + module = AnsibleModule( + argument_spec=dict( + kubeconfig=dict(default='/etc/origin/master/admin.kubeconfig', type='str'), + state=dict(default='present', type='str', choices=['present', 'list']), + debug=dict(default=False, type='bool'), + namespace=dict(default='default', type='str'), + template_name=dict(default=None, type='str'), + content=dict(default=None, type='str'), + params=dict(default=None, type='dict'), + create=dict(default=False, type='bool'), + reconcile=dict(default=True, type='bool'), + ), + supports_check_mode=True, + ) + + + rval = Process.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_process.py b/roles/lib_openshift/src/class/oc_process.py new file mode 100644 index 000000000..7cc8ff082 --- /dev/null +++ b/roles/lib_openshift/src/class/oc_process.py @@ -0,0 +1,182 @@ +# pylint: skip-file + +# pylint: disable=too-many-instance-attributes +class Process(OpenShiftCLI): + ''' Class to wrap the oc command line tools ''' + + # pylint allows 5. we need 6 + # pylint: disable=too-many-arguments + def __init__(self, + namespace, + tname=None, + params=None, + create=False, + kubeconfig='/etc/origin/master/admin.kubeconfig', + tdata=None, + verbose=False): + ''' Constructor for OpenshiftOC ''' + super(Process, self).__init__(namespace, kubeconfig) + self.namespace = namespace + self.name = tname + self.data = tdata + self.params = params + self.create = create + self.kubeconfig = kubeconfig + self.verbose = verbose + self._template = None + + @property + def template(self): + '''template property''' + if self._template == None: + results = self._process(self.name, False, self.params, self.data) + if results['returncode'] != 0: + raise OpenShiftCLIError('Error processing template [%s].' % self.name) + self._template = results['results']['items'] + + return self._template + + def get(self): + '''get the template''' + results = self._get('template', self.name) + if results['returncode'] != 0: + # Does the template exist?? + if 'not found' in results['stderr']: + results['returncode'] = 0 + results['exists'] = False + results['results'] = [] + + return results + + def delete(self, obj): + '''delete a resource''' + return self._delete(obj['kind'], obj['metadata']['name']) + + def create_obj(self, obj): + '''create a resource''' + return self._create_from_content(obj['metadata']['name'], obj) + + def process(self, create=None): + '''process a template''' + do_create = False + if create != None: + do_create = create + else: + do_create = self.create + + return self._process(self.name, do_create, self.params, self.data) + + def exists(self): + '''return whether the template exists''' + # Always return true if we're being passed template data + if self.data: + return True + t_results = self._get('template', self.name) + + if t_results['returncode'] != 0: + # Does the template exist?? + if 'not found' in t_results['stderr']: + return False + else: + raise OpenShiftCLIError('Something went wrong. %s' % t_results) + + return True + + def needs_update(self): + '''attempt to process the template and return it for comparison with oc objects''' + obj_results = [] + for obj in self.template: + + # build a list of types to skip + skip = [] + + if obj['kind'] == 'ServiceAccount': + skip.extend(['secrets', 'imagePullSecrets']) + if obj['kind'] == 'BuildConfig': + skip.extend(['lastTriggeredImageID']) + if obj['kind'] == 'ImageStream': + skip.extend(['generation']) + if obj['kind'] == 'DeploymentConfig': + skip.extend(['lastTriggeredImage']) + + # fetch the current object + curr_obj_results = self._get(obj['kind'], obj['metadata']['name']) + if curr_obj_results['returncode'] != 0: + # Does the template exist?? + if 'not found' in curr_obj_results['stderr']: + obj_results.append((obj, True)) + continue + + # check the generated object against the existing object + if not Utils.check_def_equal(obj, curr_obj_results['results'][0], skip_keys=skip): + obj_results.append((obj, True)) + continue + + obj_results.append((obj, False)) + + return obj_results + + + @staticmethod + def run_ansible(params, check_mode): + '''run the ansible idempotent code''' + + ocprocess = Process(params['namespace'], + params['template_name'], + params['params'], + params['create'], + kubeconfig=params['kubeconfig'], + tdata=params['content'], + verbose=params['debug']) + + state = params['state'] + + api_rval = ocprocess.get() + + if state == 'list': + if api_rval['returncode'] != 0: + return {"failed": True, "msg" : api_rval} + + return {"changed" : False, "results": api_rval, "state": "list") + + elif state == 'present': + if not ocprocess.exists() or not params['reconcile']: + #FIXME: this code will never get run in a way that succeeds when + # module.params['reconcile'] is true. Because oc_process doesn't + # create the actual template, the check of ocprocess.exists() + # is meaningless. Either it's already here and this code + # won't be run, or this code will fail because there is no + # template available for oc process to use. Have we conflated + # the template's existence with the existence of the objects + # it describes? + + + # Create it here + api_rval = ocprocess.process() + if api_rval['returncode'] != 0: + return {"failed": True, "msg": api_rval} + + return {"changed": True, "results": api_rval, "state": "present") + + # verify results + update = False + rval = [] + all_results = ocprocess.needs_update() + for obj, status in all_results: + if status: + ocprocess.delete(obj) + results = ocprocess.create_obj(obj) + results['kind'] = obj['kind'] + rval.append(results) + update = True + + if not update: + return {"changed": update, "results": api_rval, "state": "present") + + for cmd in rval: + if cmd['returncode'] != 0: + return {"failed": True, "changed": update, "results": rval, "state": "present") + + return {"changed": update, "results": rval, "state": "present"} + + return {"failed": True, "changed": False, "results": 'Unknown state passed ({0}). '.format(state), "state": "unknown") diff --git a/roles/lib_openshift/src/doc/process b/roles/lib_openshift/src/doc/process new file mode 100644 index 000000000..46986f8de --- /dev/null +++ b/roles/lib_openshift/src/doc/process @@ -0,0 +1,81 @@ +# flake8: noqa +# pylint: skip-file + +DOCUMENTATION = ''' +--- +module: oc_process +short_description: Module to process openshift templates +description: + - Process openshift templates programmatically. +options: + state: + description: + - Currently present is only supported state. + required: true + default: present + choices: ["present", "absent", "list"] + 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: [] + template_name: + description: + - Name of the template that is being processed. + required: false + default: None + aliases: [] + namespace: + description: + - The namespace where the object lives. + required: false + default: str + aliases: [] + content: + description: + - Template content to be processed. + required: false + default: None + aliases: [] + params: + description: + - A list of parameters that will be inserted into the template. + required: false + default: None + aliases: [] + create: + description: + - Whether or not to create the template after being processed. e.q oc process | oc create -f - + required: false + default: None + aliases: [] + reconcile: + description: + - Whether or not to attempt to determine if there are updates or changes in the incoming template. + required: false + default: true + aliases: [] +author: +- "Kenny Woodson " +extends_documentation_fragment: [] +''' +EXAMPLES = ''' +- name: process the cloud volume provisioner template with variables + oc_process: + namespace: openshift-infra + template_name: online-volume-provisioner + create: True + params: + PLAT: rhel7 + register: processout + run_once: true +- debug: var=processout +''' diff --git a/roles/lib_openshift/src/sources.yml b/roles/lib_openshift/src/sources.yml index aa02ce120..e9056655d 100644 --- a/roles/lib_openshift/src/sources.yml +++ b/roles/lib_openshift/src/sources.yml @@ -39,6 +39,16 @@ oc_obj.py: - class/oc_obj.py - ansible/oc_obj.py +oc_process.py: +- doc/generated +- doc/license +- lib/import.py +- doc/process +- ../../lib_utils/src/class/yedit.py +- lib/base.py +- class/oc_process.py +- ansible/oc_process.py + oc_route.py: - doc/generated - doc/license -- cgit v1.2.3 From 63b7227d33933df83cb33a5b1a20270fa487b58d Mon Sep 17 00:00:00 2001 From: Kenny Woodson Date: Wed, 1 Feb 2017 12:25:59 -0500 Subject: Fixing docs. --- roles/lib_openshift/src/class/oc_process.py | 8 ++++++-- roles/lib_openshift/src/doc/process | 11 +++++------ 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'roles/lib_openshift/src') diff --git a/roles/lib_openshift/src/class/oc_process.py b/roles/lib_openshift/src/class/oc_process.py index 7cc8ff082..d8e5015ed 100644 --- a/roles/lib_openshift/src/class/oc_process.py +++ b/roles/lib_openshift/src/class/oc_process.py @@ -1,4 +1,6 @@ # pylint: skip-file +# flake8: noqa + # pylint: disable=too-many-instance-attributes class Process(OpenShiftCLI): @@ -150,7 +152,6 @@ class Process(OpenShiftCLI): # the template's existence with the existence of the objects # it describes? - # Create it here api_rval = ocprocess.process() if api_rval['returncode'] != 0: @@ -179,4 +180,7 @@ class Process(OpenShiftCLI): return {"changed": update, "results": rval, "state": "present"} - return {"failed": True, "changed": False, "results": 'Unknown state passed ({0}). '.format(state), "state": "unknown") + return {"failed": True, + "changed": False, + "results": 'Unknown state passed ({0}). '.format(state), + "state": "unknown") diff --git a/roles/lib_openshift/src/doc/process b/roles/lib_openshift/src/doc/process index 46986f8de..2322bf49c 100644 --- a/roles/lib_openshift/src/doc/process +++ b/roles/lib_openshift/src/doc/process @@ -11,7 +11,6 @@ options: state: description: - Currently present is only supported state. - required: true default: present choices: ["present", "absent", "list"] aliases: [] @@ -29,19 +28,19 @@ options: aliases: [] template_name: description: - - Name of the template that is being processed. + - Name of the openshift template that is being processed. required: false default: None aliases: [] namespace: description: - - The namespace where the object lives. + - The namespace where the template lives. required: false - default: str + default: default aliases: [] content: description: - - Template content to be processed. + - Template content that will be processed. required: false default: None aliases: [] @@ -60,13 +59,13 @@ options: reconcile: description: - Whether or not to attempt to determine if there are updates or changes in the incoming template. - required: false default: true aliases: [] author: - "Kenny Woodson " extends_documentation_fragment: [] ''' + EXAMPLES = ''' - name: process the cloud volume provisioner template with variables oc_process: -- cgit v1.2.3 From 353a24669e7116b40a9c85367277d19040eb75ea Mon Sep 17 00:00:00 2001 From: Kenny Woodson Date: Thu, 2 Feb 2017 12:39:13 -0500 Subject: Adding test cases. --- roles/lib_openshift/src/ansible/oc_process.py | 2 +- roles/lib_openshift/src/class/oc_process.py | 21 +- .../src/test/integration/oc_process.yml | 83 ++++ roles/lib_openshift/src/test/unit/oc_process.py | 473 +++++++++++++++++++++ 4 files changed, 567 insertions(+), 12 deletions(-) create mode 100755 roles/lib_openshift/src/test/integration/oc_process.yml create mode 100755 roles/lib_openshift/src/test/unit/oc_process.py (limited to 'roles/lib_openshift/src') diff --git a/roles/lib_openshift/src/ansible/oc_process.py b/roles/lib_openshift/src/ansible/oc_process.py index b01c6aa86..5faa46aef 100644 --- a/roles/lib_openshift/src/ansible/oc_process.py +++ b/roles/lib_openshift/src/ansible/oc_process.py @@ -23,7 +23,7 @@ def main(): ) - rval = Process.run_ansible(module.params, module.check_mode) + rval = OCProcess.run_ansible(module.params, module.check_mode) if 'failed' in rval: module.fail_json(**rval) diff --git a/roles/lib_openshift/src/class/oc_process.py b/roles/lib_openshift/src/class/oc_process.py index d8e5015ed..6cb5ec8c9 100644 --- a/roles/lib_openshift/src/class/oc_process.py +++ b/roles/lib_openshift/src/class/oc_process.py @@ -3,7 +3,7 @@ # pylint: disable=too-many-instance-attributes -class Process(OpenShiftCLI): +class OCProcess(OpenShiftCLI): ''' Class to wrap the oc command line tools ''' # pylint allows 5. we need 6 @@ -17,7 +17,7 @@ class Process(OpenShiftCLI): tdata=None, verbose=False): ''' Constructor for OpenshiftOC ''' - super(Process, self).__init__(namespace, kubeconfig) + super(OCProcess, self).__init__(namespace, kubeconfig) self.namespace = namespace self.name = tname self.data = tdata @@ -123,7 +123,7 @@ class Process(OpenShiftCLI): def run_ansible(params, check_mode): '''run the ansible idempotent code''' - ocprocess = Process(params['namespace'], + ocprocess = OCProcess(params['namespace'], params['template_name'], params['params'], params['create'], @@ -139,7 +139,7 @@ class Process(OpenShiftCLI): if api_rval['returncode'] != 0: return {"failed": True, "msg" : api_rval} - return {"changed" : False, "results": api_rval, "state": "list") + return {"changed" : False, "results": api_rval, "state": "list"} elif state == 'present': if not ocprocess.exists() or not params['reconcile']: @@ -157,7 +157,10 @@ class Process(OpenShiftCLI): if api_rval['returncode'] != 0: return {"failed": True, "msg": api_rval} - return {"changed": True, "results": api_rval, "state": "present") + if params['create']: + return {"changed": True, "results": api_rval, "state": "present"} + + return {"changed": False, "results": api_rval, "state": "present"} # verify results update = False @@ -172,15 +175,11 @@ class Process(OpenShiftCLI): update = True if not update: - return {"changed": update, "results": api_rval, "state": "present") + return {"changed": update, "results": api_rval, "state": "present"} for cmd in rval: if cmd['returncode'] != 0: - return {"failed": True, "changed": update, "results": rval, "state": "present") + return {"failed": True, "changed": update, "results": rval, "state": "present"} return {"changed": update, "results": rval, "state": "present"} - return {"failed": True, - "changed": False, - "results": 'Unknown state passed ({0}). '.format(state), - "state": "unknown") diff --git a/roles/lib_openshift/src/test/integration/oc_process.yml b/roles/lib_openshift/src/test/integration/oc_process.yml new file mode 100755 index 000000000..7ea4c6b99 --- /dev/null +++ b/roles/lib_openshift/src/test/integration/oc_process.yml @@ -0,0 +1,83 @@ +#!/usr/bin/ansible-playbook --module-path=../../../library/:../../../../lib_utils/library + +--- +- hosts: "{{ cli_master_test }}" + gather_facts: no + user: root + vars: + template_name: mysql-ephemeral + ns_name: test + + post_tasks: + - name: get the mysql-ephemeral template + oc_obj: + name: mysql-ephemeral + state: list + namespace: openshift + kind: template + register: mysqltempl + + - name: fix namespace + yedit: + src: /tmp/mysql-template + key: metadata.namespace + value: test + backup: false + content: "{{ mysqltempl.results.results[0] | to_yaml }}" + + - name: create the test namespace + oc_obj: + name: test + state: present + namespace: test + kind: namespace + content: + path: /tmp/ns_test + data: + apiVersion: v1 + kind: Namespace + metadata: + name: test + spec: + finalizers: + - openshift.io/origin + - kubernetes + register: mysqltempl + + - name: create the mysql-ephemeral template + oc_obj: + name: mysql-ephemeral + state: present + namespace: test + kind: template + files: + - /tmp/mysql-template + delete_after: True + register: mysqltempl + + - name: process mysql-ephemeral + oc_process: + template_name: mysql-ephemeral + namespace: test + params: + NAMESPACE: test + DATABASE_SERVICE_NAME: testdb + create: False + reconcile: false + register: procout + + - assert: + that: + - not procout.changed + - procout.results.results['items'][0]['metadata']['name'] == 'testdb' + - procout.results.results['items'][0]['kind'] == 'Service' + - procout.results.results['items'][1]['metadata']['name'] == 'testdb' + - procout.results.results['items'][1]['kind'] == 'DeploymentConfig' + msg: process failed on template + + - name: remove namespace test + oc_obj: + kind: namespace + name: test + namespace: test + state: absent diff --git a/roles/lib_openshift/src/test/unit/oc_process.py b/roles/lib_openshift/src/test/unit/oc_process.py new file mode 100755 index 000000000..c0cf625cc --- /dev/null +++ b/roles/lib_openshift/src/test/unit/oc_process.py @@ -0,0 +1,473 @@ +#!/usr/bin/env python2 +''' + Unit tests for oc process +''' +# To run +# python -m unittest version +# +# . +# Ran 1 test in 0.597s +# +# OK + +import os +import sys +import unittest +import mock + +# Removing invalid variable names for tests so that I can +# keep them brief +# pylint: disable=invalid-name,no-name-in-module +# Disable import-error b/c our libraries aren't loaded in jenkins +# pylint: disable=import-error +# place class in our python path +module_path = os.path.join('/'.join(os.path.realpath(__file__).split('/')[:-4]), 'library') # noqa: E501 +sys.path.insert(0, module_path) +from oc_process import OCProcess # noqa: E402 + + +# pylint: disable=too-many-public-methods +class OCProcessTest(unittest.TestCase): + ''' + Test class for OCProcess + ''' + mysql = '''{ + "kind": "Template", + "apiVersion": "v1", + "metadata": { + "name": "mysql-ephemeral", + "namespace": "openshift", + "selfLink": "/oapi/v1/namespaces/openshift/templates/mysql-ephemeral", + "uid": "fb8b5f04-e3d3-11e6-a982-0e84250fc302", + "resourceVersion": "480", + "creationTimestamp": "2017-01-26T14:30:27Z", + "annotations": { + "iconClass": "icon-mysql-database", + "openshift.io/display-name": "MySQL (Ephemeral)", + "tags": "database,mysql" + } + }, + "objects": [ + { + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "creationTimestamp": null, + "name": "${DATABASE_SERVICE_NAME}" + }, + "spec": { + "ports": [ + { + "name": "mysql", + "nodePort": 0, + "port": 3306, + "protocol": "TCP", + "targetPort": 3306 + } + ], + "selector": { + "name": "${DATABASE_SERVICE_NAME}" + }, + "sessionAffinity": "None", + "type": "ClusterIP" + }, + "status": { + "loadBalancer": {} + } + }, + { + "apiVersion": "v1", + "kind": "DeploymentConfig", + "metadata": { + "creationTimestamp": null, + "name": "${DATABASE_SERVICE_NAME}" + }, + "spec": { + "replicas": 1, + "selector": { + "name": "${DATABASE_SERVICE_NAME}" + }, + "strategy": { + "type": "Recreate" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "name": "${DATABASE_SERVICE_NAME}" + } + }, + "spec": { + "containers": [ + { + "capabilities": {}, + "env": [ + { + "name": "MYSQL_USER", + "value": "${MYSQL_USER}" + }, + { + "name": "MYSQL_PASSWORD", + "value": "${MYSQL_PASSWORD}" + }, + { + "name": "MYSQL_DATABASE", + "value": "${MYSQL_DATABASE}" + } + ], + "image": " ", + "imagePullPolicy": "IfNotPresent", + "livenessProbe": { + "initialDelaySeconds": 30, + "tcpSocket": { + "port": 3306 + }, + "timeoutSeconds": 1 + }, + "name": "mysql", + "ports": [ + { + "containerPort": 3306, + "protocol": "TCP" + } + ], + "readinessProbe": { + "exec": { + "command": [ + "/bin/sh", + "-i", + "-c", + "MYSQL_PWD=$MYSQL_PASSWORD mysql -h 127.0.0.1 -u $MYSQL_USER -D $MYSQL_DATABASE -e 'SELECT 1'" + ] + }, + "initialDelaySeconds": 5, + "timeoutSeconds": 1 + }, + "resources": { + "limits": { + "memory": "${MEMORY_LIMIT}" + } + }, + "securityContext": { + "capabilities": {}, + "privileged": false + }, + "terminationMessagePath": "/dev/termination-log", + "volumeMounts": [ + { + "mountPath": "/var/lib/mysql/data", + "name": "${DATABASE_SERVICE_NAME}-data" + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "volumes": [ + { + "emptyDir": { + "medium": "" + }, + "name": "${DATABASE_SERVICE_NAME}-data" + } + ] + } + }, + "triggers": [ + { + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "mysql" + ], + "from": { + "kind": "ImageStreamTag", + "name": "mysql:${MYSQL_VERSION}", + "namespace": "${NAMESPACE}" + }, + "lastTriggeredImage": "" + }, + "type": "ImageChange" + }, + { + "type": "ConfigChange" + } + ] + }, + "status": {} + } + ], + "parameters": [ + { + "name": "MEMORY_LIMIT", + "displayName": "Memory Limit", + "description": "Maximum amount of memory the container can use.", + "value": "512Mi" + }, + { + "name": "NAMESPACE", + "displayName": "Namespace", + "description": "The OpenShift Namespace where the ImageStream resides.", + "value": "openshift" + }, + { + "name": "DATABASE_SERVICE_NAME", + "displayName": "Database Service Name", + "description": "The name of the OpenShift Service exposed for the database.", + "value": "mysql", + "required": true + }, + { + "name": "MYSQL_USER", + "displayName": "MySQL Connection Username", + "description": "Username for MySQL user that will be used for accessing the database.", + "generate": "expression", + "from": "user[A-Z0-9]{3}", + "required": true + }, + { + "name": "MYSQL_PASSWORD", + "displayName": "MySQL Connection Password", + "description": "Password for the MySQL connection user.", + "generate": "expression", + "from": "[a-zA-Z0-9]{16}", + "required": true + }, + { + "name": "MYSQL_DATABASE", + "displayName": "MySQL Database Name", + "description": "Name of the MySQL database accessed.", + "value": "sampledb", + "required": true + }, + { + "name": "MYSQL_VERSION", + "displayName": "Version of MySQL Image", + "description": "Version of MySQL image to be used (5.5, 5.6 or latest).", + "value": "5.6", + "required": true + } + ], + "labels": { + "template": "mysql-ephemeral-template" + } +}''' + + def setUp(self): + ''' setup method will set to known configuration ''' + pass + + @mock.patch('oc_process.OCProcess._run') + def test_state_list(self, mock_cmd): + ''' Testing a get ''' + params = {'template_name': 'mysql-ephermeral', + 'namespace': 'test', + 'content': None, + 'state': 'list', + 'reconcile': False, + 'create': False, + 'params': {'NAMESPACE': 'test', 'DATABASE_SERVICE_NAME': 'testdb'}, + 'kubeconfig': '/etc/origin/master/admin.kubeconfig', + 'debug': False} + + mock_cmd.side_effect = [ + (0, OCProcessTest.mysql, '') + ] + + results = OCProcess.run_ansible(params, False) + + self.assertFalse(results['changed']) + self.assertEqual(results['results']['results'][0]['metadata']['name'], 'mysql-ephemeral') + + @mock.patch('oc_process.OCProcess._run') + def test_process_no_create(self, mock_cmd): + ''' Testing a process with no create ''' + params = {'template_name': 'mysql-ephermeral', + 'namespace': 'test', + 'content': None, + 'state': 'present', + 'reconcile': False, + 'create': False, + 'params': {'NAMESPACE': 'test', 'DATABASE_SERVICE_NAME': 'testdb'}, + 'kubeconfig': '/etc/origin/master/admin.kubeconfig', + 'debug': False} + + mysqlproc = '''{ + "kind": "List", + "apiVersion": "v1", + "metadata": {}, + "items": [ + { + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "creationTimestamp": null, + "labels": { + "template": "mysql-ephemeral-template" + }, + "name": "testdb" + }, + "spec": { + "ports": [ + { + "name": "mysql", + "nodePort": 0, + "port": 3306, + "protocol": "TCP", + "targetPort": 3306 + } + ], + "selector": { + "name": "testdb" + }, + "sessionAffinity": "None", + "type": "ClusterIP" + }, + "status": { + "loadBalancer": {} + } + }, + { + "apiVersion": "v1", + "kind": "DeploymentConfig", + "metadata": { + "creationTimestamp": null, + "labels": { + "template": "mysql-ephemeral-template" + }, + "name": "testdb" + }, + "spec": { + "replicas": 1, + "selector": { + "name": "testdb" + }, + "strategy": { + "type": "Recreate" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "name": "testdb" + } + }, + "spec": { + "containers": [ + { + "capabilities": {}, + "env": [ + { + "name": "MYSQL_USER", + "value": "userHJJ" + }, + { + "name": "MYSQL_PASSWORD", + "value": "GITOAduAMaV6k688" + }, + { + "name": "MYSQL_DATABASE", + "value": "sampledb" + } + ], + "image": " ", + "imagePullPolicy": "IfNotPresent", + "livenessProbe": { + "initialDelaySeconds": 30, + "tcpSocket": { + "port": 3306 + }, + "timeoutSeconds": 1 + }, + "name": "mysql", + "ports": [ + { + "containerPort": 3306, + "protocol": "TCP" + } + ], + "readinessProbe": { + "exec": { + "command": [ + "/bin/sh", + "-i", + "-c", + "MYSQL_PWD=$MYSQL_PASSWORD mysql -h 127.0.0.1 -u $MYSQL_USER -D $MYSQL_DATABASE -e 'SELECT 1'" + ] + }, + "initialDelaySeconds": 5, + "timeoutSeconds": 1 + }, + "resources": { + "limits": { + "memory": "512Mi" + } + }, + "securityContext": { + "capabilities": {}, + "privileged": false + }, + "terminationMessagePath": "/dev/termination-log", + "volumeMounts": [ + { + "mountPath": "/var/lib/mysql/data", + "name": "testdb-data" + } + ] + } + ], + "dnsPolicy": "ClusterFirst", + "restartPolicy": "Always", + "volumes": [ + { + "emptyDir": { + "medium": "" + }, + "name": "testdb-data" + } + ] + } + }, + "triggers": [ + { + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "mysql" + ], + "from": { + "kind": "ImageStreamTag", + "name": "mysql:5.6", + "namespace": "test" + }, + "lastTriggeredImage": "" + }, + "type": "ImageChange" + }, + { + "type": "ConfigChange" + } + ] + } + } + ] +}''' + + mock_cmd.side_effect = [ + (0, OCProcessTest.mysql, ''), + (0, OCProcessTest.mysql, ''), + (0, mysqlproc, ''), + ] + + results = OCProcess.run_ansible(params, False) + + self.assertFalse(results['changed']) + self.assertEqual(results['results']['results']['items'][0]['metadata']['name'], 'testdb') + + def tearDown(self): + '''TearDown method''' + pass + + +if __name__ == "__main__": + unittest.main() -- cgit v1.2.3 From 7a0149cf74ec76b2bbcec3b21b7cdcd9d98178cf Mon Sep 17 00:00:00 2001 From: Kenny Woodson Date: Thu, 2 Feb 2017 12:52:40 -0500 Subject: Fixing for linters. --- roles/lib_openshift/src/ansible/oc_process.py | 1 - roles/lib_openshift/src/class/oc_process.py | 19 +++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'roles/lib_openshift/src') diff --git a/roles/lib_openshift/src/ansible/oc_process.py b/roles/lib_openshift/src/ansible/oc_process.py index 5faa46aef..17cf865b7 100644 --- a/roles/lib_openshift/src/ansible/oc_process.py +++ b/roles/lib_openshift/src/ansible/oc_process.py @@ -22,7 +22,6 @@ def main(): supports_check_mode=True, ) - rval = OCProcess.run_ansible(module.params, module.check_mode) if 'failed' in rval: module.fail_json(**rval) diff --git a/roles/lib_openshift/src/class/oc_process.py b/roles/lib_openshift/src/class/oc_process.py index 6cb5ec8c9..80d81448d 100644 --- a/roles/lib_openshift/src/class/oc_process.py +++ b/roles/lib_openshift/src/class/oc_process.py @@ -30,7 +30,7 @@ class OCProcess(OpenShiftCLI): @property def template(self): '''template property''' - if self._template == None: + if self._template is None: results = self._process(self.name, False, self.params, self.data) if results['returncode'] != 0: raise OpenShiftCLIError('Error processing template [%s].' % self.name) @@ -118,18 +118,18 @@ class OCProcess(OpenShiftCLI): return obj_results - + # pylint: disable=too-many-return-statements @staticmethod def run_ansible(params, check_mode): '''run the ansible idempotent code''' ocprocess = OCProcess(params['namespace'], - params['template_name'], - params['params'], - params['create'], - kubeconfig=params['kubeconfig'], - tdata=params['content'], - verbose=params['debug']) + params['template_name'], + params['params'], + params['create'], + kubeconfig=params['kubeconfig'], + tdata=params['content'], + verbose=params['debug']) state = params['state'] @@ -142,6 +142,9 @@ class OCProcess(OpenShiftCLI): return {"changed" : False, "results": api_rval, "state": "list"} elif state == 'present': + if check_mode and params['create']: + return {"changed": True, 'msg': "CHECK_MODE: Would have processed template."} + if not ocprocess.exists() or not params['reconcile']: #FIXME: this code will never get run in a way that succeeds when # module.params['reconcile'] is true. Because oc_process doesn't -- cgit v1.2.3 From aaeba50e584426fc8f9853dd7128c861b1efe8de Mon Sep 17 00:00:00 2001 From: Kenny Woodson Date: Thu, 9 Feb 2017 10:25:41 -0500 Subject: Fixing docs. --- roles/lib_openshift/src/doc/process | 12 ++++++++---- roles/lib_openshift/src/test/unit/oc_process.py | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'roles/lib_openshift/src') diff --git a/roles/lib_openshift/src/doc/process b/roles/lib_openshift/src/doc/process index 2322bf49c..86a854c07 100644 --- a/roles/lib_openshift/src/doc/process +++ b/roles/lib_openshift/src/doc/process @@ -10,7 +10,11 @@ description: options: state: description: - - Currently present is only supported state. + - State has a few different meanings when it comes to process. + - state: present - This state runs an `oc process