Fernet Token Support

This PS adds Keystone Fernet Token support to Kolla Kubernetes.

Partially-Implements: blueprint fernet-token-support

Change-Id: I6b142b4ef881d3a9cb0a0e7d2db9b84d2b1663a8
This commit is contained in:
Kevin Fox 2017-03-15 19:07:12 -07:00
parent 26637a1399
commit b2635d9769
16 changed files with 290 additions and 3 deletions

View File

@ -421,7 +421,7 @@ keystone_internal_url: "{{ internal_protocol }}://{{ kolla_internal_fqdn }}:{{ k
keystone_public_url: "{{ public_protocol }}://{{ kolla_external_fqdn }}:{{ keystone_public_port }}/v3"
# Valid options are [ uuid, fernet ]
keystone_token_provider: "uuid"
keystone_token_provider: "fernet"
fernet_token_expiry: 86400
keystone_default_user_role: "_member_"

View File

@ -30,7 +30,7 @@ provider = {{ keystone_token_provider }}
expiration = {{ fernet_token_expiry }}
[fernet_tokens]
max_active_keys = {{ (groups['keystone'] | length) + 1 }}
max_active_keys = 3
{% endif %}
[cache]

View File

@ -15,6 +15,8 @@
{{- $configListenPortParameter := "bind_port" }}
{{- $portName := "keystone-public" }}
{{- $extraConfigmapConfig := "keystone_extra_configmap_config" }}
{{- $extraVolumes := "keystone_extra_volumes" }}
{{- $extraVolumeMounts := "keystone_extra_volume_mounts" }}
{{- $extraAnnotations := "keystone_initcontainer" }}
{{- $checkPath := "/" }}
{{- $privileged := false }}
@ -41,6 +43,15 @@ pod.beta.kubernetes.io/init-containers: '[
}
]'
{{- end }}
{{- define "keystone_extra_volumes" }}
- name: keystone-fernet-keys
secret:
secretName: keystone-fernet-keys
{{- end }}
{{- define "keystone_extra_volume_mounts" }}
- name: keystone-fernet-keys
mountPath: /etc/keystone/fernet-keys
{{- end }}
{{- define "keystone_extra_configmap_config" }}
items:
- key: keystone.conf
@ -52,6 +63,6 @@ items:
- key: config.json
path: config.json
{{- end }}
{{- with $env := dict "netHostTrue" $netHostTrue "podTypeBootstrap" $podTypeBootstrap "resourceName" $resourceName "serviceName" $serviceName "serviceType" $serviceType "configFileName" $configFileName "configSectionName" $configSectionName "configListenHostParameter" $configListenHostParameter "configListenPortParameter" $configListenPortParameter "portName" $portName "imageFull" $imageFull "checkPath" $checkPath "extraConfigmapConfig" $extraConfigmapConfig "extraAnnotations" $extraAnnotations "privileged" $privileged "haproxy" $haproxy "Values" .Values "Release" .Release "searchPath" $searchPath }}
{{- with $env := dict "netHostTrue" $netHostTrue "podTypeBootstrap" $podTypeBootstrap "resourceName" $resourceName "serviceName" $serviceName "serviceType" $serviceType "configFileName" $configFileName "configSectionName" $configSectionName "configListenHostParameter" $configListenHostParameter "configListenPortParameter" $configListenPortParameter "portName" $portName "imageFull" $imageFull "checkPath" $checkPath "extraConfigmapConfig" $extraConfigmapConfig "extraVolume" $extraVolumes "extraVolumeMounts" $extraVolumeMounts "extraAnnotations" $extraAnnotations "privileged" $privileged "haproxy" $haproxy "Values" .Values "Release" .Release "searchPath" $searchPath }}
{{- include "common_api_apache_deployment" $env }}
{{- end }}

View File

@ -62,6 +62,8 @@ spec:
- mountPath: {{ $containerConfigDirectory }}
name: service-configmap
readOnly: true
- name: keystone-fernet-keys
mountPath: /etc/keystone/fernet-keys
env:
- name: KOLLA_KUBERNETES
value: ""
@ -77,4 +79,7 @@ spec:
- name: service-configmap
configMap:
name: {{ .resourceName }}
- name: keystone-fernet-keys
secret:
secretName: keystone-fernet-keys
{{- end }}

View File

