Configuration Management Overrides for Keystone

This commit introduces several new paradigms:

* .Values driven mounts in service containers as well as jobs.
These can be overriden at runtime by manipulating .Values.mounts.*

* Authenticated Endpoint Resolution methods in helm-toolkit
to allow the database and rabbit type endpoints to be moved
under the endpoints section.  Now endpoint lookup functions exist
for openstack endpoints as well as infrastructure elements such as
the database, rabbitmq, and memcache.

* Importing of upstream "out of the box" policy.json
and keystone-paste.ini files for better or worse.

* A rendering of the keystone.conf oslo generated config
using a new helm based Values generator. This provides "known"
paths to all configuration elements in the form of
"<section>.<oslo_namespace>.<element>" so that any of these can
be targeted for override via --set or values.yaml files loaded at
run time.

* Support for appending arbitrary string data to the policy.json,
keystone-paste.ini, or keystone.conf files via --set conf.keystone.append="#
some comment", or --set conf.policy.append="\"identity:list_projects\":
\"role:fake\""

* Support for complete verbatim overrides of these three
files via --set conf.keystone.override="full file contents",
or --set conf.policy.override="full file contents" for example
This commit is contained in:
Alan Meadows 2017-03-07 13:25:44 -08:00
parent 97fd35009a
commit 236be51343
12 changed files with 3947 additions and 131 deletions

View File

@ -120,7 +120,7 @@
{{- with $endpointMap -}}
{{- $endpointScheme := .scheme }}
{{- $endpointHost := index .hosts $endpoint | default .hosts.default}}
{{- $endpointPort := index .port $port }}
{{- $endpointPort := index .port $port | default .port.default }}
{{- $endpointPath := .path }}
{{- printf "%s://%s.%s:%1.f%s" $endpointScheme $endpointHost $fqdn $endpointPort $endpointPath | quote -}}
{{- end -}}
@ -150,6 +150,69 @@
{{- end -}}
{{- end -}}
# this function helps resolve database style endpoints, which really follow the same
# pattern as above, except they have a username and password component
#
# presuming that .Values contains an endpoint: definition for 'neutron-db' with the
# appropriate attributes, a call such as:
#
# { tuple "neutron-db" "internal" "userClass" "portName" . | include "helm-toolkit.authenticated_endpoint_uri_lookup" }
#
# where portName is optional if a default port has been defined in .Values
#
# returns: mysql+pymysql://username:password@internal_host:3306/dbname
{{- define "helm-toolkit.authenticated_endpoint_uri_lookup" -}}
{{- $type := index . 0 -}}
{{- $endpoint := index . 1 -}}
{{- $userclass := index . 2 -}}
{{- $port := index . 3 -}}
{{- $context := index . 4 -}}
{{- $endpointMap := index $context.Values.endpoints $type }}
{{- $userMap := index $endpointMap.auth $userclass }}
{{- $fqdn := $context.Release.Namespace -}}
{{- if $context.Values.endpoints.fqdn -}}
{{- $fqdn := $context.Values.endpoints.fqdn -}}
{{- end -}}
{{- with $endpointMap -}}
{{- $endpointScheme := .scheme }}
{{- $endpointUser := index $userMap "username" }}
{{- $endpointPass := index $userMap "password" }}
{{- $endpointHost := index .hosts $endpoint | default .hosts.default}}
{{- $endpointPort := index .port $port | default .port.default }}
{{- $endpointPath := .path | default "" }}
{{- printf "%s://%s:%s@%s.%s:%1.f%s" $endpointScheme $endpointUser $endpointPass $endpointHost $fqdn $endpointPort $endpointPath -}}
{{- end -}}
{{- end -}}
# this function returns hostnames from endpoint definitions for use cases
# where the uri style return is not appropriate, and only the hostname
# portion is used or relevant in the template
#
# { tuple "memcache" "internal" "portName" . | include "helm-toolkit.hostname_endpoint_uri_lookup" }
#
# returns: internal_host:port
#
# output that requires the port aspect striped should simply split the output based on ':'
{{- define "helm-toolkit.hostname_endpoint_uri_lookup" -}}
{{- $type := index . 0 -}}
{{- $endpoint := index . 1 -}}
{{- $port := index . 2 -}}
{{- $context := index . 3 -}}
{{- $endpointMap := index $context.Values.endpoints $type }}
{{- $fqdn := $context.Release.Namespace -}}
{{- if $context.Values.endpoints.fqdn -}}
{{- $fqdn := $context.Values.endpoints.fqdn -}}
{{- end -}}
{{- with $endpointMap -}}
{{- $endpointScheme := .scheme }}
{{- $endpointHost := index .hosts $endpoint | default .hosts.default}}
{{- $endpointPort := index .port $port | default .port.default }}
{{- printf "%s.%s:%1.f" $endpointHost $fqdn $endpointPort -}}
{{- end -}}
{{- end -}}
#-------------------------------
# endpoint type lookup
#-------------------------------

