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/class/oc_process.py | 182 ++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 roles/lib_openshift/src/class/oc_process.py (limited to 'roles/lib_openshift/src/class/oc_process.py') 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") -- cgit v1.2.3