diff --git a/keystone/templates/bin/_cred-clean.py.tpl b/keystone/templates/bin/_cred-clean.py.tpl new file mode 100644 index 0000000000..2361144fc7 --- /dev/null +++ b/keystone/templates/bin/_cred-clean.py.tpl @@ -0,0 +1,121 @@ +{{/* +Copyright 2019 The Openstack-Helm Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} + +#!/usr/bin/python + +# Drops db and user for an OpenStack Service: +# Set ROOT_DB_CONNECTION and DB_CONNECTION environment variables to contain +# SQLAlchemy strings for the root connection to the database and the one you +# wish the service to use. Alternatively, you can use an ini formatted config +# at the location specified by OPENSTACK_CONFIG_FILE, and extract the string +# from the key OPENSTACK_CONFIG_DB_KEY, in the section specified by +# OPENSTACK_CONFIG_DB_SECTION. + +import os +import sys +import ConfigParser +import logging +from sqlalchemy import create_engine + +# Create logger, console handler and formatter +logger = logging.getLogger('OpenStack-Helm DB Drop') +logger.setLevel(logging.DEBUG) +ch = logging.StreamHandler() +ch.setLevel(logging.DEBUG) +formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + +# Set the formatter and add the handler +ch.setFormatter(formatter) +logger.addHandler(ch) + + +# Get the connection string for the service db root user +if "ROOT_DB_CONNECTION" in os.environ: + db_connection = os.environ['ROOT_DB_CONNECTION'] + logger.info('Got DB root connection') +else: + logger.critical('environment variable ROOT_DB_CONNECTION not set') + sys.exit(1) + +# Get the connection string for the service db +if "OPENSTACK_CONFIG_FILE" in os.environ: + os_conf = os.environ['OPENSTACK_CONFIG_FILE'] + if "OPENSTACK_CONFIG_DB_SECTION" in os.environ: + os_conf_section = os.environ['OPENSTACK_CONFIG_DB_SECTION'] + else: + logger.critical('environment variable OPENSTACK_CONFIG_DB_SECTION not set') + sys.exit(1) + if "OPENSTACK_CONFIG_DB_KEY" in os.environ: + os_conf_key = os.environ['OPENSTACK_CONFIG_DB_KEY'] + else: + logger.critical('environment variable OPENSTACK_CONFIG_DB_KEY not set') + sys.exit(1) + try: + config = ConfigParser.RawConfigParser() + logger.info("Using {0} as db config source".format(os_conf)) + config.read(os_conf) + logger.info("Trying to load db config from {0}:{1}".format( + os_conf_section, os_conf_key)) + user_db_conn = config.get(os_conf_section, os_conf_key) + logger.info("Got config from {0}".format(os_conf)) + except: + logger.critical("Tried to load config from {0} but failed.".format(os_conf)) + raise +elif "DB_CONNECTION" in os.environ: + user_db_conn = os.environ['DB_CONNECTION'] + logger.info('Got config from DB_CONNECTION env var') +else: + logger.critical('Could not get db config, either from config file or env var') + sys.exit(1) + +# Root DB engine +try: + root_engine_full = create_engine(db_connection) + root_user = root_engine_full.url.username + root_password = root_engine_full.url.password + drivername = root_engine_full.url.drivername + host = root_engine_full.url.host + port = root_engine_full.url.port + root_engine_url = ''.join([drivername, '://', root_user, ':', root_password, '@', host, ':', str (port)]) + root_engine = create_engine(root_engine_url) + connection = root_engine.connect() + connection.close() + logger.info("Tested connection to DB @ {0}:{1} as {2}".format( + host, port, root_user)) +except: + logger.critical('Could not connect to database as root user') + raise + +# User DB engine +try: + user_engine = create_engine(user_db_conn) + # Get our user data out of the user_engine + database = user_engine.url.database + user = user_engine.url.username + password = user_engine.url.password + logger.info('Got user db config') +except: + logger.critical('Could not get user database config') + raise + +# Delete all entries from credential table + +try: + cmd = "DELETE FROM credential" + user_engine.execute(cmd) + logger.info('Deleted all entries in credential table') +except: + logger.critical('Failed to clean up credential table in keystone db') + raise + +logger.info('Finished DB Management') diff --git a/keystone/templates/configmap-bin.yaml b/keystone/templates/configmap-bin.yaml index b06aa84630..913e9bab39 100644 --- a/keystone/templates/configmap-bin.yaml +++ b/keystone/templates/configmap-bin.yaml @@ -35,6 +35,8 @@ data: {{ tuple $rallyTests | include "helm-toolkit.scripts.rally_test" | indent 4 }} ks-user.sh: | {{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} + cred-clean.py: | +{{ tuple "bin/_cred-clean.py.tpl" . | include "helm-toolkit.utils.template" |indent 4}} db-init.py: | {{- include "helm-toolkit.scripts.db_init" . | indent 4 }} db-sync.sh: | diff --git a/keystone/templates/job-credential-cleanup.yaml b/keystone/templates/job-credential-cleanup.yaml new file mode 100644 index 0000000000..11fed66477 --- /dev/null +++ b/keystone/templates/job-credential-cleanup.yaml @@ -0,0 +1,104 @@ +{{/* +Copyright 2019 The Openstack-Helm Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} + +{{- if .Values.manifests.job_credential_cleanup }} +{{- $envAll := index . -}} + +{{- $serviceName := "keystone" -}} +{{- $nodeSelector := index . "nodeSelector" | default ( dict $envAll.Values.labels.job.node_selector_key $envAll.Values.labels.job.node_selector_value ) -}} +{{- $configMapBin := "keystone-bin" -}} +{{- $configMapEtc := "keystone-etc" -}} +{{- $dbToClean := index . "dbToClean" | default ( dict "adminSecret" $envAll.Values.secrets.oslo_db.admin "configFile" (printf "/etc/%s/%s.conf" $serviceName $serviceName ) "logConfigFile" (printf "/etc/%s/logging.conf" $serviceName ) "configDbSection" "database" "configDbKey" "connection" ) -}} + +{{ tuple $envAll "credential_cleanup" $serviceName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} + +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: "keystone-credential-cleanup" + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeed +spec: + template: + metadata: + labels: +{{ tuple $envAll $serviceName "credential-cleanup" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} + spec: + serviceAccountName: {{ $serviceName }} + restartPolicy: OnFailure + nodeSelector: +{{ toYaml $nodeSelector | indent 8 }} + initContainers: +{{ tuple $envAll "credential_cleanup" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} + containers: +{{ $dbToCleanType := default "oslo" $dbToClean.inputType }} + - name: {{ printf "%s-%s" $serviceName "credential-cleanup" | quote }} + image: {{ $envAll.Values.images.tags.keystone_credential_cleanup }} + imagePullPolicy: {{ $envAll.Values.images.pull_policy }} +{{ tuple $envAll $envAll.Values.pod.resources.jobs.db_drop | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + env: + - name: ROOT_DB_CONNECTION + valueFrom: + secretKeyRef: + name: {{ $dbToClean.adminSecret | quote }} + key: DB_CONNECTION +{{- if eq $dbToCleanType "oslo" }} + - name: OPENSTACK_CONFIG_FILE + value: {{ $dbToClean.configFile | quote }} + - name: OPENSTACK_CONFIG_DB_SECTION + value: {{ $dbToClean.configDbSection | quote }} + - name: OPENSTACK_CONFIG_DB_KEY + value: {{ $dbToClean.configDbKey | quote }} +{{- end }} + command: + - python + - /tmp/cred-clean.py + volumeMounts: + - name: cred-clean-sh + mountPath: /tmp/cred-clean.py + subPath: cred-clean.py + readOnly: true +{{- if eq $dbToCleanType "oslo" }} + - name: etc-service + mountPath: {{ dir $dbToClean.configFile | quote }} + - name: cred-clean-conf + mountPath: {{ $dbToClean.configFile | quote }} + subPath: {{ base $dbToClean.configFile | quote }} + readOnly: true + - name: cred-clean-conf + mountPath: {{ $dbToClean.logConfigFile | quote }} + subPath: {{ base $dbToClean.logConfigFile | quote }} + readOnly: true +{{- end }} + volumes: + - name: cred-clean-sh + configMap: + name: "keystone-bin" + defaultMode: 0555 +{{- $local := dict "configMapBinFirst" true -}} +{{- $dbToCleanType := default "oslo" $dbToClean.inputType }} +{{- if and (eq $dbToCleanType "oslo") $local.configMapBinFirst }} +{{- $_ := set $local "configMapBinFirst" false }} + - name: etc-service + emptyDir: {} + - name: cred-clean-conf + secret: + secretName: "keystone-etc" + defaultMode: 0444 +{{- end -}} +{{- end -}} diff --git a/keystone/values.yaml b/keystone/values.yaml index d901804635..8b714cdaea 100644 --- a/keystone/values.yaml +++ b/keystone/values.yaml @@ -40,6 +40,7 @@ images: keystone_fernet_rotate: docker.io/openstackhelm/keystone:ocata keystone_credential_setup: docker.io/openstackhelm/keystone:ocata keystone_credential_rotate: docker.io/openstackhelm/keystone:ocata + keystone_credential_cleanup: docker.io/openstackhelm/heat:ocata keystone_api: docker.io/openstackhelm/keystone:ocata keystone_domain_manage: docker.io/openstackhelm/keystone:ocata dep_check: quay.io/stackanetes/kubernetes-entrypoint:v0.3.1 @@ -113,6 +114,10 @@ dependencies: jobs: - keystone-credential-setup credential_setup: null + credential_cleanup: + services: + - endpoint: internal + service: oslo_db db_drop: services: - endpoint: internal @@ -212,6 +217,11 @@ pod: keystone_credential_rotate: volumeMounts: volumes: + keystone_credential_cleanup: + init_container: null + keystone_credential_cleanup: + volumeMounts: + volumes: keystone_domain_manage: init_container: null keystone_domain_manage: @@ -320,6 +330,13 @@ pod: limits: memory: "1024Mi" cpu: "2000m" + credential_cleanup: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" image_repo_sync: requests: memory: "128Mi" @@ -1245,6 +1262,7 @@ manifests: deployment_api: true ingress_api: true job_bootstrap: true + job_credential_cleanup: true job_credential_setup: true job_db_init: true job_db_sync: true