View File

@ -0,0 +1,39 @@
# Copyright 2017 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.
#-----------------------------------------------
# oslo settings we will dynamically manufacture
#-----------------------------------------------
{{- define "helm-toolkit.oslo_values_setup" -}}
{{ $obj := index . 0 }}
{{ $root := index . 1 }}
# generate database uri and set $conf.conf.oslo.db.connection
{{- if empty $obj.database.oslo.db.connection -}}
{{- tuple "oslo_db" "internal" "user" "mysql" $root | include "helm-toolkit.authenticated_endpoint_uri_lookup"| set $obj.database.oslo.db "connection" -}}
{{- end -}}
# generate amqp transport uri and set $conf.endpoints.messaging
{{- if empty $obj.default.oslo.messaging.transport_url -}}
{{- tuple "oslo_messaging" "internal" "user" "amqp" $root | include "helm-toolkit.authenticated_endpoint_uri_lookup" | set $obj.default.oslo.messaging "transport_url" -}}
{{- end -}}
# generate memcache host:port and set $conf.endpoints.memcache
{{- if empty $obj.cache.oslo.cache -}}
{{- tuple "oslo_cache" "internal" "memcache" $root | include "helm-toolkit.hostname_endpoint_uri_lookup" | set $obj.cache.oslo.cache "memcache_servers" -}}
{{- end -}}
{{- end -}}

View File

@ -18,19 +18,19 @@ set -ex
export HOME=/tmp
ansible localhost -vvv \
-m mysql_db -a "login_host='{{ include "helm-toolkit.mariadb_host" . }}' \
login_port='{{ .Values.database.port }}' \
login_user='{{ .Values.database.root_user }}' \
login_password='{{ .Values.database.root_password }}' \
name='{{ .Values.database.keystone_database_name }}'"
-m mysql_db -a "login_host='{{ .Values.endpoints.oslo_db.hosts.internal | default .Values.endpoints.oslo_db.hosts.default }}' \
login_port='{{ .Values.endpoints.oslo_db.port.mysql }}' \
login_user='{{ .Values.endpoints.oslo_db.auth.admin.username }}' \
login_password='{{ .Values.endpoints.oslo_db.auth.admin.password }}' \
name='{{ .Values.endpoints.oslo_db.path | trimAll "/" }}'"
ansible localhost -vvv \
-m mysql_user -a "login_host='{{ include "helm-toolkit.mariadb_host" . }}' \
login_port='{{ .Values.database.port }}' \
login_user='{{ .Values.database.root_user }}' \
login_password='{{ .Values.database.root_password }}' \
name='{{ .Values.database.keystone_user }}' \
password='{{ .Values.database.keystone_password }}' \
-m mysql_user -a "login_host='{{ .Values.endpoints.oslo_db.hosts.internal | default .Values.endpoints.oslo_db.hosts.default }}' \
login_port='{{ .Values.endpoints.oslo_db.port.mysql }}' \
login_user='{{ .Values.endpoints.oslo_db.auth.admin.username }}' \
login_password='{{ .Values.endpoints.oslo_db.auth.admin.password }}' \
name='{{ .Values.endpoints.oslo_db.auth.user.username }}' \
password='{{ .Values.endpoints.oslo_db.auth.user.password }}' \
host='%' \
priv='{{ .Values.database.keystone_database_name }}.*:ALL' \
priv='{{ .Values.endpoints.oslo_db.path | trimAll "/" }}.*:ALL' \
append_privs='yes'"

View File

@ -12,6 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
{{- $conf := .Values.conf.keystone -}}
{{ include "helm-toolkit.oslo_values_setup" $conf | trunc 0 }}
apiVersion: v1
kind: ConfigMap
metadata:

