diff options
Diffstat (limited to 'roles/lib_openshift/src/class')
-rw-r--r-- | roles/lib_openshift/src/class/oc_adm_ca_server_cert.py | 135 | ||||
-rw-r--r-- | roles/lib_openshift/src/class/oc_adm_registry.py | 12 | ||||
-rw-r--r-- | roles/lib_openshift/src/class/oc_adm_router.py | 46 | ||||
-rw-r--r-- | roles/lib_openshift/src/class/oc_obj.py | 1 |
4 files changed, 180 insertions, 14 deletions
diff --git a/roles/lib_openshift/src/class/oc_adm_ca_server_cert.py b/roles/lib_openshift/src/class/oc_adm_ca_server_cert.py new file mode 100644 index 000000000..6ed1f2f35 --- /dev/null +++ b/roles/lib_openshift/src/class/oc_adm_ca_server_cert.py @@ -0,0 +1,135 @@ +# pylint: skip-file +# flake8: noqa + +class CAServerCertConfig(OpenShiftCLIConfig): + ''' CAServerCertConfig is a DTO for the oc adm ca command ''' + def __init__(self, kubeconfig, verbose, ca_options): + super(CAServerCertConfig, self).__init__('ca', None, kubeconfig, ca_options) + self.kubeconfig = kubeconfig + self.verbose = verbose + self._ca = ca_options + + +class CAServerCert(OpenShiftCLI): + ''' Class to wrap the oc adm ca create-server-cert command line''' + def __init__(self, + config, + verbose=False): + ''' Constructor for oadm ca ''' + super(CAServerCert, self).__init__(None, config.kubeconfig, verbose) + self.config = config + self.verbose = verbose + + def get(self): + '''get the current cert file + + If a file exists by the same name in the specified location then the cert exists + ''' + cert = self.config.config_options['cert']['value'] + if cert and os.path.exists(cert): + return open(cert).read() + + return None + + def create(self): + '''run openshift oc adm ca create-server-cert cmd''' + + # Added this here as a safegaurd for stomping on the + # cert and key files if they exist + if self.config.config_options['backup']['value']: + import time + ext = time.strftime("%Y-%m-%d@%H:%M:%S", time.localtime(time.time())) + date_str = "%s_" + "%s" % ext + + if os.path.exists(self.config.config_options['key']['value']): + shutil.copy(self.config.config_options['key']['value'], + date_str % self.config.config_options['key']['value']) + if os.path.exists(self.config.config_options['cert']['value']): + shutil.copy(self.config.config_options['cert']['value'], + date_str % self.config.config_options['cert']['value']) + + options = self.config.to_option_list() + + cmd = ['ca', 'create-server-cert'] + cmd.extend(options) + + return self.openshift_cmd(cmd, oadm=True) + + def exists(self): + ''' check whether the certificate exists and has the clusterIP ''' + + cert_path = self.config.config_options['cert']['value'] + if not os.path.exists(cert_path): + return False + + # Would prefer pyopenssl but is not installed. + # When we verify it is, switch this code + # Here is the code to get the subject and the SAN + # openssl x509 -text -noout -certopt \ + # no_header,no_version,no_serial,no_signame,no_validity,no_issuer,no_pubkey,no_sigdump,no_aux \ + # -in /etc/origin/master/registry.crt + # Instead of this solution we will use a regex. + cert_names = [] + hostnames = self.config.config_options['hostnames']['value'].split(',') + proc = subprocess.Popen(['openssl', 'x509', '-noout', '-text', '-in', cert_path], + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + x509output, _ = proc.communicate() + if proc.returncode == 0: + regex = re.compile(r"^\s*X509v3 Subject Alternative Name:\s*?\n\s*(.*)\s*\n", re.MULTILINE) + match = regex.search(x509output) # E501 + for entry in re.split(r", *", match.group(1)): + if entry.startswith('DNS') or entry.startswith('IP Address'): + cert_names.append(entry.split(':')[1]) + # now that we have cert names let's compare + cert_set = set(cert_names) + hname_set = set(hostnames) + if cert_set.issubset(hname_set) and hname_set.issubset(cert_set): + return True + + return False + + @staticmethod + def run_ansible(params, check_mode): + '''run the idempotent ansible code''' + + config = CAServerCertConfig(params['kubeconfig'], + params['debug'], + {'cert': {'value': params['cert'], 'include': True}, + 'hostnames': {'value': ','.join(params['hostnames']), 'include': True}, + 'overwrite': {'value': True, 'include': True}, + 'key': {'value': params['key'], 'include': True}, + 'signer_cert': {'value': params['signer_cert'], 'include': True}, + 'signer_key': {'value': params['signer_key'], 'include': True}, + 'signer_serial': {'value': params['signer_serial'], 'include': True}, + 'backup': {'value': params['backup'], 'include': False}, + }) + + server_cert = CAServerCert(config) + + state = params['state'] + + if state == 'present': + ######## + # Create + ######## + if not server_cert.exists() or params['force']: + + if check_mode: + return {'changed': True, + 'msg': "CHECK_MODE: Would have created the certificate.", + 'state': state} + + api_rval = server_cert.create() + + return {'changed': True, 'results': api_rval, 'state': state} + + ######## + # Exists + ######## + api_rval = server_cert.get() + return {'changed': False, 'results': api_rval, 'state': state} + + return {'failed': True, + 'msg': 'Unknown state passed. %s' % state} + diff --git a/roles/lib_openshift/src/class/oc_adm_registry.py b/roles/lib_openshift/src/class/oc_adm_registry.py index 8cb7aea31..35b417059 100644 --- a/roles/lib_openshift/src/class/oc_adm_registry.py +++ b/roles/lib_openshift/src/class/oc_adm_registry.py @@ -154,7 +154,7 @@ class Registry(OpenShiftCLI): # probably need to parse this # pylint thinks results is a string # pylint: disable=no-member - if results['returncode'] != 0 and results['results'].has_key('items'): + if results['returncode'] != 0 and 'items' in results['results']: return results service = None @@ -232,10 +232,18 @@ class Registry(OpenShiftCLI): def add_modifications(self, deploymentconfig): ''' update a deployment config with changes ''' + # The environment variable for REGISTRY_HTTP_SECRET is autogenerated + # We should set the generated deploymentconfig to the in memory version + # the following modifications will overwrite if needed + if self.deploymentconfig: + result = self.deploymentconfig.get_env_var('REGISTRY_HTTP_SECRET') + if result: + deploymentconfig.update_env_var('REGISTRY_HTTP_SECRET', result['value']) + # Currently we know that our deployment of a registry requires a few extra modifications # Modification 1 # we need specific environment variables to be set - for key, value in self.config.config_options['env_vars']['value'].items(): + for key, value in self.config.config_options['env_vars'].get('value', {}).items(): if not deploymentconfig.exists_env_key(key): deploymentconfig.add_env_value(key, value) else: diff --git a/roles/lib_openshift/src/class/oc_adm_router.py b/roles/lib_openshift/src/class/oc_adm_router.py index 9d61cfdf2..66769e73b 100644 --- a/roles/lib_openshift/src/class/oc_adm_router.py +++ b/roles/lib_openshift/src/class/oc_adm_router.py @@ -49,8 +49,11 @@ class Router(OpenShiftCLI): ''' property for the prepared router''' if self.__prepared_router is None: results = self._prepare_router() - if not results: - raise RouterException('Could not perform router preparation') + if not results or 'returncode' in results and results['returncode'] != 0: + if 'stderr' in results: + raise RouterException('Could not perform router preparation: %s' % results['stderr']) + + raise RouterException('Could not perform router preparation.') self.__prepared_router = results return self.__prepared_router @@ -180,10 +183,14 @@ class Router(OpenShiftCLI): return deploymentconfig + # pylint: disable=too-many-branches def _prepare_router(self): '''prepare router for instantiation''' - # We need to create the pem file - if self.config.config_options['default_cert']['value'] is None: + # if cacert, key, and cert were passed, combine them into a pem file + if (self.config.config_options['cacert_file']['value'] and + self.config.config_options['cert_file']['value'] and + self.config.config_options['key_file']['value']): + router_pem = '/tmp/router.pem' with open(router_pem, 'w') as rfd: rfd.write(open(self.config.config_options['cert_file']['value']).read()) @@ -193,8 +200,13 @@ class Router(OpenShiftCLI): rfd.write(open(self.config.config_options['cacert_file']['value']).read()) atexit.register(Utils.cleanup, [router_pem]) + self.config.config_options['default_cert']['value'] = router_pem + elif self.config.config_options['default_cert']['value'] is None: + # No certificate was passed to us. do not pass one to oc adm router + self.config.config_options['default_cert']['include'] = False + options = self.config.to_option_list() cmd = ['router', self.config.name, '-n', self.config.namespace] @@ -203,8 +215,8 @@ class Router(OpenShiftCLI): results = self.openshift_cmd(cmd, oadm=True, output=True, output_type='json') - # pylint: disable=no-member - if results['returncode'] != 0 and 'items' in results['results']: + # pylint: disable=maybe-no-member + if results['returncode'] != 0 or 'items' not in results['results']: return results oc_objects = {'DeploymentConfig': {'obj': None, 'path': None, 'update': False}, @@ -235,17 +247,29 @@ class Router(OpenShiftCLI): oc_objects['DeploymentConfig']['obj'] = self.add_modifications(oc_objects['DeploymentConfig']['obj']) for oc_type, oc_data in oc_objects.items(): - oc_data['path'] = Utils.create_tmp_file_from_contents(oc_type, oc_data['obj'].yaml_dict) + if oc_data['obj'] is not None: + oc_data['path'] = Utils.create_tmp_file_from_contents(oc_type, oc_data['obj'].yaml_dict) return oc_objects def create(self): - '''Create a deploymentconfig ''' + '''Create a router + + This includes the different parts: + - deploymentconfig + - service + - serviceaccount + - secrets + - clusterrolebinding + ''' results = [] - # pylint: disable=no-member + import time + # pylint: disable=maybe-no-member for _, oc_data in self.prepared_router.items(): - results.append(self._create(oc_data['path'])) + if oc_data['obj'] is not None: + time.sleep(1) + results.append(self._create(oc_data['path'])) rval = 0 for result in results: @@ -258,7 +282,7 @@ class Router(OpenShiftCLI): '''run update for the router. This performs a replace''' results = [] - # pylint: disable=no-member + # pylint: disable=maybe-no-member for _, oc_data in self.prepared_router.items(): if oc_data['update']: results.append(self._replace(oc_data['path'])) diff --git a/roles/lib_openshift/src/class/oc_obj.py b/roles/lib_openshift/src/class/oc_obj.py index 21129a50c..51d3ce996 100644 --- a/roles/lib_openshift/src/class/oc_obj.py +++ b/roles/lib_openshift/src/class/oc_obj.py @@ -77,7 +77,6 @@ class OCObject(OpenShiftCLI): if objects['returncode'] != 0: return objects - # pylint: disable=no-member data = None if files: data = Utils.get_resource_file(files[0], content_type) |