@ -0,0 +1,12 @@
name: keystone-fernet-rotate-job
version: 0.6.0-1 #FIXME make this changable
description: keystone fernet token rotation job
keywords:
- openstack
- keystone
- fernet
- rotation
sources:
- http://github.com/openstack
engine: gotpl
#icon: A URL to an SVG or PNG image to be used as an icon (optional). make this point to the new project icons when ready

View File

@ -0,0 +1,4 @@
dependencies:
- name: kolla-common
repository: file://../../kolla-common
version: 0.6.0-1

View File

@ -0,0 +1,122 @@
{{- $resourceName := "keystone-fernet-rotate-job" }}
{{- $searchPath := ":global.kolla.keystone.fernet.rotate.job:global.kolla.fernet.all:global.kolla.keystone.all:global.kolla.all" }}
{{- $c := dict "searchPath" $searchPath "Values" .Values }}
{{- $_ := set $c "contName" "keystone" }}
{{- $_ := set $c "imageName" "image_full" }}
{{- $_ := set $c "tagName" "image_tag" }}
{{- $imageFull := include "kolla_build_image_full" $c }}
{{- $imagePullPolicy := include "kolla_val_get_str" (dict "key" "image_pull_policy" "searchPath" $searchPath "Values" .Values ) }}
{{- $selectorKey := include "kolla_val_get_str" (dict "key" "selector_key" "searchPath" $searchPath "Values" .Values ) }}
{{- $selectorValue := include "kolla_val_get_str" (dict "key" "selector_value" "searchPath" $searchPath "Values" .Values ) }}
{{- $netHostTrue := false }}
{{- $podTypeBootstrap := false }}
{{- with $env := dict "netHostTrue" $netHostTrue "podTypeBootstrap" false "resourceName" $resourceName "Values" .Values "Release" .Release "searchPath" $searchPath }}
apiVersion: batch/v1
kind: Job
metadata:
name: keystone-fernet-rotate-job
spec:
template:
{{- include "init_container_header" . | indent 4 }}
{{- include "common_dependency_container_single" . | indent 10 }}
{{- include "init_container_tail" . | indent 4 }}
spec:
nodeSelector:
{{ $selectorKey }}: {{ $selectorValue | quote }}
containers:
- image: {{ $imageFull | quote }}
imagePullPolicy: {{ $imagePullPolicy | quote }}
name: main
securityContext:
runAsUser: 0
command:
- /bin/bash
- -ec
- |
KUBE_TOKEN=$(</var/run/secrets/kubernetes.io/serviceaccount/token)
KUBE_NAMESPACE=$(</var/run/secrets/kubernetes.io/serviceaccount/namespace)
curl -f --tlsv1.2 -sS --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
-H "Authorization: Bearer $KUBE_TOKEN" -o /tmp/tokens.json \
https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/api/v1/namespaces/$KUBE_NAMESPACE/secrets/keystone-fernet-keys
mkdir -p /etc/keystone/fernet-keys
cp -a /config/..data/* /etc/keystone
python - <<"EOF"
import base64
import json
import os.path
j = json.load(open("/tmp/tokens.json"));
for (k,v) in j["data"].items():
f = open(os.path.join("/etc/keystone/fernet-keys", k), "w")
f.write(base64.b64decode(v))
f.close()
EOF
chown --recursive keystone.keystone /etc/keystone
chmod 770 /etc/keystone/fernet-keys
chmod --recursive 660 /etc/keystone/fernet-keys/*
mkdir -p /var/log/kolla/keystone
chown keystone.keystone /var/log/kolla/keystone
echo Before
ls -l /etc/keystone/fernet-keys/
keystone-manage fernet_rotate --keystone-user keystone --keystone-group keystone
echo After
ls -l /etc/keystone/fernet-keys/
python - <<"EOF"
import base64
import datetime
import dateutil.parser
import json
import os
import os.path
p = "/etc/keystone/fernet-keys"
j = json.load(open("/tmp/tokens.json"));
a = j["metadata"].get("annotations", {})
if "lastmod" in a:
d = int(dateutil.parser.parse(a["lastmod"]).strftime("%s"))
now = int(datetime.datetime.utcnow().strftime("%s"))
if now < d + 5*60:
os.exit(0)
now = datetime.datetime.utcnow().replace(microsecond=0).isoformat() + 'Z'
a["lastmod"] = now
j["metadata"]["annotations"] = a
j["data"] = {}
del j["metadata"]["creationTimestamp"]
for k in os.listdir(p):
f = open(os.path.join(p, k), "r")
j["data"][k] = base64.b64encode(f.read())
f.close()
f = open("/tmp/tokens2.json", "w");
f.write(json.dumps(j))
f.close()
EOF
[ ! -f /tmp/tokens2.json ] && exit
curl_flags=""
{{- if .Values.upload_debug }}
cat /tmp/tokens2.json
curl_flags=-vvv
{{- end }}
curl -f --tlsv1.2 -sS --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
-X PUT \
-d '@/tmp/tokens2.json' \
-H 'Content-type:application/json' \
-H "Authorization: Bearer $KUBE_TOKEN" \
https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/api/v1/namespaces/$KUBE_NAMESPACE/secrets/keystone-fernet-keys $curl_flags
env:
{{- include "common_bootstrap_env_vars" . | indent 12 }}
volumeMounts:
{{- include "common_volume_mounts" $env | indent 12 }}
- mountPath: /config
name: keystone
readOnly: true
volumes:
{{- include "common_volumes" $env | indent 8 }}
- name: keystone
configMap:
name: keystone
restartPolicy: OnFailure
{{- end }}

View File

@ -0,0 +1,12 @@
name: keystone-fernet-setup-job
version: 0.6.0-1 #FIXME make this changable
description: keystone fernet token setup job
keywords:
- openstack
- keystone
- fernet
- setup
sources:
- http://github.com/openstack
engine: gotpl
#icon: A URL to an SVG or PNG image to be used as an icon (optional). make this point to the new project icons when ready

View File

@ -0,0 +1,4 @@
dependencies:
- name: kolla-common
repository: file://../../kolla-common
version: 0.6.0-1

View File

@ -0,0 +1,81 @@
{{- $resourceName := "keystone-fernet-setup-job" }}
{{- $searchPath := ":global.kolla.keystone.fernet.setup.job:global.kolla.fernet.all:global.kolla.keystone.all:global.kolla.all" }}
{{- $c := dict "searchPath" $searchPath "Values" .Values }}
{{- $_ := set $c "contName" "keystone" }}
{{- $_ := set $c "imageName" "image_full" }}
{{- $_ := set $c "tagName" "image_tag" }}
{{- $imageFull := include "kolla_build_image_full" $c }}
{{- $imagePullPolicy := include "kolla_val_get_str" (dict "key" "image_pull_policy" "searchPath" $searchPath "Values" .Values ) }}
{{- $selectorKey := include "kolla_val_get_str" (dict "key" "selector_key" "searchPath" $searchPath "Values" .Values ) }}
{{- $selectorValue := include "kolla_val_get_str" (dict "key" "selector_value" "searchPath" $searchPath "Values" .Values ) }}
{{- $netHostTrue := false }}
{{- $podTypeBootstrap := false }}
{{- with $env := dict "netHostTrue" $netHostTrue "podTypeBootstrap" false "resourceName" $resourceName "Values" .Values "Release" .Release "searchPath" $searchPath }}
apiVersion: batch/v1
kind: Job
metadata:
name: keystone-fernet-setup-job
spec:
template:
{{- include "init_container_header" . | indent 4 }}
{{- include "common_dependency_container_single" . | indent 10 }}
{{- include "init_container_tail" . | indent 4 }}
spec:
nodeSelector:
{{ $selectorKey }}: {{ $selectorValue | quote }}
containers:
- image: {{ $imageFull | quote }}
imagePullPolicy: {{ $imagePullPolicy | quote }}
name: main
securityContext:
runAsUser: 0
command:
- /bin/bash
- -ec
- |
KUBE_TOKEN=$(</var/run/secrets/kubernetes.io/serviceaccount/token)
KUBE_NAMESPACE=$(</var/run/secrets/kubernetes.io/serviceaccount/namespace)
mkdir -p /var/log/kolla/keystone
chown keystone.keystone /var/log/kolla/keystone
mkdir -p /etc/keystone/fernet-keys
cp -a /config/..data/* /etc/keystone
chown keystone.keystone /etc/keystone/fernet-keys
keystone-manage fernet_setup --keystone-user keystone --keystone-group keystone
TOKEN=$(cat /etc/keystone/fernet-keys/0 | base64)
cat > /tmp/tokens.json <<EOF
{
"apiVersion": "v1",
"kind": "Secret",
"type": "Opaque",
"metadata": {
"name": "keystone-fernet-keys",
"lastmod": "0000-01-01T12:00:00Z"
},
"data": {
"0": "$TOKEN"
}
}
EOF
curl -f --tlsv1.2 -sS --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
-d '@/tmp/tokens.json' \
-H 'Content-type:application/json' \
-H "Authorization: Bearer $KUBE_TOKEN" \
https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_PORT_443_TCP_PORT/api/v1/namespaces/$KUBE_NAMESPACE/secrets/ > /dev/null
env:
{{- include "common_bootstrap_env_vars" . | indent 12 }}
volumeMounts:
{{- include "common_volume_mounts" $env | indent 12 }}
- mountPath: /config
name: keystone
readOnly: true
volumes:
{{- include "common_volumes" $env | indent 8 }}
- name: keystone
configMap:
name: keystone
restartPolicy: OnFailure
{{- end }}

View File

@ -8,6 +8,9 @@ dependencies:
- name: keystone-public-svc
repository: file://../../microservice/keystone-public-svc
version: 0.6.0-1
- name: keystone-fernet-setup-job
repository: file://../../microservice/keystone-fernet-setup-job
version: 0.6.0-1
- name: keystone-create-db-job
repository: file://../../microservice/keystone-create-db-job
version: 0.6.0-1

View File

@ -14,6 +14,7 @@ global:
service:
- mariadb
jobs:
- keystone-fernet-setup-job
- keystone-create-db
create_keystone_endpoints:
job:

View File

@ -0,0 +1,4 @@
---
features:
- |
Added support for Keystone Fernet Tokens.

View File

@ -160,6 +160,16 @@ helm install kolla/rabbitmq-statefulset --version $VERSION \
$DIR/tools/pull_containers.sh kolla
$DIR/tools/wait_for_pods.sh kolla
helm install kolla/keystone-fernet-setup-job --version $VERSION \
--namespace kolla \
--name keystone-fernet-setup-job \
--values /tmp/general_config.yaml --values /tmp/ceph_config.yaml
$DIR/tools/pull_containers.sh kolla
$DIR/tools/wait_for_pods.sh kolla
helm delete --purge keystone-fernet-setup-job
helm install kolla/keystone-create-db-job --version $VERSION \
--namespace kolla \
--name keystone-create-db \
@ -198,6 +208,11 @@ $DIR/tools/wait_for_pods.sh kolla
$DIR/tools/build_local_admin_keystonerc.sh
. ~/keystonerc_admin
helm install kolla/keystone-fernet-rotate-job --version $VERSION \
--namespace kolla --name keystone-fernet-rotate-job \
--set upload_debug=true \
--values /tmp/general_config.yaml --values /tmp/ceph_config.yaml
helm install kolla/neutron-create-keystone-service-job --version $VERSION \
--namespace kolla --name neutron-create-keystone-service \
--values /tmp/general_config.yaml --values /tmp/ceph_config.yaml
@ -303,6 +318,8 @@ done
$DIR/tools/wait_for_pods.sh kolla
helm delete --purge keystone-fernet-rotate-job
for x in cinder glance neutron nova heat; do
helm delete --purge $x-create-keystone-user
done

View File

@ -166,6 +166,16 @@ helm install kolla/rabbitmq-statefulset --version $VERSION \
$DIR/tools/pull_containers.sh kolla
$DIR/tools/wait_for_pods.sh kolla
helm install kolla/keystone-fernet-setup-job --version $VERSION \
--namespace kolla \
--name keystone-fernet-setup-job \
--values /tmp/general_config.yaml --values /tmp/iscsi_config.yaml
$DIR/tools/pull_containers.sh kolla
$DIR/tools/wait_for_pods.sh kolla
helm delete --purge keystone-fernet-setup-job
helm install kolla/keystone-create-db-job --version $VERSION \
--namespace kolla --name keystone-create-db \
--values /tmp/general_config.yaml --values /tmp/iscsi_config.yaml

View File

@ -26,6 +26,7 @@ kubectl get deployments --all-namespaces -o yaml > \
kubectl describe node $(hostname -s) > $WORKSPACE/logs/node.txt
kubectl get pods -a --all-namespaces -o yaml > $WORKSPACE/logs/pods.yaml
kubectl get configmaps -a --all-namespaces -o yaml > $WORKSPACE/logs/configmaps.yaml
kubectl get secrets -a --all-namespaces -o yaml > $WORKSPACE/logs/secrets.yaml
sudo docker images > $WORKSPACE/logs/docker_images.txt
kubectl get pods -a --all-namespaces -o json | jq -r \
'.items[].metadata | .namespace + " " + .name' | while read line; do