View File

@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
{{ tuple .Values.conf.keystone . | include "helm-toolkit.oslo_values_setup" | trunc 0 }}
apiVersion: v1
kind: ConfigMap
metadata:

View File

@ -14,6 +14,8 @@
{{- $envAll := . }}
{{- $dependencies := .Values.dependencies.api }}
{{- $mounts := .Values.mounts.api }}
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
@ -72,58 +74,8 @@ spec:
readinessProbe:
tcpSocket:
port: {{ .Values.network.port.api }}
volumeMounts:
- name: pod-etc-keystone
mountPath: /etc/keystone
- name: keystoneconf
mountPath: /etc/keystone/keystone.conf
subPath: keystone.conf
readOnly: true
- name: keystonepaste
mountPath: /etc/keystone/keystone-paste.ini
subPath: keystone-paste.ini
readOnly: true
- name: keystonepolicy
mountPath: /etc/keystone/policy.json
subPath: policy.json
readOnly: true
- name: keystonessotemplate
mountPath: /etc/keystone/sso_callback_template.html
subPath: sso_callback_template.html
readOnly: true
- name: wsgikeystone
mountPath: /etc/apache2/conf-enabled/wsgi-keystone.conf
subPath: wsgi-keystone.conf
readOnly: true
- name: mpmeventconf
mountPath: /etc/apache2/mods-available/mpm_event.conf
subPath: mpm_event.conf
readOnly: true
- name: startsh
mountPath: /tmp/start.sh
subPath: start.sh
readOnly: true
volumeMounts:
{{ toYaml $mounts.volumeMounts | indent 12 }}
volumes:
- name: pod-etc-keystone
emptyDir: {}
- name: keystoneconf
configMap:
name: keystone-etc
- name: keystonepaste
configMap:
name: keystone-etc
- name: keystonepolicy
configMap:
name: keystone-etc
- name: keystonessotemplate
configMap:
name: keystone-etc
- name: wsgikeystone
configMap:
name: keystone-etc
- name: mpmeventconf
configMap:
name: keystone-etc
- name: startsh
configMap:
name: keystone-bin
{{ toYaml $mounts.volumes | indent 8 }}

View File

