Add credential delete hook to keystone chart
This change creates a pre-delete hook to clean out all entries in the credential table of the keystone database when the keystone service is deleted. Note that these are not the typical username/password.[0] This fixes the issue of leftover credential blobs being saved in the database that are unable to be decrypted since the original encryption keys are removed upon deletion of the keystone service [0] https://specs.openstack.org/openstack/keystone-specs/specs/keystone/newton/credential-encryption.html Change-Id: I8adf0878af2f3b880e9194a6cb8d97b58d6895a5
This commit is contained in:
parent
db87cf6390
commit
3d6f3088a3
121
keystone/templates/bin/_cred-clean.py.tpl
Normal file
121
keystone/templates/bin/_cred-clean.py.tpl
Normal file
@ -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')
|
@ -35,6 +35,8 @@ data:
|
|||||||
{{ tuple $rallyTests | include "helm-toolkit.scripts.rally_test" | indent 4 }}
|
{{ tuple $rallyTests | include "helm-toolkit.scripts.rally_test" | indent 4 }}
|
||||||
ks-user.sh: |
|
ks-user.sh: |
|
||||||
{{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }}
|
{{- 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: |
|
db-init.py: |
|
||||||
{{- include "helm-toolkit.scripts.db_init" . | indent 4 }}
|
{{- include "helm-toolkit.scripts.db_init" . | indent 4 }}
|
||||||
db-sync.sh: |
|
db-sync.sh: |
|
||||||
|
104
keystone/templates/job-credential-cleanup.yaml
Normal file
104
keystone/templates/job-credential-cleanup.yaml
Normal file
@ -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 -}}
|
@ -40,6 +40,7 @@ images:
|
|||||||
keystone_fernet_rotate: docker.io/openstackhelm/keystone:ocata
|
keystone_fernet_rotate: docker.io/openstackhelm/keystone:ocata
|
||||||
keystone_credential_setup: docker.io/openstackhelm/keystone:ocata
|
keystone_credential_setup: docker.io/openstackhelm/keystone:ocata
|
||||||
keystone_credential_rotate: 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_api: docker.io/openstackhelm/keystone:ocata
|
||||||
keystone_domain_manage: docker.io/openstackhelm/keystone:ocata
|
keystone_domain_manage: docker.io/openstackhelm/keystone:ocata
|
||||||
dep_check: quay.io/stackanetes/kubernetes-entrypoint:v0.3.1
|
dep_check: quay.io/stackanetes/kubernetes-entrypoint:v0.3.1
|
||||||
@ -113,6 +114,10 @@ dependencies:
|
|||||||
jobs:
|
jobs:
|
||||||
- keystone-credential-setup
|
- keystone-credential-setup
|
||||||
credential_setup: null
|
credential_setup: null
|
||||||
|
credential_cleanup:
|
||||||
|
services:
|
||||||
|
- endpoint: internal
|
||||||
|
service: oslo_db
|
||||||
db_drop:
|
db_drop:
|
||||||
services:
|
services:
|
||||||
- endpoint: internal
|
- endpoint: internal
|
||||||
@ -212,6 +217,11 @@ pod:
|
|||||||
keystone_credential_rotate:
|
keystone_credential_rotate:
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
volumes:
|
volumes:
|
||||||
|
keystone_credential_cleanup:
|
||||||
|
init_container: null
|
||||||
|
keystone_credential_cleanup:
|
||||||
|
volumeMounts:
|
||||||
|
volumes:
|
||||||
keystone_domain_manage:
|
keystone_domain_manage:
|
||||||
init_container: null
|
init_container: null
|
||||||
keystone_domain_manage:
|
keystone_domain_manage:
|
||||||
@ -320,6 +330,13 @@ pod:
|
|||||||
limits:
|
limits:
|
||||||
memory: "1024Mi"
|
memory: "1024Mi"
|
||||||
cpu: "2000m"
|
cpu: "2000m"
|
||||||
|
credential_cleanup:
|
||||||
|
requests:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "1024Mi"
|
||||||
|
cpu: "2000m"
|
||||||
image_repo_sync:
|
image_repo_sync:
|
||||||
requests:
|
requests:
|
||||||
memory: "128Mi"
|
memory: "128Mi"
|
||||||
@ -1245,6 +1262,7 @@ manifests:
|
|||||||
deployment_api: true
|
deployment_api: true
|
||||||
ingress_api: true
|
ingress_api: true
|
||||||
job_bootstrap: true
|
job_bootstrap: true
|
||||||
|
job_credential_cleanup: true
|
||||||
job_credential_setup: true
|
job_credential_setup: true
|
||||||
job_db_init: true
|
job_db_init: true
|
||||||
job_db_sync: true
|
job_db_sync: true
|
||||||
|
Loading…
Reference in New Issue
Block a user