diff --git a/Makefile b/Makefile index 5c7e2a1e61..e3c08d22c4 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,12 @@ -.PHONY: ceph bootstrap mariadb keystone memcached rabbitmq common openstack neutron maas all clean +.PHONY: ceph bootstrap mariadb keystone memcached rabbitmq common openstack neutron heat maas all clean B64_DIRS := common/secrets B64_EXCLUDE := $(wildcard common/secrets/*.b64) -CHARTS := ceph mariadb rabbitmq GLANCE memcached keystone glance horizon neutron maas openstack +CHARTS := ceph mariadb rabbitmq GLANCE memcached keystone glance horizon neutron heat maas openstack COMMON_TPL := common/templates/_globals.tpl -all: common ceph bootstrap mariadb rabbitmq memcached keystone glance horizon neutron maas openstack +all: common ceph bootstrap mariadb rabbitmq memcached keystone glance horizon neutron heat maas openstack common: build-common @@ -27,6 +27,8 @@ glance: build-glance neutron: build-neutron +heat: build-heat + maas: build-maas memcached: build-memcached @@ -44,4 +46,3 @@ build-%: if [ -f $*/requirements.yaml ]; then helm dep up $*; fi helm lint $* helm package $* - diff --git a/common/templates/_endpoints.tpl b/common/templates/_endpoints.tpl index 68914d6dfc..fe0a7d1888 100644 --- a/common/templates/_endpoints.tpl +++ b/common/templates/_endpoints.tpl @@ -87,8 +87,51 @@ {{- end -}} {{- end -}} +# this function returns the endpoint uri for a service, it takes an tuple +# input in the form: service-name, endpoint-class, port-name. eg: +# { tuple "heat" "public" "api" . | include "endpoint_addr_lookup" } +# will return the appropriate URI. Once merged this should phase out the above. + +{{- define "endpoint_addr_lookup" -}} +{{- $name := index . 0 -}} +{{- $endpoint := index . 1 -}} +{{- $port := index . 2 -}} +{{- $context := index . 3 -}} +{{- $nameNorm := $name | replace "-" "_" }} +{{- $endpointMap := index $context.Values.endpoints $nameNorm }} +{{- $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 }} +{{- $endpointPath := .path }} +{{- printf "%s://%s.%s:%1.f%s" $endpointScheme $endpointHost $fqdn $endpointPort $endpointPath | quote -}} +{{- end -}} +{{- end -}} + + +#------------------------------- +# endpoint type lookup +#------------------------------- + +# this function is used in endpoint management templates +# it returns the service type for an openstack service eg: +# { tuple heat . | include "ks_endpoint_type" } +# will return "orchestration" + +{{- define "endpoint_type_lookup" -}} +{{- $name := index . 0 -}} +{{- $context := index . 1 -}} +{{- $nameNorm := $name | replace "-" "_" }} +{{- $endpointMap := index $context.Values.endpoints $nameNorm }} +{{- $endpointType := index $endpointMap "type" }} +{{- $endpointType | quote -}} +{{- end -}} + #------------------------------- # kolla helpers #------------------------------- {{ define "keystone_auth" }}{'auth_url':'{{ include "endpoint_keystone_internal" . }}', 'username':'{{ .Values.keystone.admin_user }}','password':'{{ .Values.keystone.admin_password }}','project_name':'{{ .Values.keystone.admin_project_name }}','domain_name':'default'}{{end}} - diff --git a/common/templates/_funcs.tpl b/common/templates/_funcs.tpl index e83d171a97..fe6c9a675e 100644 --- a/common/templates/_funcs.tpl +++ b/common/templates/_funcs.tpl @@ -21,4 +21,3 @@ {{- $wtf := $context.Template.Name | replace $last $name -}} {{- include $wtf $context | sha256sum | quote -}} {{- end -}} - diff --git a/common/templates/scripts/_ks-domain-user.sh.tpl b/common/templates/scripts/_ks-domain-user.sh.tpl new file mode 100644 index 0000000000..44bfd27684 --- /dev/null +++ b/common/templates/scripts/_ks-domain-user.sh.tpl @@ -0,0 +1,57 @@ +{{- define "common_keystone_domain_user" }} +#!/bin/bash + +# Copyright 2017 Pete Birley +# +# 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. + +set -ex + +# Manage domain +SERVICE_OS_DOMAIN_ID=$(openstack domain create --or-show --enable -f value -c id \ + --description="Service Domain for ${SERVICE_OS_REGION_NAME}/${SERVICE_OS_DOMAIN_NAME}" \ + "${SERVICE_OS_DOMAIN_NAME}") + +# Display domain +openstack domain show "${SERVICE_OS_DOMAIN_ID}" + +# Manage user +SERVICE_OS_USERID=$(openstack user create --or-show --enable -f value -c id \ + --domain="${SERVICE_OS_DOMAIN_ID}" \ + --description "Service User for ${SERVICE_OS_REGION_NAME}/${SERVICE_OS_DOMAIN_NAME}" \ + --password="${SERVICE_OS_PASSWORD}" \ + "${SERVICE_OS_USERNAME}") + +# Display user +openstack user show "${SERVICE_OS_USERID}" + +# Manage role +SERVICE_OS_ROLE_ID=$(openstack role show -f value -c id \ + --domain="${SERVICE_OS_DOMAIN_ID}" \ + "${SERVICE_OS_ROLE}" || openstack role create -f value -c id \ + --domain="${SERVICE_OS_DOMAIN_ID}" \ + "${SERVICE_OS_ROLE}" ) + +# Manage user role assignment +openstack role add \ + --domain="${SERVICE_OS_DOMAIN_ID}" \ + --user="${SERVICE_OS_USERID}" \ + --user-domain="${SERVICE_OS_DOMAIN_ID}" \ + "${SERVICE_OS_ROLE_ID}" + +# Display user role assignment +openstack role assignment list \ + --role="${SERVICE_OS_ROLE_ID}" \ + --user-domain="${SERVICE_OS_DOMAIN_ID}" \ + --user="${SERVICE_OS_USERID}" +{{- end }} diff --git a/common/templates/scripts/_ks-endpoints.sh.tpl b/common/templates/scripts/_ks-endpoints.sh.tpl new file mode 100755 index 0000000000..1c70a499a1 --- /dev/null +++ b/common/templates/scripts/_ks-endpoints.sh.tpl @@ -0,0 +1,65 @@ +{{- define "common_keystone_endpoints" }} +#!/bin/bash + +# Copyright 2017 Pete Birley +# +# 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. + +set -ex + +# Get Service ID +OS_SERVICE_ID=$( openstack service list -f csv --quote none | \ + grep ",${OS_SERVICE_NAME},${OS_SERVICE_TYPE}$" | \ + sed -e "s/,${OS_SERVICE_NAME},${OS_SERVICE_TYPE}//g" ) + +# Get Endpoint ID if it exists +OS_ENDPOINT_ID=$( openstack endpoint list -f csv --quote none | \ + grep "^[a-z0-9]*,${OS_REGION_NAME},${OS_SERVICE_NAME},${OS_SERVICE_TYPE},True,${OS_SVC_ENDPOINT}," | \ + awk -F ',' '{ print $1 }' ) + +# Making sure only a single endpoint exists for a service within a region +if [ "$(echo $OS_ENDPOINT_ID | wc -w)" -gt "1" ]; then + echo "More than one endpoint found, cleaning up" + for ENDPOINT_ID in $OS_ENDPOINT_ID; do + openstack endpoint delete ${ENDPOINT_ID} + done + unset OS_ENDPOINT_ID +fi + +# Determine if Endpoint needs updated +if [[ ${OS_ENDPOINT_ID} ]]; then + OS_ENDPOINT_URL_CURRENT=$(openstack endpoint show ${OS_ENDPOINT_ID} --f value -c url) + if [ "${OS_ENDPOINT_URL_CURRENT}" == "${OS_SERVICE_ENDPOINT}" ]; then + echo "Endpoints Match: no action required" + OS_ENDPOINT_UPDATE="False" + else + echo "Endpoints Dont Match: removing existing entries" + openstack endpoint delete ${OS_ENDPOINT_ID} + OS_ENDPOINT_UPDATE="True" + fi +else + OS_ENDPOINT_UPDATE="True" +fi + +# Update Endpoint if required +if [[ "${OS_ENDPOINT_UPDATE}" == "True" ]]; then + OS_ENDPOINT_ID=$( openstack endpoint create -f value -c id \ + --region="${OS_REGION_NAME}" \ + "${OS_SERVICE_ID}" \ + ${OS_SVC_ENDPOINT} \ + "${OS_SERVICE_ENDPOINT}" ) +fi + +# Display the Endpoint +openstack endpoint show ${OS_ENDPOINT_ID} +{{- end }} diff --git a/common/templates/scripts/_ks-service.sh.tpl b/common/templates/scripts/_ks-service.sh.tpl new file mode 100644 index 0000000000..7c6f2580f3 --- /dev/null +++ b/common/templates/scripts/_ks-service.sh.tpl @@ -0,0 +1,37 @@ +{{- define "common_keystone_service" }} +#!/bin/bash + +# Copyright 2017 Pete Birley +# +# 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. + +set -ex + +# Service boilerplate description +OS_SERVICE_DESC="${OS_REGION_NAME}: ${OS_SERVICE_NAME} (${OS_SERVICE_TYPE}) service" + +# Get Service ID if it exists +unset OS_SERVICE_ID +OS_SERVICE_ID=$( openstack service list -f csv --quote none | \ + grep ",${OS_SERVICE_NAME},${OS_SERVICE_TYPE}$" | \ + sed -e "s/,${OS_SERVICE_NAME},${OS_SERVICE_TYPE}//g" ) + +# If a Service ID was not found, then create the service +if [[ -z ${OS_SERVICE_ID} ]]; then + OS_SERVICE_ID=$(openstack service create -f value -c id \ + --name="${OS_SERVICE_NAME}" \ + --description "${OS_SERVICE_DESC}" \ + --enable \ + "${OS_SERVICE_TYPE}") +fi +{{- end }} diff --git a/common/templates/scripts/_ks-user.sh.tpl b/common/templates/scripts/_ks-user.sh.tpl new file mode 100644 index 0000000000..e815da3049 --- /dev/null +++ b/common/templates/scripts/_ks-user.sh.tpl @@ -0,0 +1,60 @@ +{{- define "common_keystone_user" }} +#!/bin/bash + +# Copyright 2017 Pete Birley +# +# 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. + +set -ex + +# Manage user project +USER_PROJECT_DESC="Service Project for ${SERVICE_OS_REGION_NAME}/${SERVICE_OS_PROJECT_DOMAIN_NAME}" +USER_PROJECT_ID=$(openstack project create --or-show --enable -f value -c id \ + --domain="${SERVICE_OS_PROJECT_DOMAIN_NAME}" \ + --description="${USER_PROJECT_DESC}" \ + "${SERVICE_OS_PROJECT_NAME}"); + +# Display project +openstack project show "${USER_PROJECT_ID}" + +# Manage user +USER_DESC="Service User for ${SERVICE_OS_REGION_NAME}/${SERVICE_OS_USER_DOMAIN_NAME}/${SERVICE_OS_SERVICE_NAME}" +USER_ID=$(openstack user create --or-show --enable -f value -c id \ + --domain="${SERVICE_OS_USER_DOMAIN_NAME}" \ + --project-domain="${SERVICE_OS_PROJECT_DOMAIN_NAME}" \ + --project="${USER_PROJECT_ID}" \ + --description="${USER_DESC}" \ + --password="${SERVICE_OS_PASSWORD}" \ + "${SERVICE_OS_USERNAME}"); + +# Display user +openstack user show "${USER_ID}" + +# Manage user role +USER_ROLE_ID=$(openstack role create --or-show -f value -c id \ + "${SERVICE_OS_ROLE}"); + +# Manage user role assignment +openstack role add \ + --user="${USER_ID}" \ + --user-domain="${SERVICE_OS_USER_DOMAIN_NAME}" \ + --project-domain="${SERVICE_OS_PROJECT_DOMAIN_NAME}" \ + --project="${USER_PROJECT_ID}" \ + "${USER_ROLE_ID}" + +# Display user role assignment +openstack role assignment list \ + --role="${SERVICE_OS_ROLE}" \ + --user-domain="${SERVICE_OS_USER_DOMAIN_NAME}" \ + --user="${USER_ID}" +{{- end }} diff --git a/common/templates/snippets/_ks_env_openrc.tpl b/common/templates/snippets/_ks_env_openrc.tpl new file mode 100644 index 0000000000..140ce25c97 --- /dev/null +++ b/common/templates/snippets/_ks_env_openrc.tpl @@ -0,0 +1,40 @@ +{{- define "env_ks_openrc_tpl" }} +{{- $ksUserSecret := .ksUserSecret }} +- name: OS_IDENTITY_API_VERSION + value: "3" +- name: OS_AUTH_URL + valueFrom: + secretKeyRef: + name: {{ $ksUserSecret }} + key: OS_AUTH_URL +- name: OS_REGION_NAME + valueFrom: + secretKeyRef: + name: {{ $ksUserSecret }} + key: OS_REGION_NAME +- name: OS_PROJECT_DOMAIN_NAME + valueFrom: + secretKeyRef: + name: {{ $ksUserSecret }} + key: OS_PROJECT_DOMAIN_NAME +- name: OS_PROJECT_NAME + valueFrom: + secretKeyRef: + name: {{ $ksUserSecret }} + key: OS_PROJECT_NAME +- name: OS_USER_DOMAIN_NAME + valueFrom: + secretKeyRef: + name: {{ $ksUserSecret }} + key: OS_USER_DOMAIN_NAME +- name: OS_USERNAME + valueFrom: + secretKeyRef: + name: {{ $ksUserSecret }} + key: OS_USERNAME +- name: OS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ $ksUserSecret }} + key: OS_PASSWORD +{{- end }} diff --git a/common/templates/snippets/_ks_env_user_create_openrc.tpl b/common/templates/snippets/_ks_env_user_create_openrc.tpl new file mode 100644 index 0000000000..5ce6e58077 --- /dev/null +++ b/common/templates/snippets/_ks_env_user_create_openrc.tpl @@ -0,0 +1,33 @@ +{{- define "env_ks_user_create_openrc_tpl" }} +{{- $ksUserSecret := .ksUserSecret }} +- name: SERVICE_OS_REGION_NAME + valueFrom: + secretKeyRef: + name: {{ $ksUserSecret }} + key: OS_REGION_NAME +- name: SERVICE_OS_PROJECT_DOMAIN_NAME + valueFrom: + secretKeyRef: + name: {{ $ksUserSecret }} + key: OS_PROJECT_DOMAIN_NAME +- name: SERVICE_OS_PROJECT_NAME + valueFrom: + secretKeyRef: + name: {{ $ksUserSecret }} + key: OS_PROJECT_NAME +- name: SERVICE_OS_USER_DOMAIN_NAME + valueFrom: + secretKeyRef: + name: {{ $ksUserSecret }} + key: OS_USER_DOMAIN_NAME +- name: SERVICE_OS_USERNAME + valueFrom: + secretKeyRef: + name: {{ $ksUserSecret }} + key: OS_USERNAME +- name: SERVICE_OS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ $ksUserSecret }} + key: OS_PASSWORD +{{- end }} diff --git a/docs/developer/minikube.md b/docs/developer/minikube.md index b005c3ff9f..4ee88495a8 100644 --- a/docs/developer/minikube.md +++ b/docs/developer/minikube.md @@ -163,6 +163,7 @@ $ helm install --name=horizon local/horizon --namespace=openstack $ helm install --name=glance local/glance --namespace=openstack $ helm install --name=nova local/nova --namespace=openstack $ helm install --name=neutron local/neutron --namespace=openstack +$ helm install --name=heat local/heat --namespace=openstack ``` # Horizon Management @@ -173,7 +174,7 @@ After each chart is deployed, you may wish to change the typical service endpoin $ sudo kubectl edit svc horizon -n openstack ``` -With the deployed manifest in edit mode, you can enable `nodePort` by replicating some of the fields below (specifically, the `nodePort` lines). +With the deployed manifest in edit mode, you can enable `nodePort` by replicating some of the fields below (specifically, the `nodePort` lines). ``` apiVersion: v1 @@ -224,7 +225,7 @@ $ kubectl exec mariadb-0 -it -n openstack -- mysql -uroot -ppassword -e 'show da | mysql | | performance_schema | +--------------------+ -$ +$ ``` **Helm Server/Repository**
@@ -251,7 +252,7 @@ $ helm repo list NAME URL stable https://kubernetes-charts.storage.googleapis.com/ local http://localhost:8879/charts -$ +$ $ helm repo remove local ``` diff --git a/heat/Chart.yaml b/heat/Chart.yaml new file mode 100644 index 0000000000..65c0ea4b74 --- /dev/null +++ b/heat/Chart.yaml @@ -0,0 +1,3 @@ +description: A Helm chart for heat +name: heat +version: 0.1.0 diff --git a/heat/requirements.yaml b/heat/requirements.yaml new file mode 100644 index 0000000000..2350b1facb --- /dev/null +++ b/heat/requirements.yaml @@ -0,0 +1,4 @@ +dependencies: + - name: common + repository: http://localhost:8879/charts + version: 0.1.0 diff --git a/heat/templates/bin/_db-init.sh.tpl b/heat/templates/bin/_db-init.sh.tpl new file mode 100644 index 0000000000..ba1c302c03 --- /dev/null +++ b/heat/templates/bin/_db-init.sh.tpl @@ -0,0 +1,21 @@ +#!/bin/bash +set -ex +export HOME=/tmp + +ansible localhost -vvv \ + -m mysql_db -a "login_host='{{ .Values.database.address }}' \ + login_port='{{ .Values.database.port }}' \ + login_user='{{ .Values.database.root_user }}' \ + login_password='{{ .Values.database.root_password }}' \ + name='{{ .Values.database.heat_database_name }}'" + +ansible localhost -vvv \ + -m mysql_user -a "login_host='{{ .Values.database.address }}' \ + login_port='{{ .Values.database.port }}' \ + login_user='{{ .Values.database.root_user }}' \ + login_password='{{ .Values.database.root_password }}' \ + name='{{ .Values.database.heat_user }}' \ + password='{{ .Values.database.heat_password }}' \ + host='%' \ + priv='{{ .Values.database.heat_database_name }}.*:ALL' \ + append_privs='yes'" diff --git a/heat/templates/configmap-bin.yaml b/heat/templates/configmap-bin.yaml new file mode 100644 index 0000000000..27da8c6947 --- /dev/null +++ b/heat/templates/configmap-bin.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: heat-bin +data: + db-init.sh: |+ +{{ tuple "bin/_db-init.sh.tpl" . | include "template" | indent 4 }} + ks-service.sh: |+ +{{- include "common_keystone_service" . | indent 4 }} + ks-endpoints.sh: |+ +{{- include "common_keystone_endpoints" . | indent 4 }} + ks-user.sh: |+ +{{- include "common_keystone_user" . | indent 4 }} + ks-domain-user.sh: |+ +{{- include "common_keystone_domain_user" . | indent 4 }} diff --git a/heat/templates/configmap-etc.yaml b/heat/templates/configmap-etc.yaml new file mode 100644 index 0000000000..c3039714c8 --- /dev/null +++ b/heat/templates/configmap-etc.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: heat-etc +data: + heat.conf: |+ +{{ tuple "etc/_heat.conf.tpl" . | include "template" | indent 4 }} + api-paste.ini: |+ +{{ tuple "etc/_heat-api-paste.ini.tpl" . | include "template" | indent 4 }} + policy.json: |+ +{{ tuple "etc/_heat-policy.json.tpl" . | include "template" | indent 4 }} diff --git a/heat/templates/deployment-api.yaml b/heat/templates/deployment-api.yaml new file mode 100755 index 0000000000..759571c4e3 --- /dev/null +++ b/heat/templates/deployment-api.yaml @@ -0,0 +1,83 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: heat-api +spec: + replicas: {{ .Values.replicas.api }} + template: + metadata: + labels: + app: heat-api + annotations: + pod.beta.kubernetes.io/init-containers: '[ + { + "name": "init", + "image": {{ .Values.images.dep_check | quote }}, + "imagePullPolicy": {{ .Values.images.pull_policy | quote }}, + "env": [ + { + "name": "NAMESPACE", + "value": "{{ .Release.Namespace }}" + }, + { + "name": "DEPENDENCY_SERVICE", + "value": "{{ include "joinListWithColon" .Values.dependencies.api.service }}" + }, + { + "name": "DEPENDENCY_JOBS", + "value": "{{ include "joinListWithColon" .Values.dependencies.api.jobs }}" + }, + { + "name": "COMMAND", + "value": "echo done" + } + ] + } + ]' + spec: + nodeSelector: + {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }} + containers: + - name: heat-api + image: {{ .Values.images.api }} + imagePullPolicy: {{ .Values.images.pull_policy }} + command: + - heat-api + - --config-dir + - /etc/heat/conf + ports: + - containerPort: {{ .Values.service.api.port }} + readinessProbe: + tcpSocket: + port: {{ .Values.service.api.port }} + volumeMounts: + - name: pod-etc-heat + mountPath: /etc/heat + - name: pod-var-cache-heat + mountPath: /var/cache/heat + - name: heatconf + mountPath: /etc/heat/conf/heat.conf + subPath: heat.conf + readOnly: true + - name: heatpaste + mountPath: /etc/heat/api-paste.ini + subPath: api-paste.ini + readOnly: true + - name: heatpolicy + mountPath: /etc/heat/policy.json + subPath: policy.json + readOnly: true + volumes: + - name: pod-etc-heat + emptyDir: {} + - name: pod-var-cache-heat + emptyDir: {} + - name: heatconf + configMap: + name: heat-etc + - name: heatpaste + configMap: + name: heat-etc + - name: heatpolicy + configMap: + name: heat-etc diff --git a/heat/templates/deployment-cfn.yaml b/heat/templates/deployment-cfn.yaml new file mode 100644 index 0000000000..94d6d55e35 --- /dev/null +++ b/heat/templates/deployment-cfn.yaml @@ -0,0 +1,83 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: heat-cfn +spec: + replicas: {{ .Values.replicas.cfn }} + template: + metadata: + labels: + app: heat-cfn + annotations: + pod.beta.kubernetes.io/init-containers: '[ + { + "name": "init", + "image": {{ .Values.images.dep_check | quote }}, + "imagePullPolicy": {{ .Values.images.pull_policy | quote }}, + "env": [ + { + "name": "NAMESPACE", + "value": "{{ .Release.Namespace }}" + }, + { + "name": "DEPENDENCY_SERVICE", + "value": "{{ include "joinListWithColon" .Values.dependencies.cfn.service }}" + }, + { + "name": "DEPENDENCY_JOBS", + "value": "{{ include "joinListWithColon" .Values.dependencies.cfn.jobs }}" + }, + { + "name": "COMMAND", + "value": "echo done" + } + ] + } + ]' + spec: + nodeSelector: + {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }} + containers: + - name: heat-cfn + image: {{ .Values.images.cfn }} + imagePullPolicy: {{ .Values.images.pull_policy }} + command: + - heat-api-cfn + - --config-dir + - /etc/heat/conf + ports: + - containerPort: {{ .Values.service.cfn.port }} + readinessProbe: + tcpSocket: + port: {{ .Values.service.cfn.port }} + volumeMounts: + - name: pod-etc-heat + mountPath: /etc/heat + - name: pod-var-cache-heat + mountPath: /var/cache/heat + - name: heatconf + mountPath: /etc/heat/conf/heat.conf + subPath: heat.conf + readOnly: true + - name: heatpaste + mountPath: /etc/heat/api-paste.ini + subPath: api-paste.ini + readOnly: true + - name: heatpolicy + mountPath: /etc/heat/policy.json + subPath: policy.json + readOnly: true + volumes: + - name: pod-etc-heat + emptyDir: {} + - name: pod-var-cache-heat + emptyDir: {} + - name: heatconf + configMap: + name: heat-etc + - name: heatpaste + configMap: + name: heat-etc + - name: heatpolicy + configMap: + name: heat-etc diff --git a/heat/templates/deployment-cloudwatch.yaml b/heat/templates/deployment-cloudwatch.yaml new file mode 100644 index 0000000000..d4753011c6 --- /dev/null +++ b/heat/templates/deployment-cloudwatch.yaml @@ -0,0 +1,83 @@ +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: heat-cloudwatch +spec: + replicas: {{ .Values.replicas.cloudwatch }} + template: + metadata: + labels: + app: heat-cloudwatch + annotations: + pod.beta.kubernetes.io/init-containers: '[ + { + "name": "init", + "image": {{ .Values.images.dep_check | quote }}, + "imagePullPolicy": {{ .Values.images.pull_policy | quote }}, + "env": [ + { + "name": "NAMESPACE", + "value": "{{ .Release.Namespace }}" + }, + { + "name": "DEPENDENCY_SERVICE", + "value": "{{ include "joinListWithColon" .Values.dependencies.cloudwatch.service }}" + }, + { + "name": "DEPENDENCY_JOBS", + "value": "{{ include "joinListWithColon" .Values.dependencies.cloudwatch.jobs }}" + }, + { + "name": "COMMAND", + "value": "echo done" + } + ] + } + ]' + spec: + nodeSelector: + {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }} + containers: + - name: heat-cloudwatch + image: {{ .Values.images.cloudwatch }} + imagePullPolicy: {{ .Values.images.pull_policy }} + command: + - heat-api-cloudwatch + - --config-dir + - /etc/heat/conf + ports: + - containerPort: {{ .Values.service.cloudwatch.port }} + readinessProbe: + tcpSocket: + port: {{ .Values.service.cloudwatch.port }} + volumeMounts: + - name: pod-etc-heat + mountPath: /etc/heat + - name: pod-var-cache-heat + mountPath: /var/cache/heat + - name: heatconf + mountPath: /etc/heat/conf/heat.conf + subPath: heat.conf + readOnly: true + - name: heatpaste + mountPath: /etc/heat/api-paste.ini + subPath: api-paste.ini + readOnly: true + - name: heatpolicy + mountPath: /etc/heat/policy.json + subPath: policy.json + readOnly: true + volumes: + - name: pod-etc-heat + emptyDir: {} + - name: pod-var-cache-heat + emptyDir: {} + - name: heatconf + configMap: + name: heat-etc + - name: heatpaste + configMap: + name: heat-etc + - name: heatpolicy + configMap: + name: heat-etc diff --git a/heat/templates/etc/_heat-api-paste.ini.tpl b/heat/templates/etc/_heat-api-paste.ini.tpl new file mode 100644 index 0000000000..ad6501e662 --- /dev/null +++ b/heat/templates/etc/_heat-api-paste.ini.tpl @@ -0,0 +1,104 @@ +# heat-api pipeline +[pipeline:heat-api] +pipeline = cors request_id faultwrap http_proxy_to_wsgi versionnegotiation osprofiler authurl authtoken context apiv1app + +# heat-api pipeline for standalone heat +# ie. uses alternative auth backend that authenticates users against keystone +# using username and password instead of validating token (which requires +# an admin/service token). +# To enable, in heat.conf: +# [paste_deploy] +# flavor = standalone +# +[pipeline:heat-api-standalone] +pipeline = cors request_id faultwrap http_proxy_to_wsgi versionnegotiation authurl authpassword context apiv1app + +# heat-api pipeline for custom cloud backends +# i.e. in heat.conf: +# [paste_deploy] +# flavor = custombackend +# +[pipeline:heat-api-custombackend] +pipeline = cors request_id faultwrap versionnegotiation context custombackendauth apiv1app + +# heat-api-cfn pipeline +[pipeline:heat-api-cfn] +pipeline = cors cfnversionnegotiation osprofiler ec2authtoken authtoken context apicfnv1app + +# heat-api-cfn pipeline for standalone heat +# relies exclusively on authenticating with ec2 signed requests +[pipeline:heat-api-cfn-standalone] +pipeline = cors cfnversionnegotiation ec2authtoken context apicfnv1app + +# heat-api-cloudwatch pipeline +[pipeline:heat-api-cloudwatch] +pipeline = cors versionnegotiation osprofiler ec2authtoken authtoken context apicwapp + +# heat-api-cloudwatch pipeline for standalone heat +# relies exclusively on authenticating with ec2 signed requests +[pipeline:heat-api-cloudwatch-standalone] +pipeline = cors versionnegotiation ec2authtoken context apicwapp + +[app:apiv1app] +paste.app_factory = heat.common.wsgi:app_factory +heat.app_factory = heat.api.openstack.v1:API + +[app:apicfnv1app] +paste.app_factory = heat.common.wsgi:app_factory +heat.app_factory = heat.api.cfn.v1:API + +[app:apicwapp] +paste.app_factory = heat.common.wsgi:app_factory +heat.app_factory = heat.api.cloudwatch:API + +[filter:versionnegotiation] +paste.filter_factory = heat.common.wsgi:filter_factory +heat.filter_factory = heat.api.openstack:version_negotiation_filter + +[filter:cors] +paste.filter_factory = oslo_middleware.cors:filter_factory +oslo_config_project = heat + +[filter:faultwrap] +paste.filter_factory = heat.common.wsgi:filter_factory +heat.filter_factory = heat.api.openstack:faultwrap_filter + +[filter:cfnversionnegotiation] +paste.filter_factory = heat.common.wsgi:filter_factory +heat.filter_factory = heat.api.cfn:version_negotiation_filter + +[filter:cwversionnegotiation] +paste.filter_factory = heat.common.wsgi:filter_factory +heat.filter_factory = heat.api.cloudwatch:version_negotiation_filter + +[filter:context] +paste.filter_factory = heat.common.context:ContextMiddleware_filter_factory + +[filter:ec2authtoken] +paste.filter_factory = heat.api.aws.ec2token:EC2Token_filter_factory + +[filter:http_proxy_to_wsgi] +paste.filter_factory = oslo_middleware:HTTPProxyToWSGI.factory + +# Middleware to set auth_url header appropriately +[filter:authurl] +paste.filter_factory = heat.common.auth_url:filter_factory + +# Auth middleware that validates token against keystone +[filter:authtoken] +paste.filter_factory = keystonemiddleware.auth_token:filter_factory + +# Auth middleware that validates username/password against keystone +[filter:authpassword] +paste.filter_factory = heat.common.auth_password:filter_factory + +# Auth middleware that validates against custom backend +[filter:custombackendauth] +paste.filter_factory = heat.common.custom_backend_auth:filter_factory + +# Middleware to set x-openstack-request-id in http response header +[filter:request_id] +paste.filter_factory = oslo_middleware.request_id:RequestId.factory + +[filter:osprofiler] +paste.filter_factory = osprofiler.web:WsgiMiddleware.factory diff --git a/heat/templates/etc/_heat-policy.json.tpl b/heat/templates/etc/_heat-policy.json.tpl new file mode 100644 index 0000000000..c9aae5ff79 --- /dev/null +++ b/heat/templates/etc/_heat-policy.json.tpl @@ -0,0 +1,96 @@ +{ + "context_is_admin": "role:admin and is_admin_project:True", + "project_admin": "role:admin", + "deny_stack_user": "not role:heat_stack_user", + "deny_everybody": "!", + + "cloudformation:ListStacks": "rule:deny_stack_user", + "cloudformation:CreateStack": "rule:deny_stack_user", + "cloudformation:DescribeStacks": "rule:deny_stack_user", + "cloudformation:DeleteStack": "rule:deny_stack_user", + "cloudformation:UpdateStack": "rule:deny_stack_user", + "cloudformation:CancelUpdateStack": "rule:deny_stack_user", + "cloudformation:DescribeStackEvents": "rule:deny_stack_user", + "cloudformation:ValidateTemplate": "rule:deny_stack_user", + "cloudformation:GetTemplate": "rule:deny_stack_user", + "cloudformation:EstimateTemplateCost": "rule:deny_stack_user", + "cloudformation:DescribeStackResource": "", + "cloudformation:DescribeStackResources": "rule:deny_stack_user", + "cloudformation:ListStackResources": "rule:deny_stack_user", + + "cloudwatch:DeleteAlarms": "rule:deny_stack_user", + "cloudwatch:DescribeAlarmHistory": "rule:deny_stack_user", + "cloudwatch:DescribeAlarms": "rule:deny_stack_user", + "cloudwatch:DescribeAlarmsForMetric": "rule:deny_stack_user", + "cloudwatch:DisableAlarmActions": "rule:deny_stack_user", + "cloudwatch:EnableAlarmActions": "rule:deny_stack_user", + "cloudwatch:GetMetricStatistics": "rule:deny_stack_user", + "cloudwatch:ListMetrics": "rule:deny_stack_user", + "cloudwatch:PutMetricAlarm": "rule:deny_stack_user", + "cloudwatch:PutMetricData": "", + "cloudwatch:SetAlarmState": "rule:deny_stack_user", + + "actions:action": "rule:deny_stack_user", + "build_info:build_info": "rule:deny_stack_user", + "events:index": "rule:deny_stack_user", + "events:show": "rule:deny_stack_user", + "resource:index": "rule:deny_stack_user", + "resource:metadata": "", + "resource:signal": "", + "resource:mark_unhealthy": "rule:deny_stack_user", + "resource:show": "rule:deny_stack_user", + "stacks:abandon": "rule:deny_stack_user", + "stacks:create": "rule:deny_stack_user", + "stacks:delete": "rule:deny_stack_user", + "stacks:detail": "rule:deny_stack_user", + "stacks:export": "rule:deny_stack_user", + "stacks:generate_template": "rule:deny_stack_user", + "stacks:global_index": "rule:deny_everybody", + "stacks:index": "rule:deny_stack_user", + "stacks:list_resource_types": "rule:deny_stack_user", + "stacks:list_template_versions": "rule:deny_stack_user", + "stacks:list_template_functions": "rule:deny_stack_user", + "stacks:lookup": "", + "stacks:preview": "rule:deny_stack_user", + "stacks:resource_schema": "rule:deny_stack_user", + "stacks:show": "rule:deny_stack_user", + "stacks:template": "rule:deny_stack_user", + "stacks:environment": "rule:deny_stack_user", + "stacks:files": "rule:deny_stack_user", + "stacks:update": "rule:deny_stack_user", + "stacks:update_patch": "rule:deny_stack_user", + "stacks:preview_update": "rule:deny_stack_user", + "stacks:preview_update_patch": "rule:deny_stack_user", + "stacks:validate_template": "rule:deny_stack_user", + "stacks:snapshot": "rule:deny_stack_user", + "stacks:show_snapshot": "rule:deny_stack_user", + "stacks:delete_snapshot": "rule:deny_stack_user", + "stacks:list_snapshots": "rule:deny_stack_user", + "stacks:restore_snapshot": "rule:deny_stack_user", + "stacks:list_outputs": "rule:deny_stack_user", + "stacks:show_output": "rule:deny_stack_user", + + "software_configs:global_index": "rule:deny_everybody", + "software_configs:index": "rule:deny_stack_user", + "software_configs:create": "rule:deny_stack_user", + "software_configs:show": "rule:deny_stack_user", + "software_configs:delete": "rule:deny_stack_user", + "software_deployments:index": "rule:deny_stack_user", + "software_deployments:create": "rule:deny_stack_user", + "software_deployments:show": "rule:deny_stack_user", + "software_deployments:update": "rule:deny_stack_user", + "software_deployments:delete": "rule:deny_stack_user", + "software_deployments:metadata": "", + + "service:index": "rule:context_is_admin", + + "resource_types:OS::Nova::Flavor": "rule:project_admin", + "resource_types:OS::Cinder::EncryptedVolumeType": "rule:project_admin", + "resource_types:OS::Cinder::VolumeType": "rule:project_admin", + "resource_types:OS::Cinder::Quota": "rule:project_admin", + "resource_types:OS::Manila::ShareType": "rule:project_admin", + "resource_types:OS::Neutron::QoSPolicy": "rule:project_admin", + "resource_types:OS::Neutron::QoSBandwidthLimitRule": "rule:project_admin", + "resource_types:OS::Nova::HostAggregate": "rule:project_admin", + "resource_types:OS::Cinder::QoSSpecs": "rule:project_admin" +} diff --git a/heat/templates/etc/_heat.conf.tpl b/heat/templates/etc/_heat.conf.tpl new file mode 100644 index 0000000000..e902fe7114 --- /dev/null +++ b/heat/templates/etc/_heat.conf.tpl @@ -0,0 +1,82 @@ +[DEFAULT] +debug = {{ .Values.misc.debug }} +use_syslog = False +use_stderr = True + +deferred_auth_method = "trusts" + +enable_stack_adopt = "True" +enable_stack_abandon = "True" + +heat_metadata_server_url = {{ .Values.service.cfn.proto }}://{{ .Values.service.cfn.name }}:{{ .Values.service.cfn.port }} +heat_waitcondition_server_url = {{ .Values.service.cfn.proto }}://{{ .Values.service.cfn.name }}:{{ .Values.service.cfn.port }}/v1/waitcondition +heat_watch_server_url = {{ .Values.service.cloudwatch.proto }}://{{ .Values.service.cloudwatch.name }}:{{ .Values.service.cloudwatch.port }} + +num_engine_workers = {{ .Values.resources.engine.workers }} + +stack_user_domain_name = {{ .Values.keystone.heat_stack_user_domain }} +stack_domain_admin = {{ .Values.keystone.heat_stack_user }} +stack_domain_admin_password = {{ .Values.keystone.heat_stack_password }} + +trusts_delegated_roles = "Member" + +[cache] +enabled = "True" +backend = oslo_cache.memcache_pool +memcache_servers = "{{ .Values.memcached.host }}:{{ .Values.memcached.port }}" + +[database] +connection = mysql+pymysql://{{ .Values.database.heat_user }}:{{ .Values.database.heat_password }}@{{ .Values.database.address }}:{{ .Values.database.port }}/{{ .Values.database.heat_database_name }} +max_retries = -1 + +[keystone_authtoken] +signing_dir = "/var/cache/heat" +memcached_servers = "{{ .Values.memcached.host }}:{{ .Values.memcached.port }}" +auth_version = v3 +auth_url = {{ include "endpoint_keystone_internal" . }} +auth_type = password +region_name = {{ .Values.keystone.heat_region_name }} +project_domain_name = {{ .Values.keystone.heat_project_domain }} +project_name = {{ .Values.keystone.heat_project_name }} +user_domain_name = {{ .Values.keystone.heat_user_domain }} +username = {{ .Values.keystone.heat_user }} +password = {{ .Values.keystone.heat_password }} + +[heat_api] +bind_port = {{ .Values.service.api.port }} +bind_host = 0.0.0.0 +workers = {{ .Values.resources.api.workers }} + +[heat_api_cloudwatch] +bind_port = {{ .Values.service.cloudwatch.port }} +bind_host = 0.0.0.0 +workers = {{ .Values.resources.cloudwatch.workers }} + +[heat_api_cfn] +bind_port = {{ .Values.service.cfn.port }} +bind_host = 0.0.0.0 +workers = {{ .Values.resources.cfn.workers }} + +[oslo_messaging_rabbit] +rabbit_userid = {{ .Values.messaging.user }} +rabbit_password = {{ .Values.messaging.password }} +rabbit_ha_queues = true +rabbit_hosts = {{ .Values.messaging.hosts }} + +[paste_deploy] +config_file = /etc/heat/api-paste.ini + +[trustee] +auth_type = "password" +auth_section = "trustee_keystone" + +[trustee_keystone] +signing_dir = "/var/cache/heat" +memcached_servers = "{{ .Values.memcached.host }}:{{ .Values.memcached.port }}" +auth_version = v3 +auth_url = {{ include "endpoint_keystone_internal" . }} +auth_type = password +region_name = {{ .Values.keystone.heat_trustee_region_name }} +user_domain_name = {{ .Values.keystone.heat_trustee_user_domain }} +username = {{ .Values.keystone.heat_trustee_user }} +password = {{ .Values.keystone.heat_trustee_password }} diff --git a/heat/templates/job-db-init.yaml b/heat/templates/job-db-init.yaml new file mode 100644 index 0000000000..affd85693c --- /dev/null +++ b/heat/templates/job-db-init.yaml @@ -0,0 +1,54 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: heat-db-init +spec: + template: + metadata: + annotations: + pod.beta.kubernetes.io/init-containers: '[ + { + "name": "init", + "image": {{ .Values.images.dep_check | quote }}, + "imagePullPolicy": {{ .Values.images.pull_policy | quote }}, + "env": [ + { + "name": "NAMESPACE", + "value": "{{ .Release.Namespace }}" + }, + { + "name": "DEPENDENCY_SERVICE", + "value": "{{ include "joinListWithColon" .Values.dependencies.db_init.service }}" + }, + { + "name": "DEPENDENCY_JOBS", + "value": "{{ include "joinListWithColon" .Values.dependencies.db_init.jobs }}" + }, + { + "name": "COMMAND", + "value": "echo done" + } + ] + } + ]' + spec: + restartPolicy: OnFailure + containers: + - name: heat-db-init + image: {{ .Values.images.db_init | quote }} + imagePullPolicy: {{ .Values.images.pull_policy | quote }} + env: + - name: ANSIBLE_LIBRARY + value: /usr/share/ansible/ + command: + - bash + - /tmp/db-init.sh + volumeMounts: + - name: dbinitsh + mountPath: /tmp/db-init.sh + subPath: db-init.sh + readOnly: true + volumes: + - name: dbinitsh + configMap: + name: heat-bin diff --git a/heat/templates/job-db-sync.yaml b/heat/templates/job-db-sync.yaml new file mode 100644 index 0000000000..3c66c4c5af --- /dev/null +++ b/heat/templates/job-db-sync.yaml @@ -0,0 +1,58 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: heat-db-sync +spec: + template: + metadata: + annotations: + pod.beta.kubernetes.io/init-containers: '[ + { + "name": "init", + "image": {{ .Values.images.dep_check | quote }}, + "imagePullPolicy": {{ .Values.images.pull_policy | quote }}, + "env": [ + { + "name": "NAMESPACE", + "value": "{{ .Release.Namespace }}" + }, + { + "name": "DEPENDENCY_SERVICE", + "value": "{{ include "joinListWithColon" .Values.dependencies.db_sync.service }}" + }, + { + "name": "DEPENDENCY_JOBS", + "value": "{{ include "joinListWithColon" .Values.dependencies.db_sync.jobs }}" + }, + { + "name": "COMMAND", + "value": "echo done" + } + ] + } + ]' + spec: + restartPolicy: OnFailure + containers: + - name: heat-db-sync + image: {{ .Values.images.db_sync }} + imagePullPolicy: {{ .Values.images.pull_policy }} + command: + - heat-manage + args: + - --config-dir + - /etc/heat/conf + - db_sync + volumeMounts: + - name: pod-etc-heat + mountPath: /etc/heat + - name: heatconf + mountPath: /etc/heat/conf/heat.conf + subPath: heat.conf + readOnly: true + volumes: + - name: pod-etc-heat + emptyDir: {} + - name: heatconf + configMap: + name: heat-etc diff --git a/heat/templates/job-ks-endpoints.yaml.yaml b/heat/templates/job-ks-endpoints.yaml.yaml new file mode 100644 index 0000000000..4b3f30036a --- /dev/null +++ b/heat/templates/job-ks-endpoints.yaml.yaml @@ -0,0 +1,65 @@ +{{- $envAll := . }} +{{- $ksAdminSecret := .Values.keystone_secrets.admin }} +apiVersion: batch/v1 +kind: Job +metadata: + name: heat-ks-endpoints +spec: + template: + metadata: + annotations: + pod.beta.kubernetes.io/init-containers: '[ + { + "name": "init", + "image": {{ .Values.images.dep_check | quote }}, + "imagePullPolicy": {{ .Values.images.pull_policy | quote }}, + "env": [ + { + "name": "NAMESPACE", + "value": "{{ .Release.Namespace }}" + }, + { + "name": "DEPENDENCY_SERVICE", + "value": "{{ include "joinListWithColon" .Values.dependencies.ks_service.service }}" + }, + { + "name": "COMMAND", + "value": "echo done" + } + ] + } + ]' + spec: + restartPolicy: OnFailure + containers: +{{- range $key1, $osServiceName := tuple "heat" "heat-cfn" }} +{{- range $key2, $osServiceEndPoint := tuple "admin" "internal" "public" }} + - name: {{ $osServiceName }}-ks-endpoints-{{ $osServiceEndPoint }} + image: {{ $envAll.Values.images.ks_endpoints }} + imagePullPolicy: {{ $envAll.Values.images.pull_policy }} + command: + - bash + - /tmp/ks-endpoints.sh + volumeMounts: + - name: ks-endpoints-sh + mountPath: /tmp/ks-endpoints.sh + subPath: ks-endpoints.sh + readOnly: true + env: +{{- with $env := dict "ksUserSecret" $ksAdminSecret }} +{{- include "env_ks_openrc_tpl" $env | indent 12 }} +{{- end }} + - name: OS_SVC_ENDPOINT + value: {{ $osServiceEndPoint }} + - name: OS_SERVICE_NAME + value: {{ $osServiceName }} + - name: OS_SERVICE_TYPE + value: {{ tuple $osServiceName $envAll | include "endpoint_type_lookup" }} + - name: OS_SERVICE_ENDPOINT + value: {{ tuple $osServiceName $osServiceEndPoint "api" $envAll | include "endpoint_addr_lookup" }} +{{- end }} +{{- end }} + volumes: + - name: ks-endpoints-sh + configMap: + name: heat-bin diff --git a/heat/templates/job-ks-service.yaml b/heat/templates/job-ks-service.yaml new file mode 100644 index 0000000000..3ce06a12a1 --- /dev/null +++ b/heat/templates/job-ks-service.yaml @@ -0,0 +1,59 @@ +{{- $envAll := . }} +{{- $ksAdminSecret := .Values.keystone_secrets.admin }} +apiVersion: batch/v1 +kind: Job +metadata: + name: heat-ks-service +spec: + template: + metadata: + annotations: + pod.beta.kubernetes.io/init-containers: '[ + { + "name": "init", + "image": {{ .Values.images.dep_check | quote }}, + "imagePullPolicy": {{ .Values.images.pull_policy | quote }}, + "env": [ + { + "name": "NAMESPACE", + "value": "{{ .Release.Namespace }}" + }, + { + "name": "DEPENDENCY_SERVICE", + "value": "{{ include "joinListWithColon" .Values.dependencies.ks_service.service }}" + }, + { + "name": "COMMAND", + "value": "echo done" + } + ] + } + ]' + spec: + restartPolicy: OnFailure + containers: +{{- range $key1, $osServiceName := tuple "heat" "heat-cfn" }} + - name: {{ $osServiceName }}-ks-service-registration + image: {{ $envAll.Values.images.ks_service }} + imagePullPolicy: {{ $envAll.Values.images.pull_policy }} + command: + - bash + - /tmp/ks-service.sh + volumeMounts: + - name: ks-service-sh + mountPath: /tmp/ks-service.sh + subPath: ks-service.sh + readOnly: true + env: +{{- with $env := dict "ksUserSecret" $ksAdminSecret }} +{{- include "env_ks_openrc_tpl" $env | indent 12 }} +{{- end }} + - name: OS_SERVICE_NAME + value: {{ $osServiceName }} + - name: OS_SERVICE_TYPE + value: {{ tuple $osServiceName $envAll | include "endpoint_type_lookup" }} +{{- end }} + volumes: + - name: ks-service-sh + configMap: + name: heat-bin diff --git a/heat/templates/job-ks-user.yaml b/heat/templates/job-ks-user.yaml new file mode 100644 index 0000000000..66981c9f0d --- /dev/null +++ b/heat/templates/job-ks-user.yaml @@ -0,0 +1,124 @@ +{{- $ksAdminSecret := .Values.keystone_secrets.admin }} +{{- $ksUserSecret := .Values.keystone_secrets.user }} +# The heat user management job is a bit different from other services as it also needs to create a stack domain and trusts user +{{- $ksTrusteeUserSecret := .Values.keystone_secrets.trustee }} +{{- $ksStackUserSecret := .Values.keystone_secrets.stack }} +apiVersion: batch/v1 +kind: Job +metadata: + name: heat-ks-user +spec: + template: + metadata: + annotations: + pod.beta.kubernetes.io/init-containers: '[ + { + "name": "init", + "image": {{ .Values.images.dep_check | quote }}, + "imagePullPolicy": {{ .Values.images.pull_policy | quote }}, + "env": [ + { + "name": "NAMESPACE", + "value": "{{ .Release.Namespace }}" + }, + { + "name": "DEPENDENCY_SERVICE", + "value": "{{ include "joinListWithColon" .Values.dependencies.ks_user.service }}" + }, + { + "name": "COMMAND", + "value": "echo done" + } + ] + } + ]' + spec: + restartPolicy: OnFailure + containers: + - name: heat-ks-user + image: {{ .Values.images.ks_user }} + imagePullPolicy: {{ .Values.images.pull_policy }} + command: + - bash + - /tmp/ks-user.sh + volumeMounts: + - name: ks-user-sh + mountPath: /tmp/ks-user.sh + subPath: ks-user.sh + readOnly: true + env: +{{- with $env := dict "ksUserSecret" $ksAdminSecret }} +{{- include "env_ks_openrc_tpl" $env | indent 12 }} +{{- end }} + - name: SERVICE_OS_SERVICE_NAME + value: "heat" +{{- with $env := dict "ksUserSecret" $ksUserSecret }} +{{- include "env_ks_user_create_openrc_tpl" $env | indent 12 }} +{{- end }} + - name: SERVICE_OS_ROLE + value: {{ .Values.keystone.heat_user_role | quote }} + - name: heat-ks-trustee-user + image: {{ .Values.images.ks_user }} + imagePullPolicy: {{ .Values.images.pull_policy }} + command: + - bash + - /tmp/ks-user.sh + volumeMounts: + - name: ks-user-sh + mountPath: /tmp/ks-user.sh + subPath: ks-user.sh + readOnly: true + env: +{{- with $env := dict "ksUserSecret" $ksAdminSecret }} +{{- include "env_ks_openrc_tpl" $env | indent 12 }} +{{- end }} + - name: SERVICE_OS_SERVICE_NAME + value: "heat" +{{- with $env := dict "ksUserSecret" $ksTrusteeUserSecret }} +{{- include "env_ks_user_create_openrc_tpl" $env | indent 12 }} +{{- end }} + - name: SERVICE_OS_ROLE + value: {{ .Values.keystone.heat_trustee_role | quote }} + - name: heat-ks-domain-user + image: {{ .Values.images.ks_user }} + imagePullPolicy: {{ .Values.images.pull_policy }} + command: + - bash + - /tmp/ks-domain-user.sh + volumeMounts: + - name: ks-user-sh + mountPath: /tmp/ks-domain-user.sh + subPath: ks-domain-user.sh + readOnly: true + env: +{{- with $env := dict "ksUserSecret" $ksAdminSecret }} +{{- include "env_ks_openrc_tpl" $env | indent 12 }} +{{- end }} + - name: SERVICE_OS_SERVICE_NAME + value: "heat" + - name: SERVICE_OS_REGION_NAME + valueFrom: + secretKeyRef: + name: {{ $ksStackUserSecret }} + key: OS_REGION_NAME + - name: SERVICE_OS_DOMAIN_NAME + valueFrom: + secretKeyRef: + name: {{ $ksStackUserSecret }} + key: OS_DOMAIN_NAME + - name: SERVICE_OS_USERNAME + valueFrom: + secretKeyRef: + name: {{ $ksStackUserSecret }} + key: OS_USERNAME + - name: SERVICE_OS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ $ksStackUserSecret }} + key: OS_PASSWORD + - name: SERVICE_OS_ROLE + value: {{ .Values.keystone.heat_stack_user_role | quote }} + volumes: + - name: ks-user-sh + configMap: + name: heat-bin diff --git a/heat/templates/secret-keystone-admin.env.yaml b/heat/templates/secret-keystone-admin.env.yaml new file mode 100644 index 0000000000..ddbc7cece2 --- /dev/null +++ b/heat/templates/secret-keystone-admin.env.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.keystone_secrets.admin }} +type: Opaque +data: + OS_AUTH_URL: | +{{ .Values.keystone.auth_url | b64enc | indent 4 }} + OS_REGION_NAME: | +{{ .Values.keystone.admin_region_name | b64enc | indent 4 }} + OS_PROJECT_DOMAIN_NAME: | +{{ .Values.keystone.admin_project_domain | b64enc | indent 4 }} + OS_PROJECT_NAME: | +{{ .Values.keystone.admin_project_name | b64enc | indent 4 }} + OS_USER_DOMAIN_NAME: | +{{ .Values.keystone.admin_user_domain | b64enc | indent 4 }} + OS_USERNAME: | +{{ .Values.keystone.admin_user | b64enc | indent 4 }} + OS_PASSWORD: | +{{ .Values.keystone.admin_password | b64enc | indent 4 }} diff --git a/heat/templates/secret-keystone-stack-user.env.yaml b/heat/templates/secret-keystone-stack-user.env.yaml new file mode 100644 index 0000000000..703bd37097 --- /dev/null +++ b/heat/templates/secret-keystone-stack-user.env.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.keystone_secrets.stack }} +type: Opaque +data: + OS_REGION_NAME: | +{{ .Values.keystone.heat_stack_region_name | b64enc | indent 4 }} + OS_DOMAIN_NAME: | +{{ .Values.keystone.heat_stack_domain | b64enc | indent 4 }} + OS_USERNAME: | +{{ .Values.keystone.heat_stack_user | b64enc | indent 4 }} + OS_PASSWORD: | +{{ .Values.keystone.heat_stack_password | b64enc | indent 4 }} diff --git a/heat/templates/secret-keystone-trustee.env.yaml b/heat/templates/secret-keystone-trustee.env.yaml new file mode 100644 index 0000000000..63db347e87 --- /dev/null +++ b/heat/templates/secret-keystone-trustee.env.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.keystone_secrets.trustee }} +type: Opaque +data: + OS_AUTH_URL: | +{{ .Values.keystone.auth_url | b64enc | indent 4 }} + OS_REGION_NAME: | +{{ .Values.keystone.heat_trustee_region_name | b64enc | indent 4 }} + OS_PROJECT_DOMAIN_NAME: | +{{ .Values.keystone.heat_trustee_project_domain | b64enc | indent 4 }} + OS_PROJECT_NAME: | +{{ .Values.keystone.heat_trustee_project_name | b64enc | indent 4 }} + OS_USER_DOMAIN_NAME: | +{{ .Values.keystone.heat_trustee_user_domain | b64enc | indent 4 }} + OS_USERNAME: | +{{ .Values.keystone.heat_trustee_user | b64enc | indent 4 }} + OS_PASSWORD: | +{{ .Values.keystone.heat_trustee_password | b64enc | indent 4 }} diff --git a/heat/templates/secret-keystone-user.env.yaml b/heat/templates/secret-keystone-user.env.yaml new file mode 100644 index 0000000000..f54a264f1b --- /dev/null +++ b/heat/templates/secret-keystone-user.env.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.keystone_secrets.user }} +type: Opaque +data: + OS_AUTH_URL: | +{{ .Values.keystone.auth_url | b64enc | indent 4 }} + OS_REGION_NAME: | +{{ .Values.keystone.heat_region_name | b64enc | indent 4 }} + OS_PROJECT_DOMAIN_NAME: | +{{ .Values.keystone.heat_project_domain | b64enc | indent 4 }} + OS_PROJECT_NAME: | +{{ .Values.keystone.heat_project_name | b64enc | indent 4 }} + OS_USER_DOMAIN_NAME: | +{{ .Values.keystone.heat_user_domain | b64enc | indent 4 }} + OS_USERNAME: | +{{ .Values.keystone.heat_user | b64enc | indent 4 }} + OS_PASSWORD: | +{{ .Values.keystone.heat_password | b64enc | indent 4 }} diff --git a/heat/templates/service-api.yaml b/heat/templates/service-api.yaml new file mode 100644 index 0000000000..482a116bfb --- /dev/null +++ b/heat/templates/service-api.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.service.api.name }} +spec: + ports: + - port: {{ .Values.service.api.port }} + selector: + app: heat-api diff --git a/heat/templates/service-cfn.yaml b/heat/templates/service-cfn.yaml new file mode 100644 index 0000000000..799e57d133 --- /dev/null +++ b/heat/templates/service-cfn.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.service.cfn.name }} +spec: + ports: + - port: {{ .Values.service.cfn.port }} + selector: + app: heat-cfn diff --git a/heat/templates/service-cloudwatch.yaml b/heat/templates/service-cloudwatch.yaml new file mode 100644 index 0000000000..071f2c928c --- /dev/null +++ b/heat/templates/service-cloudwatch.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.service.cloudwatch.name }} +spec: + ports: + - port: {{ .Values.service.cloudwatch.port }} + selector: + app: heat-cloudwatch diff --git a/heat/templates/statefulset-engine.yaml b/heat/templates/statefulset-engine.yaml new file mode 100644 index 0000000000..0478e39173 --- /dev/null +++ b/heat/templates/statefulset-engine.yaml @@ -0,0 +1,65 @@ +apiVersion: apps/v1beta1 +kind: StatefulSet +metadata: + name: heat-engine +spec: + serviceName: heat-engine + replicas: {{ .Values.replicas.engine }} + template: + metadata: + labels: + app: heat-engine + annotations: + pod.beta.kubernetes.io/init-containers: '[ + { + "name": "init", + "image": {{ .Values.images.dep_check | quote }}, + "imagePullPolicy": {{ .Values.images.pull_policy | quote }}, + "env": [ + { + "name": "NAMESPACE", + "value": "{{ .Release.Namespace }}" + }, + { + "name": "DEPENDENCY_SERVICE", + "value": "{{ include "joinListWithColon" .Values.dependencies.engine.service }}" + }, + { + "name": "DEPENDENCY_JOBS", + "value": "{{ include "joinListWithColon" .Values.dependencies.engine.jobs }}" + }, + { + "name": "COMMAND", + "value": "echo done" + } + ] + } + ]' + spec: + nodeSelector: + {{ .Values.labels.node_selector_key }}: {{ .Values.labels.node_selector_value }} + containers: + - name: heat-engine + image: {{ .Values.images.engine }} + imagePullPolicy: {{ .Values.images.pull_policy }} + command: + - heat-engine + - --config-dir + - /etc/heat/conf + volumeMounts: + - name: pod-etc-heat + mountPath: /etc/heat + - name: pod-var-cache-heat + mountPath: /var/cache/heat + - name: heatconf + mountPath: /etc/heat/conf/heat.conf + subPath: heat.conf + readOnly: true + volumes: + - name: pod-etc-heat + emptyDir: {} + - name: pod-var-cache-heat + emptyDir: {} + - name: heatconf + configMap: + name: heat-etc diff --git a/heat/values.yaml b/heat/values.yaml new file mode 100644 index 0000000000..6373aa22de --- /dev/null +++ b/heat/values.yaml @@ -0,0 +1,208 @@ +# Default values for keystone. +# This is a YAML-formatted file. +# Declare name/value pairs to be passed into your templates. +# name: value + + +replicas: + api: 1 + cfn: 1 + cloudwatch: 1 + engine: 1 + +labels: + node_selector_key: openstack-control-plane + node_selector_value: enabled + +images: + dep_check: quay.io/stackanetes/kubernetes-entrypoint:v0.1.0 + db_init: quay.io/stackanetes/stackanetes-kolla-toolbox:newton + db_sync: docker.io/kolla/ubuntu-source-heat-api:3.0.1 + ks_user: quay.io/stackanetes/stackanetes-kolla-toolbox:newton + ks_service: quay.io/stackanetes/stackanetes-kolla-toolbox:newton + ks_endpoints: quay.io/stackanetes/stackanetes-kolla-toolbox:newton + api: docker.io/kolla/ubuntu-source-heat-api:3.0.1 + cfn: docker.io/kolla/ubuntu-source-heat-api:3.0.1 + cloudwatch: docker.io/kolla/ubuntu-source-heat-api:3.0.1 + engine: docker.io/kolla/ubuntu-source-heat-engine:3.0.1 + pull_policy: "IfNotPresent" + +keystone_secrets: + admin: "heat-env-keystone-admin" + user: "heat-env-keystone-user" + trustee: "heat-env-keystone-trustee" + stack: "heat-env-keystone-stack-user" + +keystone: + auth_uri: "http://keystone-api:5000" + auth_url: "http://keystone-api:35357" + admin_user: "admin" + admin_user_domain: "default" + admin_password: "password" + admin_project_name: "admin" + admin_project_domain: "default" + admin_region_name: "RegionOne" + + heat_user: "heat" + heat_user_domain: "default" + heat_user_role: "admin" + heat_password: "password" + heat_project_name: "service" + heat_project_domain: "default" + heat_region_name: "RegionOne" + + heat_trustee_user: "heat-trust" + heat_trustee_user_domain: "default" + heat_trustee_role: "admin" + heat_trustee_password: "password" + heat_trustee_project_name: "service" + heat_trustee_project_domain: "default" + heat_trustee_region_name: "RegionOne" + + heat_stack_user: "heat-domain" + heat_stack_domain: "heat" + heat_stack_user_role: "admin" + heat_stack_password: "password" + heat_stack_region_name: "RegionOne" + +service: + api: + name: "heat-api" + port: 8004 + proto: "http" + cfn: + name: "heat-cfn" + port: 8000 + proto: "http" + cloudwatch: + name: "heat-cloudwatch" + port: 8003 + proto: "http" + +database: + address: mariadb + port: 3306 + root_user: root + root_password: password + heat_database_name: heat + heat_password: password + heat_user: heat + +messaging: + hosts: rabbitmq + user: rabbitmq + password: password + +memcached: + host: memcached + port: 11211 + +resources: + api: + workers: 8 + cfn: + workers: 8 + cloudwatch: + workers: 8 + engine: + workers: 8 + +misc: + debug: false + +secrets: + keystone_admin: + +dependencies: + db_init: + jobs: + - mariadb-seed + service: + - mariadb + db_sync: + jobs: + - heat-db-init + service: + - mariadb + ks_user: + service: + - keystone-api + ks_service: + service: + - keystone-api + ks_endpoints: + jobs: + - heat-ks-service + service: + - keystone-api + api: + jobs: + - heat-db-sync + - heat-ks-user + - heat-ks-endpoints + service: + - keystone-api + - mariadb + cfn: + jobs: + - heat-db-sync + - heat-ks-user + - heat-ks-endpoints + service: + - keystone-api + - mariadb + cloudwatch: + jobs: + - heat-db-sync + - heat-ks-user + - heat-ks-endpoints + service: + - keystone-api + - mariadb + engine: + jobs: + - heat-db-sync + - heat-ks-user + - heat-ks-endpoints + service: + - keystone-api + - mariadb + +# typically overriden by environmental +# values, but should include all endpoints +# required by this chart +endpoints: + keystone: + hosts: + default: keystone-api + path: /v3 + type: identity + scheme: 'http' + port: + admin: 35357 + public: 5000 + heat: + hosts: + default: heat-api + path: '/v1/%(project_id)s' + type: orchestration + scheme: 'http' + port: + api: 8004 + heat_cfn: + hosts: + default: heat-cfn + path: /v1 + type: cloudformation + scheme: 'http' + port: + api: 8000 +# Cloudwatch does not get an entry in the keystone service catalog + heat_cloudwatch: + hosts: + default: heat-cloudwatch + path: null + type: null + scheme: 'http' + port: + api: 8003