@ -12,6 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
{{- if empty .Values.conf.paste.override -}}
{{ include "keystone.conf.paste" .Values.conf.paste }}
{{- else -}}
{{ .Values.conf.paste.override }}
{{- end -}}
{{- define "keystone.conf.paste" -}}
# Keystone PasteDeploy configuration file.
[filter:debug]
@ -41,9 +49,6 @@ oslo_config_project = keystone
[filter:http_proxy_to_wsgi]
use = egg:oslo.middleware#http_proxy_to_wsgi
[filter:healthcheck]
use = egg:oslo.middleware#healthcheck
[filter:ec2_extension]
use = egg:keystone#ec2_extension
@ -74,17 +79,17 @@ use = egg:keystone#admin_service
[pipeline:public_api]
# The last item in this pipeline must be public_service or an equivalent
# application. It cannot be a filter.
pipeline = healthcheck cors sizelimit http_proxy_to_wsgi osprofiler url_normalize request_id build_auth_context token_auth json_body ec2_extension public_service
pipeline = cors sizelimit http_proxy_to_wsgi osprofiler url_normalize request_id admin_token_auth build_auth_context token_auth json_body ec2_extension public_service
[pipeline:admin_api]
# The last item in this pipeline must be admin_service or an equivalent
# application. It cannot be a filter.
pipeline = healthcheck cors sizelimit http_proxy_to_wsgi osprofiler url_normalize request_id build_auth_context token_auth json_body ec2_extension s3_extension admin_service
pipeline = cors sizelimit http_proxy_to_wsgi osprofiler url_normalize request_id admin_token_auth build_auth_context token_auth json_body ec2_extension s3_extension admin_service
[pipeline:api_v3]
# The last item in this pipeline must be service_v3 or an equivalent
# application. It cannot be a filter.
pipeline = healthcheck cors sizelimit http_proxy_to_wsgi osprofiler url_normalize request_id build_auth_context token_auth json_body ec2_extension_v3 s3_extension service_v3
pipeline = cors sizelimit http_proxy_to_wsgi osprofiler url_normalize request_id admin_token_auth build_auth_context token_auth json_body ec2_extension_v3 s3_extension service_v3
[app:public_version_service]
use = egg:keystone#public_version_service
@ -93,10 +98,10 @@ use = egg:keystone#public_version_service
use = egg:keystone#admin_version_service
[pipeline:public_version_api]
pipeline = healthcheck cors sizelimit osprofiler url_normalize public_version_service
pipeline = cors sizelimit osprofiler url_normalize public_version_service
[pipeline:admin_version_api]
pipeline = healthcheck cors sizelimit osprofiler url_normalize admin_version_service
pipeline = cors sizelimit osprofiler url_normalize admin_version_service
[composite:main]
use = egg:Paste#urlmap
@ -109,3 +114,9 @@ use = egg:Paste#urlmap
/v2.0 = admin_api
/v3 = api_v3
/ = admin_version_api
{{ if .append }}
{{ .append }}
{{ end }}
{{- end -}}

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,11 @@
{{- if empty .Values.conf.policy.override -}}
{{ include "keystone.conf.policy" .Values.conf.policy }}
{{- else -}}
{{ .Values.conf.policy.override }}
{{- end -}}
{{- define "keystone.conf.policy" -}}
{
"admin_required": "role:admin or is_admin:1",
"service_role": "role:service",
@ -176,7 +184,7 @@
"identity:list_projects_for_user": "",
"identity:list_domains_for_user": "",
"identity:list_revoke_events": "rule:service_or_admin",
"identity:list_revoke_events": "",
"identity:create_policy_association_for_endpoint": "rule:admin_required",
"identity:check_policy_association_for_endpoint": "rule:admin_required",
@ -192,8 +200,14 @@
"identity:create_domain_config": "rule:admin_required",
"identity:get_domain_config": "rule:admin_required",
"identity:get_security_compliance_domain_config": "",
"identity:update_domain_config": "rule:admin_required",
"identity:delete_domain_config": "rule:admin_required",
"identity:get_domain_config_default": "rule:admin_required"
{{- if .append -}}
,
{{ .append | indent 4 }}
{{ end }}
}
{{ end -}}

View File

@ -14,6 +14,7 @@
{{- $envAll := . }}
{{- $dependencies := .Values.dependencies.init }}
{{- $mounts := .Values.mounts.job_db_init }}
apiVersion: batch/v1
kind: Job
metadata:
@ -45,11 +46,8 @@ spec:
command:
- bash
- /tmp/init.sh
volumeMounts:
- name: keystone-bin
mountPath: /tmp/init.sh
subPath: init.sh
volumeMounts:
{{ toYaml $mounts.volumeMounts | indent 12 }}
volumes:
- name: keystone-bin
configMap:
name: keystone-bin
{{ toYaml $mounts.volumes | indent 8 }}

View File

@ -14,6 +14,7 @@
{{- $envAll := . }}
{{- $dependencies := .Values.dependencies.db_sync }}
{{- $mounts := .Values.mounts.job_db_sync }}
apiVersion: batch/v1
kind: Job
metadata:
@ -45,23 +46,7 @@ spec:
command:
- bash
- /tmp/db-sync.sh
volumeMounts:
- name: pod-etc-keystone
mountPath: /etc/keystone
- name: keystoneconf
mountPath: /etc/keystone/keystone.conf
subPath: keystone.conf
readOnly: true
- name: keystone-bin
mountPath: /tmp/db-sync.sh
subPath: db-sync.sh
readOnly: true
volumeMounts:
{{ toYaml $mounts.volumeMounts | indent 12 }}
volumes:
- name: pod-etc-keystone
emptyDir: {}
- name: keystoneconf
configMap:
name: keystone-etc
- name: keystone-bin
configMap:
name: keystone-bin
{{ toYaml $mounts.volumes | indent 8 }}

View File

