def fetch_provider_vault_secret(path, version, name, labels, annotations, type, integration, integration_version): # get the fields from vault vault_client = VaultClient() raw_data = vault_client.read_all({'path': path, 'version': version}) # construct oc resource body = { "apiVersion": "v1", "kind": "Secret", "type": type, "metadata": { "name": name, "annotations": annotations } } if labels: body['metadata']['labels'] = labels if raw_data.items(): body['data'] = {} # populate data for k, v in raw_data.items(): if v == "": continue if k.lower().endswith(QONTRACT_BASE64_SUFFIX): k = k[:-len(QONTRACT_BASE64_SUFFIX)] elif v is not None: v = base64.b64encode(v.encode()).decode('utf-8') body['data'][k] = v try: return OR(body, integration, integration_version, error_details=path) except ConstructResourceError as e: raise FetchResourceError(str(e))
def write_output_to_vault(dry_run, vault_path, account, secret_data, name): integration_name = QONTRACT_INTEGRATION secret_path = f"{vault_path}/{integration_name}/{account}/{name}" secret = {'path': secret_path, 'data': secret_data} logging.info(['write_secret', secret_path]) vault_client = VaultClient() if not dry_run: vault_client.write(secret)
def write_outputs_to_vault(vault_path, ri): integration_name = QONTRACT_INTEGRATION.replace('_', '-') vault_client = VaultClient() for cluster, namespace, _, data in ri: for name, d_item in data['desired'].items(): secret_path = \ f"{vault_path}/{integration_name}/{cluster}/{namespace}/{name}" secret = {'path': secret_path, 'data': d_item.body['data']} vault_client.write(secret)
def lookup_vault_secret(path, key, version=None, tvars=None): if tvars is not None: path = process_jinja2_template(path, vars=tvars) key = process_jinja2_template(key, vars=tvars) if version and not isinstance(version, int): version = process_jinja2_template(version, vars=tvars) secret = {'path': path, 'field': key, 'version': version} try: vault_client = VaultClient() return vault_client.read(secret) except Exception as e: raise FetchVaultSecretError(e)
def fetch_provider_route(path, tls_path, tls_version): global _log_lock openshift_resource = fetch_provider_resource(path) if tls_path is None or tls_version is None: return openshift_resource # override existing tls fields from vault secret openshift_resource.body['spec'].setdefault('tls', {}) tls = openshift_resource.body['spec']['tls'] # get tls fields from vault vault_client = VaultClient() raw_data = vault_client.read_all({ 'path': tls_path, 'version': tls_version }) valid_keys = [ 'termination', 'insecureEdgeTerminationPolicy', 'certificate', 'key', 'caCertificate', 'destinationCACertificate' ] for k, v in raw_data.items(): if k in valid_keys: tls[k] = v continue msg = "Route secret '{}' key '{}' not in valid keys {}".format( tls_path, k, valid_keys) _log_lock.acquire() logging.info(msg) _log_lock.release() host = openshift_resource.body['spec'].get('host') certificate = openshift_resource.body['spec']['tls'].get('certificate') if host and certificate: match = openssl.certificate_matches_host(certificate, host) if not match: e_msg = "Route host does not match CN (common name): {}" raise FetchRouteError(e_msg.format(path)) return openshift_resource
def write_outputs_to_vault(vault_path, ri): integration_name = QONTRACT_INTEGRATION.replace('_', '-') vault_client = VaultClient() for cluster, namespace, _, data in ri: for name, d_item in data['desired'].items(): body_data = d_item.body['data'] # write secret to per-namespace location secret_path = \ f"{vault_path}/{integration_name}/" + \ f"{cluster}/{namespace}/{name}" secret = {'path': secret_path, 'data': body_data} vault_client.write(secret) # write secret to shared-resources location secret_path = \ f"{vault_path}/{integration_name}/" + \ f"shared-resources/{name}" secret = {'path': secret_path, 'data': body_data} vault_client.write(secret)
def vault_client(self): if self._vault_client is None: self._vault_client = VaultClient() return self._vault_client