@ -45,25 +45,11 @@ keystone:
admin_password: password
admin_project_name: admin
api:
default:
debug: false
token:
provider: uuid
network:
port:
admin: 35357
api: 5000
database:
port: 3306
root_user: root
root_password: password
keystone_database_name: keystone
keystone_password: password
keystone_user: keystone
dependencies:
api:
jobs:
@ -108,6 +94,196 @@ resources:
memory: "128Mi"
cpu: "500m"
mounts:
job_db_init:
volumes:
- name: keystone-bin
configMap:
name: keystone-bin
volumeMounts:
- name: keystone-bin
mountPath: /tmp/init.sh
subPath: init.sh
job_db_sync:
volumes:
- name: empty
emptyDir: {}
- name: keystone-etc
configMap:
name: keystone-etc
- name: keystone-bin
configMap:
name: keystone-bin
volumeMounts:
- name: empty
mountPath: /etc/keystone
- name: keystone-etc
mountPath: /etc/keystone/keystone.conf
subPath: keystone.conf
readOnly: true
- name: keystone-bin
mountPath: /tmp/db-sync.sh
subPath: db-sync.sh
readOnly: true
api:
volumes:
- name: empty
emptyDir: {}
- name: keystone-etc
configMap:
name: keystone-etc
- name: keystone-bin
configMap:
name: keystone-bin
volumeMounts:
- name: empty
mountPath: /etc/keystone
- name: keystone-etc
mountPath: /etc/keystone/keystone.conf
subPath: keystone.conf
readOnly: true
- name: keystone-etc
mountPath: /etc/keystone/keystone-paste.ini
subPath: keystone-paste.ini
readOnly: true
- name: keystone-etc
mountPath: /etc/keystone/policy.json
subPath: policy.json
readOnly: true
- name: keystone-etc
mountPath: /etc/keystone/sso_callback_template.html
subPath: sso_callback_template.html
readOnly: true
- name: keystone-etc
mountPath: /etc/apache2/conf-enabled/wsgi-keystone.conf
subPath: wsgi-keystone.conf
readOnly: true
- name: keystone-etc
mountPath: /etc/apache2/mods-available/mpm_event.conf
subPath: mpm_event.conf
readOnly: true
- name: keystone-bin
mountPath: /tmp/start.sh
subPath: start.sh
readOnly: true
conf:
paste:
override:
append:
policy:
override:
append:
keystone:
override:
append:
assignment:
keystone: {}
auth:
keystone: {}
catalog:
keystone: {}
credential:
keystone: {}
domain_config:
keystone: {}
endpoint_filter:
keystone: {}
endpoint_policy:
keystone: {}
eventlet_server:
keystone: {}
federation:
keystone: {}
fernet_tokens:
keystone: {}
identity:
keystone: {}
identity_mapping:
keystone: {}
kvs:
keystone: {}
ldap:
keystone: {}
oauth1:
keystone: {}
policy:
keystone: {}
resource:
keystone: {}
role:
keystone: {}
saml:
keystone: {}
security_compliance:
keystone: {}
shadow_users:
keystone: {}
signing:
keystone: {}
token:
keystone:
provider: uuid
tokenless_auth:
keystone: {}
trust:
keystone: {}
memcache:
keystone: {}
os_inherit:
keystone: {}
paste_deploy:
keystone: {}
revoke:
keystone: {}
default:
keystone: {}
oslo:
log: {}
messaging: {}
cache:
oslo:
cache: {}
cors:
oslo:
middleware: {}
subdomain:
oslo:
middleware: {}
database:
oslo:
db:
max_retries: -1
healthcheck:
oslo:
middleware: {}
matchmaker_redis:
oslo:
messaging: {}
oslo_messaging_amqp:
oslo:
messaging: {}
oslo_messaging_kafka:
oslo:
messaging: {}
oslo_messaging_notifications:
oslo:
messaging: {}
oslo_messaging_rabbit:
oslo:
messaging: {}
oslo_messaging_zmq:
oslo:
messaging: {}
oslo_middleware:
oslo:
middleware: {}
oslo_policy:
oslo:
policy: {}
profiler:
osprofiler: {}
# typically overriden by environmental
# values, but should include all endpoints
# required by this chart
@ -121,3 +297,36 @@ endpoints:
port:
admin: 35357
api: 5000
oslo_db:
auth:
admin:
username: root
password: password
user:
username: keystone
password: password
hosts:
default: mariadb
path: /keystone
scheme: mysql+pymysql
port:
mysql: 3306
oslo_messaging:
auth:
admin:
username: admin
password: password
user:
username: keystone
password: password
hosts:
default: rabbitmq
path: /openstack
scheme: rabbit
port:
amqp: 5672
oslo_cache:
hosts:
default: memcache
port:
memcache: 11211