From 918a307427ee9bfaf4ecdb758905de59831f15b5 Mon Sep 17 00:00:00 2001 From: Tin Lam Date: Wed, 3 Jun 2020 12:40:40 -0500 Subject: [PATCH] feat(tls): add tls support to openstack services This patch set enables TLS for the following OpenStack services: keystone, horizon, glance, cinder, heat, nova, placement and neutron for s- (stein) and t- (train) release. This serves as a consolidation and clean up patch for the following patches: [0] https://review.opendev.org/#/c/733291 [1] https://review.opendev.org/#/c/735202 [2] https://review.opendev.org/#/c/733962 [3] https://review.opendev.org/#/c/733404 [4] https://review.opendev.org/#/c/734896 This also addresses comments mentioned in previous patches. Co-authored-by: Gage Hugo Co-authored-by: sgupta Depends-on: https://review.opendev.org/#/c/737194/ Change-Id: Id34ace54298660b4b151522916e929a29f5731be Signed-off-by: Tin Lam --- cinder/templates/bin/_cinder-api.sh.tpl | 40 +++ cinder/templates/certificates.yaml | 17 ++ cinder/templates/configmap-etc.yaml | 4 + cinder/templates/deployment-api.yaml | 22 ++ cinder/templates/deployment-volume.yaml | 6 +- cinder/templates/ingress-api.yaml | 7 +- cinder/templates/job-bootstrap.yaml | 3 + .../templates/job-create-internal-tenant.yaml | 4 +- cinder/templates/job-ks-endpoints.yaml | 3 + cinder/templates/job-ks-service.yaml | 3 + cinder/templates/job-ks-user.yaml | 3 + cinder/templates/pod-rally-test.yaml | 7 +- cinder/values.yaml | 3 +- cinder/values_overrides/tls.yaml | 136 ++++++++++ glance/templates/bin/_nginx.sh.tpl | 17 ++ glance/templates/certificates.yaml | 18 ++ glance/templates/configmap-bin.yaml | 4 + glance/templates/configmap-etc.yaml | 1 + glance/templates/deployment-api.yaml | 58 ++++- glance/templates/deployment-registry.yaml | 58 ++++- glance/templates/ingress-api.yaml | 7 +- glance/templates/ingress-registry.yaml | 7 +- glance/templates/job-bootstrap.yaml | 3 + glance/templates/job-ks-endpoints.yaml | 3 + glance/templates/job-ks-service.yaml | 3 + glance/templates/job-ks-user.yaml | 3 + glance/values.yaml | 6 +- glance/values_overrides/tls.yaml | 138 ++++++++++ heat/templates/bin/_heat-api.sh.tpl | 36 +++ heat/templates/bin/_heat-cfn.sh.tpl | 37 +++ heat/templates/certificates.yaml | 18 ++ heat/templates/configmap-etc.yaml | 5 + heat/templates/deployment-api.yaml | 16 ++ heat/templates/deployment-cfn.yaml | 16 ++ heat/templates/deployment-engine.yaml | 2 + heat/templates/ingress-api.yaml | 7 +- heat/templates/ingress-cfn.yaml | 7 +- heat/templates/job-bootstrap.yaml | 3 + heat/templates/job-ks-endpoints.yaml | 3 + heat/templates/job-ks-service.yaml | 3 + heat/templates/job-ks-user-domain.yaml | 4 +- heat/templates/job-ks-user-trustee.yaml | 3 + heat/templates/job-ks-user.yaml | 3 + heat/templates/job-trusts.yaml | 4 +- heat/templates/pod-rally-test.yaml | 7 +- heat/values.yaml | 4 +- heat/values_overrides/tls.yaml | 182 +++++++++++++ horizon/templates/certificates.yaml | 17 ++ horizon/templates/deployment.yaml | 6 +- horizon/templates/ingress-api.yaml | 7 +- horizon/values.yaml | 8 +- horizon/values_overrides/tls.yaml | 109 ++++++++ keystone/templates/bin/_keystone-api.sh.tpl | 4 + keystone/templates/certificates.yaml | 17 ++ keystone/templates/deployment-api.yaml | 4 +- keystone/templates/ingress-api.yaml | 7 +- keystone/templates/job-bootstrap.yaml | 3 + keystone/templates/pod-rally-test.yaml | 7 +- keystone/values.yaml | 2 + keystone/values_overrides/tls.yaml | 80 ++++++ .../templates/bin/_neutron-rpc-server.sh.tpl | 30 +++ neutron/templates/bin/_neutron-server.sh.tpl | 57 +++++ neutron/templates/certificates.yaml | 17 ++ neutron/templates/configmap-bin.yaml | 4 + neutron/templates/configmap-etc.yaml | 4 + .../templates/daemonset-metadata-agent.yaml | 2 + neutron/templates/deployment-server.yaml | 55 ++++ neutron/templates/ingress-server.yaml | 7 +- neutron/templates/job-bootstrap.yaml | 3 + neutron/templates/job-ks-endpoints.yaml | 3 + neutron/templates/job-ks-service.yaml | 3 + neutron/templates/job-ks-user.yaml | 3 + neutron/templates/pod-rally-test.yaml | 10 +- neutron/values.yaml | 8 + .../values_overrides/rocky-ubuntu_bionic.yaml | 1 + neutron/values_overrides/tls.yaml | 145 +++++++++++ .../values_overrides/train-ubuntu_bionic.yaml | 1 + nova/templates/bin/_nova-api-metadata.sh.tpl | 38 +++ nova/templates/bin/_nova-api.sh.tpl | 39 +++ nova/templates/bin/_nova-placement-api.sh.tpl | 3 + nova/templates/certificates.yaml | 27 ++ nova/templates/configmap-etc.yaml | 5 + nova/templates/cron-job-service-cleaner.yaml | 2 +- nova/templates/daemonset-compute.yaml | 11 + nova/templates/deployment-api-metadata.yaml | 18 ++ nova/templates/deployment-api-osapi.yaml | 18 ++ nova/templates/deployment-conductor.yaml | 6 + nova/templates/deployment-novncproxy.yaml | 2 + nova/templates/deployment-placement.yaml | 2 + nova/templates/deployment-scheduler.yaml | 6 + nova/templates/deployment-spiceproxy.yaml | 2 + nova/templates/ingress-metadata.yaml | 7 +- nova/templates/ingress-novncproxy.yaml | 7 +- nova/templates/ingress-osapi.yaml | 7 +- nova/templates/ingress-placement.yaml | 7 +- nova/templates/job-bootstrap.yaml | 4 +- nova/templates/job-cell-setup.yaml | 4 +- nova/templates/job-ks-endpoints.yaml | 3 + .../templates/job-ks-placement-endpoints.yaml | 3 + nova/templates/job-ks-placement-service.yaml | 3 + nova/templates/job-ks-placement-user.yaml | 3 + nova/templates/job-ks-service.yaml | 3 + nova/templates/job-ks-user.yaml | 3 + nova/templates/pod-rally-test.yaml | 7 +- nova/values.yaml | 11 + nova/values_overrides/tls.yaml | 242 ++++++++++++++++++ placement/templates/bin/_placement-api.sh.tpl | 3 + placement/templates/certificates.yaml | 17 ++ placement/templates/deployment.yaml | 2 + placement/templates/ingress.yaml | 7 +- placement/templates/job-db-migrate.yaml | 4 +- placement/templates/job-ks-endpoints.yaml | 3 + placement/templates/job-ks-service.yaml | 3 + placement/templates/job-ks-user.yaml | 3 + placement/values.yaml | 2 + placement/values_overrides/tls.yaml | 78 ++++++ tools/deployment/common/setup-client.sh | 41 ++- tools/deployment/component/ceph/ceph.sh | 2 + .../component/compute-kit/compute-kit.sh | 4 +- tools/deployment/component/heat/heat.sh | 9 +- tools/deployment/component/horizon/horizon.sh | 5 + .../deployment/component/keystone/keystone.sh | 5 + tools/scripts/tls/cert-manager.sh | 55 ++++ zuul.d/jobs-openstack-helm.yaml | 53 +++- zuul.d/project.yaml | 15 +- 125 files changed, 2307 insertions(+), 65 deletions(-) create mode 100644 cinder/templates/certificates.yaml create mode 100644 cinder/values_overrides/tls.yaml create mode 100644 glance/templates/bin/_nginx.sh.tpl create mode 100644 glance/templates/certificates.yaml create mode 100644 glance/values_overrides/tls.yaml create mode 100644 heat/templates/certificates.yaml create mode 100644 heat/values_overrides/tls.yaml create mode 100644 horizon/templates/certificates.yaml create mode 100644 horizon/values_overrides/tls.yaml create mode 100644 keystone/templates/certificates.yaml create mode 100644 keystone/values_overrides/tls.yaml create mode 100644 neutron/templates/bin/_neutron-rpc-server.sh.tpl create mode 100644 neutron/templates/certificates.yaml create mode 100644 neutron/values_overrides/tls.yaml create mode 100644 nova/templates/certificates.yaml create mode 100644 nova/values_overrides/tls.yaml create mode 100644 placement/templates/certificates.yaml create mode 100644 placement/values_overrides/tls.yaml diff --git a/cinder/templates/bin/_cinder-api.sh.tpl b/cinder/templates/bin/_cinder-api.sh.tpl index b883d007d9..3b64745c43 100644 --- a/cinder/templates/bin/_cinder-api.sh.tpl +++ b/cinder/templates/bin/_cinder-api.sh.tpl @@ -18,12 +18,52 @@ set -ex COMMAND="${@:-start}" function start () { +{{- if .Values.manifests.certificates }} + for WSGI_SCRIPT in cinder-wsgi; do + cp -a $(type -p ${WSGI_SCRIPT}) /var/www/cgi-bin/cinder/ + done + + if [ -f /etc/apache2/envvars ]; then + # Loading Apache2 ENV variables + source /etc/apache2/envvars + mkdir -p ${APACHE_RUN_DIR} + fi + +{{- if .Values.conf.software.apache2.a2enmod }} + {{- range .Values.conf.software.apache2.a2enmod }} + a2enmod {{ . }} + {{- end }} +{{- end }} + +{{- if .Values.conf.software.apache2.a2dismod }} + {{- range .Values.conf.software.apache2.a2dismod }} + a2dismod {{ . }} + {{- end }} +{{- end }} + + if [ -f /var/run/apache2/apache2.pid ]; then + # Remove the stale pid for debian/ubuntu images + rm -f /var/run/apache2/apache2.pid + fi + # Starts Apache2 + exec {{ .Values.conf.software.apache2.binary }} {{ .Values.conf.software.apache2.start_parameters }} +{{- else }} exec cinder-api \ --config-file /etc/cinder/cinder.conf +{{- end }} } function stop () { +{{- if .Values.manifests.certificates }} + if [ -f /etc/apache2/envvars ]; then + # Loading Apache2 ENV variables + source /etc/apache2/envvars + mkdir -p ${APACHE_RUN_DIR} + fi + {{ .Values.conf.software.apache2.binary }} -k graceful-stop +{{- else }} kill -TERM 1 +{{- end }} } $COMMAND diff --git a/cinder/templates/certificates.yaml b/cinder/templates/certificates.yaml new file mode 100644 index 0000000000..7ccf6ca145 --- /dev/null +++ b/cinder/templates/certificates.yaml @@ -0,0 +1,17 @@ +{{/* +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.certificates -}} +{{ dict "envAll" . "service" "volumev3" "type" "internal" | include "helm-toolkit.manifests.certificates" }} +{{- end -}} diff --git a/cinder/templates/configmap-etc.yaml b/cinder/templates/configmap-etc.yaml index 663f7eb989..bec953bb18 100644 --- a/cinder/templates/configmap-etc.yaml +++ b/cinder/templates/configmap-etc.yaml @@ -117,6 +117,10 @@ data: backends.conf: {{ include "helm-toolkit.utils.to_ini" .Values.conf.backends | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.paste | b64enc }} policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} +{{- if .Values.manifests.certificates }} +{{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.mpm_event "key" "mpm_event.conf" "format" "Secret" ) | indent 2 }} +{{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_cinder "key" "wsgi-cinder.conf" "format" "Secret" ) | indent 2 }} +{{- end }} api_audit_map.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.api_audit_map | b64enc }} cinder_sudoers: {{ $envAll.Values.conf.cinder_sudoers | b64enc }} rootwrap.conf: {{ $envAll.Values.conf.rootwrap | b64enc }} diff --git a/cinder/templates/deployment-api.yaml b/cinder/templates/deployment-api.yaml index 34f0e730ce..e0c5643ff5 100644 --- a/cinder/templates/deployment-api.yaml +++ b/cinder/templates/deployment-api.yaml @@ -100,6 +100,8 @@ spec: volumeMounts: - name: pod-tmp mountPath: /tmp + - name: wsgi-cinder + mountPath: /var/www/cgi-bin/cinder - name: cinder-bin mountPath: /tmp/cinder-api.sh subPath: cinder-api.sh @@ -130,14 +132,33 @@ spec: mountPath: {{ .Values.conf.cinder.DEFAULT.resource_query_filters_file }} subPath: resource_filters.json readOnly: true +{{- if .Values.conf.security }} + - name: cinder-etc + mountPath: {{ .Values.conf.software.apache2.conf_dir }}/security.conf + subPath: security.conf + readOnly: true +{{- end }} {{- if eq ( split "://" .Values.conf.cinder.coordination.backend_url )._0 "file" }} - name: cinder-coordination mountPath: {{ ( split "://" .Values.conf.cinder.coordination.backend_url )._1 }} {{- end }} + {{- if .Values.manifests.certificates }} + - name: cinder-etc + mountPath: {{ .Values.conf.software.apache2.site_dir }}/cinder-api.conf + subPath: wsgi-cinder.conf + readOnly: true + - name: cinder-etc + mountPath: {{ .Values.conf.software.apache2.mods_dir }}/mpm_event.conf + subPath: mpm_event.conf + readOnly: true + {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.volume.api.internal "path" "/etc/cinder/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_cinder_api.volumeMounts }}{{ toYaml $mounts_cinder_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} + - name: wsgi-cinder + emptyDir: {} - name: cinder-bin configMap: name: cinder-bin @@ -152,5 +173,6 @@ spec: - name: cinder-coordination emptyDir: {} {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.volume.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_cinder_api.volumes }}{{ toYaml $mounts_cinder_api.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/cinder/templates/deployment-volume.yaml b/cinder/templates/deployment-volume.yaml index af8a8d9c5c..f46e1a30f9 100755 --- a/cinder/templates/deployment-volume.yaml +++ b/cinder/templates/deployment-volume.yaml @@ -111,19 +111,18 @@ spec: readOnly: true - name: pod-shared mountPath: /tmp/pod-shared +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.volume.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} env: -{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: INTERNAL_PROJECT_NAME value: {{ .Values.conf.cinder.DEFAULT.internal_project_name | quote }} - name: INTERNAL_USER_NAME value: {{ .Values.conf.cinder.DEFAULT.internal_user_name | quote }} - {{- with $env := dict "ksUserSecret" (index .Values.secrets.identity "cinder" ) }} {{- include "helm-toolkit.snippets.keystone_user_create_env_vars" $env | indent 12 }} {{- end }} - containers: - name: cinder-volume {{ tuple $envAll "cinder_volume" | include "helm-toolkit.snippets.image" | indent 10 }} @@ -259,5 +258,6 @@ spec: - name: usrlocalsbin emptyDir: {} {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.volume.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_cinder_volume.volumes }}{{ toYaml $mounts_cinder_volume.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/cinder/templates/ingress-api.yaml b/cinder/templates/ingress-api.yaml index a514adfde3..4586d3a118 100644 --- a/cinder/templates/ingress-api.yaml +++ b/cinder/templates/ingress-api.yaml @@ -13,6 +13,11 @@ limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} -{{- $ingressOpts := dict "envAll" . "backendServiceType" "volume" "backendPort" "c-api" -}} +{{- $envAll := . -}} +{{- $ingressOpts := dict "envAll" $envAll "backendServiceType" "volume" "backendPort" "c-api" -}} +{{- $secretName := $envAll.Values.secrets.tls.volume.api.internal -}} +{{- if and .Values.manifests.certificates $secretName -}} +{{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.volume.host_fqdn_override.default.tls.issuerRef.name -}} +{{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} diff --git a/cinder/templates/job-bootstrap.yaml b/cinder/templates/job-bootstrap.yaml index 4867099cbd..0104dc5574 100644 --- a/cinder/templates/job-bootstrap.yaml +++ b/cinder/templates/job-bootstrap.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "cinder" "keystoneUser" .Values.bootstrap.ks_user "logConfigFile" .Values.conf.cinder.DEFAULT.log_config_append -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $bootstrapJob "tlsSecret" .Values.secrets.tls.volume.api.internal -}} +{{- end -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} diff --git a/cinder/templates/job-create-internal-tenant.yaml b/cinder/templates/job-create-internal-tenant.yaml index 2cb722e242..24c5c9897c 100644 --- a/cinder/templates/job-create-internal-tenant.yaml +++ b/cinder/templates/job-create-internal-tenant.yaml @@ -54,8 +54,9 @@ spec: mountPath: /tmp/create-internal-tenant.sh subPath: create-internal-tenant.sh readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.volume.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} env: -{{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME @@ -82,4 +83,5 @@ spec: configMap: name: {{ $configMapBin | quote }} defaultMode: 0555 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.volume.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end -}} diff --git a/cinder/templates/job-ks-endpoints.yaml b/cinder/templates/job-ks-endpoints.yaml index 60f5beca3c..1f400928ae 100644 --- a/cinder/templates/job-ks-endpoints.yaml +++ b/cinder/templates/job-ks-endpoints.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "cinder" "serviceTypes" ( tuple "volume" "volumev2" "volumev3" ) -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.volume.api.internal -}} +{{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} diff --git a/cinder/templates/job-ks-service.yaml b/cinder/templates/job-ks-service.yaml index bfdad1e210..630d8e42ca 100644 --- a/cinder/templates/job-ks-service.yaml +++ b/cinder/templates/job-ks-service.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "cinder" "serviceTypes" ( tuple "volume" "volumev2" "volumev3" ) -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.volume.api.internal -}} +{{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} diff --git a/cinder/templates/job-ks-user.yaml b/cinder/templates/job-ks-user.yaml index 4d10dfe19b..b5039d273d 100644 --- a/cinder/templates/job-ks-user.yaml +++ b/cinder/templates/job-ks-user.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "cinder" -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.volume.api.internal -}} +{{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} diff --git a/cinder/templates/pod-rally-test.yaml b/cinder/templates/pod-rally-test.yaml index 690b527b04..1daf9280ad 100644 --- a/cinder/templates/pod-rally-test.yaml +++ b/cinder/templates/pod-rally-test.yaml @@ -50,8 +50,9 @@ spec: mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true +{{ dict "enabled" .Values.manifests.certificates "name" $envAll.Values.secrets.tls.volume.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} env: -{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME @@ -66,7 +67,7 @@ spec: {{ tuple $envAll "test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} env: -{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} @@ -89,6 +90,7 @@ spec: readOnly: true - name: rally-db mountPath: /var/lib/rally +{{ dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.volume.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{ if $mounts_tests.volumeMounts }}{{ toYaml $mounts_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp @@ -103,5 +105,6 @@ spec: defaultMode: 0555 - name: rally-db emptyDir: {} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.volume.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{ if $mounts_tests.volumes }}{{ toYaml $mounts_tests.volumes | indent 4 }}{{ end }} {{- end }} diff --git a/cinder/values.yaml b/cinder/values.yaml index c1f75e2ffe..d37ecd5cf2 100644 --- a/cinder/values.yaml +++ b/cinder/values.yaml @@ -1196,7 +1196,7 @@ secrets: volume: api: public: cinder-tls-public - + internal: cinder-tls-api # We use a different layout of the endpoints here to account for versioning # this swaps the service name and type, and should be rolled out to other # services. @@ -1449,6 +1449,7 @@ network_policy: - {} manifests: + certificates: false configmap_bin: true configmap_etc: true cron_volume_usage_audit: true diff --git a/cinder/values_overrides/tls.yaml b/cinder/values_overrides/tls.yaml new file mode 100644 index 0000000000..b2dca77ebe --- /dev/null +++ b/cinder/values_overrides/tls.yaml @@ -0,0 +1,136 @@ +--- +pod: + security_context: + cinder_api: + container: + cinder_api: + runAsUser: 0 + readOnlyRootFilesystem: false +network: + api: + ingress: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "https" +conf: + software: + apache2: + binary: apache2 + start_parameters: -DFOREGROUND + site_dir: /etc/apache2/sites-enabled + conf_dir: /etc/apache2/conf-enabled + mods_dir: /etc/apache2/mods-available + a2enmod: + - ssl + a2dismod: null + mpm_event: | + + ServerLimit 1024 + StartServers 32 + MinSpareThreads 32 + MaxSpareThreads 256 + ThreadsPerChild 25 + MaxRequestsPerChild 128 + ThreadLimit 720 + + wsgi_cinder: | + {{- $portInt := tuple "volume" "internal" "api" $ | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + Listen {{ $portInt }} + + ServerName {{ printf "%s.%s.svc.%s" "cinder-api" .Release.Namespace .Values.endpoints.cluster_domain_suffix }} + WSGIDaemonProcess cinder-api processes=1 threads=1 user=cinder display-name=%{GROUP} + WSGIProcessGroup cinder-api + WSGIScriptAlias / /var/www/cgi-bin/cinder/cinder-wsgi + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + AllowEncodedSlashes On + = 2.4> + ErrorLogFormat "%{cu}t %M" + + SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded + ErrorLog /dev/stdout + CustomLog /dev/stdout combined env=!forwarded + CustomLog /dev/stdout proxy env=forwarded + + SSLEngine on + SSLCertificateFile /etc/cinder/certs/tls.crt + SSLCertificateKeyFile /etc/cinder/certs/tls.key + SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 + SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 + SSLHonorCipherOrder on + + cinder: + keystone_authtoken: + cafile: /etc/cinder/certs/ca.crt + +endpoints: + identity: + auth: + admin: + cacert: /etc/ssl/certs/openstack-helm.crt + cinder: + cacert: /etc/ssl/certs/openstack-helm.crt + test: + cacert: /etc/ssl/certs/openstack-helm.crt + scheme: + default: https + port: + api: + default: 443 + image: + scheme: + default: https + port: + api: + public: 443 + image_registry: + scheme: + default: https + port: + api: + public: 443 + volume: + host_fqdn_override: + default: + tls: + secretName: cinder-tls-api + issuerRef: + name: ca-issuer + scheme: + default: https + internal: https + port: + api: + public: 443 + volumev2: + host_fqdn_override: + default: + tls: + secretName: cinder-tls-api + issuerRef: + name: ca-issuer + scheme: + default: https + internal: https + port: + api: + public: 443 + volumev3: + host_fqdn_override: + default: + tls: + secretName: cinder-tls-api + issuerRef: + name: ca-issuer + scheme: + default: https + internal: https + port: + api: + public: 443 + ingress: + port: + ingress: + default: 443 +manifests: + certificates: true +... diff --git a/glance/templates/bin/_nginx.sh.tpl b/glance/templates/bin/_nginx.sh.tpl new file mode 100644 index 0000000000..e44ffd27a9 --- /dev/null +++ b/glance/templates/bin/_nginx.sh.tpl @@ -0,0 +1,17 @@ +#!/bin/bash +set -xe + +COMMAND="${@:-start}" + +function start () { + envsubst < /etc/nginx/nginx.conf > /tmp/nginx.conf + cat /tmp/nginx.conf + nginx -t -c /tmp/nginx.conf + exec nginx -c /tmp/nginx.conf +} + +function stop () { + nginx -s stop +} + +$COMMAND diff --git a/glance/templates/certificates.yaml b/glance/templates/certificates.yaml new file mode 100644 index 0000000000..55f3751ba1 --- /dev/null +++ b/glance/templates/certificates.yaml @@ -0,0 +1,18 @@ +{{/* +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.certificates -}} +{{ dict "envAll" . "service" "image" "type" "internal" | include "helm-toolkit.manifests.certificates" }} +{{ dict "envAll" . "service" "image_registry" "type" "internal" | include "helm-toolkit.manifests.certificates" }} +{{- end -}} diff --git a/glance/templates/configmap-bin.yaml b/glance/templates/configmap-bin.yaml index 4469929ea0..14638eeeab 100644 --- a/glance/templates/configmap-bin.yaml +++ b/glance/templates/configmap-bin.yaml @@ -61,4 +61,8 @@ data: {{ tuple "bin/_clean-secrets.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} rabbit-init.sh: | {{- include "helm-toolkit.scripts.rabbit_init" . | indent 4 }} +{{- if .Values.manifests.certificates }} + nginx.sh: | +{{ tuple "bin/_nginx.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} +{{- end }} {{- end }} diff --git a/glance/templates/configmap-etc.yaml b/glance/templates/configmap-etc.yaml index 18fc26d581..3b478a062a 100644 --- a/glance/templates/configmap-etc.yaml +++ b/glance/templates/configmap-etc.yaml @@ -188,4 +188,5 @@ data: policy.json: {{ toJson .Values.conf.policy | b64enc }} api_audit_map.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.api_audit_map | b64enc }} {{- include "helm-toolkit.snippets.values_template_renderer" ( dict "envAll" $envAll "template" .Values.conf.swift_store "key" "swift-store.conf" "format" "Secret" ) | indent 2 }} +{{- include "helm-toolkit.snippets.values_template_renderer" ( dict "envAll" $envAll "template" .Values.conf.nginx "key" "nginx.conf" "format" "Secret" ) | indent 2 }} {{- end }} diff --git a/glance/templates/deployment-api.yaml b/glance/templates/deployment-api.yaml index 76f8655caf..aeaae7e1fa 100644 --- a/glance/templates/deployment-api.yaml +++ b/glance/templates/deployment-api.yaml @@ -92,6 +92,45 @@ spec: readOnly: true {{ end }} containers: + {{- if $envAll.Values.manifests.certificates }} + - name: nginx +{{ tuple $envAll "nginx" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.nginx | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + ports: + - name: g-api + containerPort: {{ tuple "image" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + env: + - name: PORT + value: {{ tuple "image" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SHORTNAME + value: {{ tuple "image" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" | quote }} + readinessProbe: + tcpSocket: + port: {{ tuple "image" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + command: + - /tmp/nginx.sh + - start + lifecycle: + preStop: + exec: + command: + - /tmp/nginx.sh + - stop + volumeMounts: + - name: glance-bin + mountPath: /tmp/nginx.sh + subPath: nginx.sh + readOnly: true + - name: glance-etc + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.image.api.internal "path" "/etc/nginx/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} + {{- end }} - name: glance-api {{ tuple $envAll "glance_api" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} @@ -105,6 +144,21 @@ spec: command: - /tmp/glance-api.sh - stop + {{- if $envAll.Values.manifests.certificates }} + readinessProbe: + exec: + command: + - python + - -c + - "import requests; requests.get('http://127.0.0.1:{{ tuple "image" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}')" + livenessProbe: + exec: + command: + - python + - -c + - "import requests; requests.get('http://127.0.0.1:{{ tuple "image" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}')" + initialDelaySeconds: 30 + {{- else }} ports: - name: g-api containerPort: {{ tuple "image" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} @@ -114,7 +168,7 @@ spec: livenessProbe: tcpSocket: port: {{ tuple "image" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - initialDelaySeconds: 30 + {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp @@ -164,6 +218,7 @@ spec: subPath: key readOnly: true {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.image.api.internal "path" "/etc/glance/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_glance_api.volumeMounts }}{{ toYaml $mounts_glance_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp @@ -197,5 +252,6 @@ spec: secret: secretName: {{ .Values.secrets.rbd | quote }} {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.image.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_glance_api.volumes }}{{ toYaml $mounts_glance_api.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/glance/templates/deployment-registry.yaml b/glance/templates/deployment-registry.yaml index 5928c2bb7b..5308453af8 100644 --- a/glance/templates/deployment-registry.yaml +++ b/glance/templates/deployment-registry.yaml @@ -55,6 +55,45 @@ spec: initContainers: {{ tuple $envAll "registry" $mounts_glance_registry_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} containers: + {{- if $envAll.Values.manifests.certificates }} + - name: nginx +{{ tuple $envAll "nginx" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.nginx | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + ports: + - name: g-reg + containerPort: {{ tuple "image_registry" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + env: + - name: PORT + value: {{ tuple "image_registry" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SHORTNAME + value: {{ tuple "image_registry" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" | quote }} + readinessProbe: + tcpSocket: + port: {{ tuple "image_registry" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + command: + - /tmp/nginx.sh + - start + lifecycle: + preStop: + exec: + command: + - /tmp/nginx.sh + - stop + volumeMounts: + - name: glance-bin + mountPath: /tmp/nginx.sh + subPath: nginx.sh + readOnly: true + - name: glance-etc + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.image_registry.api.internal "path" "/etc/nginx/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} + {{- end }} - name: glance-registry {{ tuple $envAll "glance_registry" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.registry | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} @@ -68,6 +107,21 @@ spec: command: - /tmp/glance-registry.sh - stop + {{- if $envAll.Values.manifests.certificates }} + readinessProbe: + exec: + command: + - python + - -c + - "import requests; requests.get('http://127.0.0.1:{{ tuple "image_registry" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}')" + livenessProbe: + exec: + command: + - python + - -c + - "import requests; requests.get('http://127.0.0.1:{{ tuple "image_registry" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }}')" + initialDelaySeconds: 30 + {{- else }} ports: - name: g-reg containerPort: {{ tuple "image_registry" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} @@ -77,7 +131,7 @@ spec: livenessProbe: tcpSocket: port: {{ tuple "image_registry" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} - initialDelaySeconds: 30 + {{- end }} volumeMounts: - name: pod-tmp mountPath: /tmp @@ -109,6 +163,7 @@ spec: mountPath: /etc/glance/policy.json subPath: policy.json readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.image_registry.api.internal "path" "/etc/glance/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_glance_registry.volumeMounts }}{{ toYaml $mounts_glance_registry.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp @@ -123,5 +178,6 @@ spec: secret: secretName: glance-etc defaultMode: 0444 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.image_registry.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_glance_registry.volumes }}{{ toYaml $mounts_glance_registry.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/glance/templates/ingress-api.yaml b/glance/templates/ingress-api.yaml index 497d96ad39..939855e0ac 100644 --- a/glance/templates/ingress-api.yaml +++ b/glance/templates/ingress-api.yaml @@ -13,6 +13,11 @@ limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} -{{- $ingressOpts := dict "envAll" . "backendServiceType" "image" "backendPort" "g-api" -}} +{{- $envAll := . }} +{{- $ingressOpts := dict "envAll" $envAll "backendServiceType" "image" "backendPort" "g-api" -}} +{{- $secretName := $envAll.Values.secrets.tls.image.api.internal -}} +{{- if and .Values.manifests.certificates $secretName -}} +{{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.image.host_fqdn_override.default.tls.issuerRef.name -}} +{{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} diff --git a/glance/templates/ingress-registry.yaml b/glance/templates/ingress-registry.yaml index 4c845132a4..9f2c0ceb13 100644 --- a/glance/templates/ingress-registry.yaml +++ b/glance/templates/ingress-registry.yaml @@ -13,6 +13,11 @@ limitations under the License. */}} {{- if and .Values.manifests.ingress_registry .Values.network.registry.ingress.public }} -{{- $ingressOpts := dict "envAll" . "backendService" "registry" "backendServiceType" "image_registry" "backendPort" "g-reg" -}} +{{- $envAll := . }} +{{- $ingressOpts := dict "envAll" $envAll "backendService" "registry" "backendServiceType" "image_registry" "backendPort" "g-reg" -}} +{{- $secretName := $envAll.Values.secrets.tls.image_registry.api.internal -}} +{{- if and .Values.manifests.certificates $secretName -}} +{{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.image_registry.host_fqdn_override.default.tls.issuerRef.name -}} +{{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} diff --git a/glance/templates/job-bootstrap.yaml b/glance/templates/job-bootstrap.yaml index 3fe72b4cbb..aaeabb5b3b 100644 --- a/glance/templates/job-bootstrap.yaml +++ b/glance/templates/job-bootstrap.yaml @@ -25,5 +25,8 @@ volumes: {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $podVolumes := tuple . | include "glance.templates._job_bootstrap.pod_volumes" | toString | fromYaml }} {{- $bootstrapJob := dict "envAll" . "serviceName" "glance" "keystoneUser" .Values.bootstrap.ks_user "logConfigFile" .Values.conf.glance.DEFAULT.log_config_append "podVolMounts" $podVolumes.volumeMounts "podVols" $podVolumes.volumes -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $bootstrapJob "tlsSecret" .Values.secrets.tls.image.api.internal -}} +{{- end -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} diff --git a/glance/templates/job-ks-endpoints.yaml b/glance/templates/job-ks-endpoints.yaml index 5ac03006b0..b66e01becc 100644 --- a/glance/templates/job-ks-endpoints.yaml +++ b/glance/templates/job-ks-endpoints.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "glance" "serviceTypes" ( tuple "image" ) -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.image.api.internal -}} +{{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} diff --git a/glance/templates/job-ks-service.yaml b/glance/templates/job-ks-service.yaml index d323ba3b68..440f456025 100644 --- a/glance/templates/job-ks-service.yaml +++ b/glance/templates/job-ks-service.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "glance" "serviceTypes" ( tuple "image" ) -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.image.api.internal -}} +{{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} diff --git a/glance/templates/job-ks-user.yaml b/glance/templates/job-ks-user.yaml index d39d6a35bf..93adf112d5 100644 --- a/glance/templates/job-ks-user.yaml +++ b/glance/templates/job-ks-user.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "glance" -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.image.api.internal -}} +{{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} diff --git a/glance/values.yaml b/glance/values.yaml index 43de91e5bd..fddc104041 100644 --- a/glance/values.yaml +++ b/glance/values.yaml @@ -569,7 +569,10 @@ secrets: image: api: public: glance-tls-public - + internal: glance-tls-api + image_registry: + api: + internal: glance-tls-reg # typically overridden by environmental # values, but should include all endpoints @@ -991,6 +994,7 @@ pod: cpu: "2000m" manifests: + certificates: false configmap_bin: true configmap_etc: true deployment_api: true diff --git a/glance/values_overrides/tls.yaml b/glance/values_overrides/tls.yaml new file mode 100644 index 0000000000..c9a77cfa09 --- /dev/null +++ b/glance/values_overrides/tls.yaml @@ -0,0 +1,138 @@ +--- +images: + tags: + nginx: docker.io/nginx:1.18.0 +conf: + glance: + DEFAULT: + bind_host: 127.0.0.1 + keystone_authtoken: + cafile: /etc/glance/certs/ca.crt + glance_store: + https_ca_certificates_file: /etc/glance/certs/ca.crt + glance_registry: + DEFAULT: + bind_host: 127.0.0.1 + keystone_authtoken: + cafile: /etc/glance/certs/ca.crt + nginx: | + worker_processes 1; + daemon off; + user nginx; + + events { + worker_connections 1024; + } + + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + sendfile on; + keepalive_timeout 65s; + tcp_nodelay on; + + log_format main '[nginx] method=$request_method path=$request_uri ' + 'status=$status upstream_status=$upstream_status duration=$request_time size=$body_bytes_sent ' + '"$remote_user" "$http_referer" "$http_user_agent"'; + + access_log /dev/stdout main; + + upstream websocket { + server 127.0.0.1:$PORT; + } + + server { + server_name {{ printf "%s.%s.svc.%s" "${SHORTNAME}" .Release.Namespace .Values.endpoints.cluster_domain_suffix }}; + listen $POD_IP:$PORT ssl; + + client_max_body_size 0; + + ssl_certificate /etc/nginx/certs/tls.crt; + ssl_certificate_key /etc/nginx/certs/tls.key; + ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; + + location / { + proxy_pass_request_headers on; + + proxy_http_version 1.1; + proxy_pass http://websocket; + proxy_read_timeout 90; + } + } + } +network: + api: + ingress: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "https" + registry: + ingress: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "https" + +endpoints: + identity: + name: keystone + auth: + admin: + cacert: /etc/ssl/certs/openstack-helm.crt + glance: + cacert: /etc/ssl/certs/openstack-helm.crt + test: + cacert: /etc/ssl/certs/openstack-helm.crt + scheme: + default: https + port: + api: + default: 443 + image: + host_fqdn_override: + default: + tls: + secretName: glance-tls-api + issuerRef: + name: ca-issuer + scheme: + default: https + public: https + port: + api: + public: 443 + image_registry: + host_fqdn_override: + default: + tls: + secretName: glance-tls-reg + issuerRef: + name: ca-issuer + scheme: + default: https + public: https + port: + api: + public: 443 + dashboard: + scheme: + default: https + public: https + port: + web: + default: 80 + public: 443 +pod: + security_context: + glance: + pod: + runAsUser: 0 + resources: + nginx: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" +manifests: + certificates: true +... diff --git a/heat/templates/bin/_heat-api.sh.tpl b/heat/templates/bin/_heat-api.sh.tpl index 1488eacf2c..b756d59e1f 100644 --- a/heat/templates/bin/_heat-api.sh.tpl +++ b/heat/templates/bin/_heat-api.sh.tpl @@ -18,12 +18,48 @@ set -ex COMMAND="${@:-start}" function start () { + +{{- if .Values.manifests.certificates }} + for WSGI_SCRIPT in heat-wsgi-api; do + cp -a $(type -p ${WSGI_SCRIPT}) /var/www/cgi-bin/heat/ + done + + if [ -f /etc/apache2/envvars ]; then + # Loading Apache2 ENV variables + source /etc/apache2/envvars + mkdir -p ${APACHE_RUN_DIR} + fi + +{{- if .Values.conf.software.apache2.a2enmod }} + {{- range .Values.conf.software.apache2.a2enmod }} + a2enmod {{ . }} + {{- end }} +{{- end }} + +{{- if .Values.conf.software.apache2.a2dismod }} + {{- range .Values.conf.software.apache2.a2dismod }} + a2dismod {{ . }} + {{- end }} +{{- end }} + + if [ -f /var/run/apache2/apache2.pid ]; then + # Remove the stale pid for debian/ubuntu images + rm -f /var/run/apache2/apache2.pid + fi + # Starts Apache2 + exec {{ .Values.conf.software.apache2.binary }} {{ .Values.conf.software.apache2.start_parameters }} +{{- else }} exec heat-api \ --config-file /etc/heat/heat.conf +{{- end }} } function stop () { +{{- if .Values.manifests.certificates }} + {{ .Values.conf.software.apache2.binary }} -k graceful-stop +{{- else }} kill -TERM 1 +{{- end }} } $COMMAND diff --git a/heat/templates/bin/_heat-cfn.sh.tpl b/heat/templates/bin/_heat-cfn.sh.tpl index 97f8279882..757b59afc9 100644 --- a/heat/templates/bin/_heat-cfn.sh.tpl +++ b/heat/templates/bin/_heat-cfn.sh.tpl @@ -18,12 +18,49 @@ set -ex COMMAND="${@:-start}" function start () { +{{- if .Values.manifests.certificates }} + for WSGI_SCRIPT in heat-wsgi-api-cfn; do + cp -a $(type -p ${WSGI_SCRIPT}) /var/www/cgi-bin/heat/ + done + + if [ -f /etc/apache2/envvars ]; then + # Loading Apache2 ENV variables + source /etc/apache2/envvars + mkdir -p ${APACHE_RUN_DIR} + fi + + +{{- if .Values.conf.software.apache2.a2enmod }} + {{- range .Values.conf.software.apache2.a2enmod }} + a2enmod {{ . }} + {{- end }} +{{- end }} + +{{- if .Values.conf.software.apache2.a2dismod }} + {{- range .Values.conf.software.apache2.a2dismod }} + a2dismod {{ . }} + {{- end }} +{{- end }} + + + if [ -f /var/run/apache2/apache2.pid ]; then + # Remove the stale pid for debian/ubuntu images + rm -f /var/run/apache2/apache2.pid + fi + # Starts Apache2 + exec {{ .Values.conf.software.apache2.binary }} {{ .Values.conf.software.apache2.start_parameters }} +{{- else }} exec heat-api-cfn \ --config-file /etc/heat/heat.conf +{{- end }} } function stop () { +{{- if .Values.manifests.certificates }} + {{ .Values.conf.software.apache2.binary }} -k graceful-stop +{{- else }} kill -TERM 1 +{{- end }} } $COMMAND diff --git a/heat/templates/certificates.yaml b/heat/templates/certificates.yaml new file mode 100644 index 0000000000..353dfd69dc --- /dev/null +++ b/heat/templates/certificates.yaml @@ -0,0 +1,18 @@ +{{/* +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.certificates -}} +{{ dict "envAll" . "service" "orchestration" "type" "internal" | include "helm-toolkit.manifests.certificates" }} +{{ dict "envAll" . "service" "cloudformation" "type" "internal" | include "helm-toolkit.manifests.certificates" }} +{{- end -}} diff --git a/heat/templates/configmap-etc.yaml b/heat/templates/configmap-etc.yaml index 79e9acd25e..75ccee0bb5 100644 --- a/heat/templates/configmap-etc.yaml +++ b/heat/templates/configmap-etc.yaml @@ -136,6 +136,11 @@ data: logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} api-paste.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.paste | b64enc }} policy.json: {{ toJson .Values.conf.policy | b64enc }} +{{- if .Values.manifests.certificates }} +{{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.mpm_event "key" "mpm_event.conf" "format" "Secret" ) | indent 2 }} +{{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_heat "key" "wsgi-heat.conf" "format" "Secret" ) | indent 2 }} +{{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_cfn "key" "wsgi-cnf.conf" "format" "Secret" ) | indent 2 }} +{{- end }} api_audit_map.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.api_audit_map | b64enc }} {{- range $key, $value := $envAll.Values.conf.rally_tests.templates }} {{ printf "test_template_%d" $key }}: {{ $value.template | b64enc }} diff --git a/heat/templates/deployment-api.yaml b/heat/templates/deployment-api.yaml index f76093b5a5..d6ada3736e 100644 --- a/heat/templates/deployment-api.yaml +++ b/heat/templates/deployment-api.yaml @@ -83,6 +83,8 @@ spec: mountPath: /tmp - name: pod-etc-heat mountPath: /etc/heat + - name: wsgi-heat + mountPath: /var/www/cgi-bin/heat - name: heat-bin mountPath: /tmp/heat-api.sh subPath: heat-api.sh @@ -109,12 +111,25 @@ spec: mountPath: /etc/heat/api_audit_map.conf subPath: api_audit_map.conf readOnly: true + {{- if .Values.manifests.certificates }} + - name: heat-etc + mountPath: {{ .Values.conf.software.apache2.site_dir }}/heat-api.conf + subPath: wsgi-heat.conf + readOnly: true + - name: heat-etc + mountPath: {{ .Values.conf.software.apache2.mods_dir }}/mpm_event.conf + subPath: mpm_event.conf + readOnly: true + {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.orchestration.api.internal "path" "/etc/heat/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_heat_api.volumeMounts }}{{ toYaml $mounts_heat_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-heat emptyDir: {} + - name: wsgi-heat + emptyDir: {} - name: heat-bin configMap: name: heat-bin @@ -123,5 +138,6 @@ spec: secret: secretName: heat-etc defaultMode: 0444 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_heat_api.volumes }}{{ toYaml $mounts_heat_api.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/heat/templates/deployment-cfn.yaml b/heat/templates/deployment-cfn.yaml index 65be294e62..1a5061d563 100644 --- a/heat/templates/deployment-cfn.yaml +++ b/heat/templates/deployment-cfn.yaml @@ -83,6 +83,8 @@ spec: mountPath: /tmp - name: pod-etc-heat mountPath: /etc/heat + - name: wsgi-heat + mountPath: /var/www/cgi-bin/heat - name: heat-bin mountPath: /tmp/heat-cfn.sh subPath: heat-cfn.sh @@ -109,12 +111,25 @@ spec: mountPath: /etc/heat/api_audit_map.conf subPath: api_audit_map.conf readOnly: true + {{- if .Values.manifests.certificates }} + - name: heat-etc + mountPath: {{ .Values.conf.software.apache2.site_dir }}/heat-api-cfn.conf + subPath: wsgi-cnf.conf + readOnly: true + - name: heat-etc + mountPath: {{ .Values.conf.software.apache2.mods_dir }}/mpm_event.conf + subPath: mpm_event.conf + readOnly: true + {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.cloudformation.cfn.internal "path" "/etc/heat/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_heat_cfn.volumeMounts }}{{ toYaml $mounts_heat_cfn.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} - name: pod-etc-heat emptyDir: {} + - name: wsgi-heat + emptyDir: {} - name: heat-bin configMap: name: heat-bin @@ -123,5 +138,6 @@ spec: secret: secretName: heat-etc defaultMode: 0444 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.cloudformation.cfn.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_heat_cfn.volumes }}{{ toYaml $mounts_heat_cfn.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/heat/templates/deployment-engine.yaml b/heat/templates/deployment-engine.yaml index da007ef780..e78521d46f 100644 --- a/heat/templates/deployment-engine.yaml +++ b/heat/templates/deployment-engine.yaml @@ -99,6 +99,7 @@ spec: mountPath: /etc/heat/policy.json subPath: policy.json readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.orchestration.api.internal "path" "/etc/heat/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_heat_engine.volumeMounts }}{{ toYaml $mounts_heat_engine.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp @@ -113,5 +114,6 @@ spec: secret: secretName: heat-etc defaultMode: 0444 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_heat_engine.volumes }}{{ toYaml $mounts_heat_engine.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/heat/templates/ingress-api.yaml b/heat/templates/ingress-api.yaml index d72d3f7cd5..8d5c9a0364 100644 --- a/heat/templates/ingress-api.yaml +++ b/heat/templates/ingress-api.yaml @@ -13,6 +13,11 @@ limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} -{{- $ingressOpts := dict "envAll" . "backendServiceType" "orchestration" "backendPort" "h-api" -}} +{{- $envAll := . }} +{{- $ingressOpts := dict "envAll" $envAll "backendServiceType" "orchestration" "backendPort" "h-api" -}} +{{- $secretName := $envAll.Values.secrets.tls.orchestration.api.internal -}} +{{- if and .Values.manifests.certificates $secretName -}} +{{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.orchestration.host_fqdn_override.default.tls.issuerRef.name -}} +{{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} diff --git a/heat/templates/ingress-cfn.yaml b/heat/templates/ingress-cfn.yaml index fac7cda739..d965338477 100644 --- a/heat/templates/ingress-cfn.yaml +++ b/heat/templates/ingress-cfn.yaml @@ -13,6 +13,11 @@ limitations under the License. */}} {{- if and .Values.manifests.ingress_cfn .Values.network.cfn.ingress.public }} -{{- $ingressOpts := dict "envAll" . "backendService" "cfn" "backendServiceType" "cloudformation" "backendPort" "h-cfn" -}} +{{- $envAll := . }} +{{- $ingressOpts := dict "envAll" $envAll "backendService" "cfn" "backendServiceType" "cloudformation" "backendPort" "h-cfn" -}} +{{- $secretName := $envAll.Values.secrets.tls.cloudformation.cfn.internal -}} +{{- if and .Values.manifests.certificates $secretName -}} +{{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.cloudformation.host_fqdn_override.default.tls.issuerRef.name -}} +{{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} diff --git a/heat/templates/job-bootstrap.yaml b/heat/templates/job-bootstrap.yaml index 8334e12f9c..f6ba562f74 100644 --- a/heat/templates/job-bootstrap.yaml +++ b/heat/templates/job-bootstrap.yaml @@ -15,5 +15,8 @@ limitations under the License. {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "heat" "keystoneUser" .Values.bootstrap.ks_user "logConfigFile" .Values.conf.heat.DEFAULT.log_config_append -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $bootstrapJob "tlsSecret" .Values.secrets.tls.orchestration.api.internal -}} +{{- end -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} diff --git a/heat/templates/job-ks-endpoints.yaml b/heat/templates/job-ks-endpoints.yaml index 61989035ab..a593e1c7bc 100644 --- a/heat/templates/job-ks-endpoints.yaml +++ b/heat/templates/job-ks-endpoints.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "heat" "serviceTypes" ( tuple "orchestration" "cloudformation" ) -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.orchestration.api.internal -}} +{{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} diff --git a/heat/templates/job-ks-service.yaml b/heat/templates/job-ks-service.yaml index b468ff2397..f8f274b187 100644 --- a/heat/templates/job-ks-service.yaml +++ b/heat/templates/job-ks-service.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "heat" "serviceTypes" ( tuple "orchestration" "cloudformation" ) -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.orchestration.api.internal -}} +{{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} diff --git a/heat/templates/job-ks-user-domain.yaml b/heat/templates/job-ks-user-domain.yaml index 9158402092..8e64c7f324 100644 --- a/heat/templates/job-ks-user-domain.yaml +++ b/heat/templates/job-ks-user-domain.yaml @@ -53,8 +53,9 @@ spec: mountPath: /tmp/ks-domain-user.sh subPath: ks-domain-user.sh readOnly: true +{{ dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} env: -{{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME @@ -88,4 +89,5 @@ spec: configMap: name: heat-bin defaultMode: 0555 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} diff --git a/heat/templates/job-ks-user-trustee.yaml b/heat/templates/job-ks-user-trustee.yaml index a9fadc8fa8..0c67e9231a 100644 --- a/heat/templates/job-ks-user-trustee.yaml +++ b/heat/templates/job-ks-user-trustee.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_user_trustee }} {{- $ksUserJob := dict "envAll" . "serviceName" "heat" "serviceUser" "heat_trustee" -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.orchestration.api.internal -}} +{{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} diff --git a/heat/templates/job-ks-user.yaml b/heat/templates/job-ks-user.yaml index 6a08b355bb..863457c262 100644 --- a/heat/templates/job-ks-user.yaml +++ b/heat/templates/job-ks-user.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "heat" -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.orchestration.api.internal -}} +{{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} diff --git a/heat/templates/job-trusts.yaml b/heat/templates/job-trusts.yaml index 10f156d908..08e8576326 100644 --- a/heat/templates/job-trusts.yaml +++ b/heat/templates/job-trusts.yaml @@ -57,9 +57,10 @@ spec: mountPath: /tmp/trusts.sh subPath: trusts.sh readOnly: true +{{ dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_heat_trusts.volumeMounts }}{{ toYaml $mounts_heat_trusts.volumeMounts | indent 12 }}{{ end }} env: -{{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin "useCA" $envAll.Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: SERVICE_OS_ROLES @@ -75,4 +76,5 @@ spec: configMap: name: heat-bin defaultMode: 0555 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_heat_trusts.volumes }}{{ toYaml $mounts_heat_trusts.volumes | indent 8 }}{{ end }} diff --git a/heat/templates/pod-rally-test.yaml b/heat/templates/pod-rally-test.yaml index 52d2aee70c..9aa6373e96 100644 --- a/heat/templates/pod-rally-test.yaml +++ b/heat/templates/pod-rally-test.yaml @@ -49,8 +49,9 @@ spec: mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" $envAll.Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} env: -{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME @@ -65,7 +66,7 @@ spec: {{ tuple $envAll "test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} env: -{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} @@ -94,6 +95,7 @@ spec: subPath: {{ printf "test_template_%d" $key }} readOnly: true {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" $envAll.Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{ if $mounts_tests.volumeMounts }}{{ toYaml $mounts_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp @@ -108,5 +110,6 @@ spec: defaultMode: 0555 - name: rally-db emptyDir: {} +{{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.secrets.tls.orchestration.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{ if $mounts_tests.volumes }}{{ toYaml $mounts_tests.volumes | indent 4 }}{{ end }} {{- end }} diff --git a/heat/values.yaml b/heat/values.yaml index 347858395f..5f64051c1d 100644 --- a/heat/values.yaml +++ b/heat/values.yaml @@ -797,10 +797,11 @@ secrets: orchestration: api: public: heat-tls-public + internal: heat-tls-api cloudformation: cfn: public: cloudformation-tls-public - + internal: heat-tls-cfn # typically overridden by environmental # values, but should include all endpoints # required by this chart @@ -1262,6 +1263,7 @@ network_policy: - {} manifests: + certificates: false configmap_bin: true configmap_etc: true cron_job_engine_cleaner: true diff --git a/heat/values_overrides/tls.yaml b/heat/values_overrides/tls.yaml new file mode 100644 index 0000000000..895916f99c --- /dev/null +++ b/heat/values_overrides/tls.yaml @@ -0,0 +1,182 @@ +--- +conf: + software: + apache2: + binary: apache2 + start_parameters: -DFOREGROUND + site_dir: /etc/apache2/sites-enabled + conf_dir: /etc/apache2/conf-enabled + mods_dir: /etc/apache2/mods-available + a2enmod: + - ssl + a2dismod: null + mpm_event: | + + ServerLimit 1024 + StartServers 32 + MinSpareThreads 32 + MaxSpareThreads 256 + ThreadsPerChild 25 + MaxRequestsPerChild 128 + ThreadLimit 720 + + wsgi_heat: | + {{- $portInt := tuple "orchestration" "internal" "api" $ | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + Listen {{ $portInt }} + + ServerName {{ printf "%s.%s.svc.%s" "heat-api" .Release.Namespace .Values.endpoints.cluster_domain_suffix }} + WSGIDaemonProcess heat-api processes=1 threads=1 user=heat display-name=%{GROUP} + WSGIProcessGroup heat-api + WSGIScriptAlias / /var/www/cgi-bin/heat/heat-wsgi-api + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + AllowEncodedSlashes On + = 2.4> + ErrorLogFormat "%{cu}t %M" + + SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded + ErrorLog /dev/stdout + CustomLog /dev/stdout combined env=!forwarded + CustomLog /dev/stdout proxy env=forwarded + + SSLEngine on + SSLCertificateFile /etc/heat/certs/tls.crt + SSLCertificateKeyFile /etc/heat/certs/tls.key + SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 + SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 + SSLHonorCipherOrder on + + + wsgi_cfn: | + {{- $portInt := tuple "cloudformation" "internal" "api" $ | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + Listen {{ $portInt }} + + ServerName {{ printf "%s.%s.svc.%s" "heat-api-cfn" .Release.Namespace .Values.endpoints.cluster_domain_suffix }} + WSGIDaemonProcess heat-api-cfn processes=1 threads=1 user=heat display-name=%{GROUP} + WSGIProcessGroup heat-api-cfn + WSGIScriptAlias / /var/www/cgi-bin/heat/heat-wsgi-api-cfn + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + AllowEncodedSlashes On + = 2.4> + ErrorLogFormat "%{cu}t %M" + + SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded + ErrorLog /dev/stdout + CustomLog /dev/stdout combined env=!forwarded + CustomLog /dev/stdout proxy env=forwarded + + SSLEngine on + SSLCertificateFile /etc/heat/certs/tls.crt + SSLCertificateKeyFile /etc/heat/certs/tls.key + SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 + SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 + SSLHonorCipherOrder on + + + heat: + clients_neutron: + ca_file: /etc/heat/certs/ca.crt + clients_cinder: + ca_file: /etc/heat/certs/ca.crt + clients_glance: + ca_file: /etc/heat/certs/ca.crt + clients_nova: + ca_file: /etc/heat/certs/ca.crt + clients_swift: + ca_file: /etc/heat/certs/ca.crt + ssl: + ca_file: /etc/heat/certs/ca.crt + keystone_authtoken: + cafile: /etc/heat/certs/ca.crt + clients: + ca_file: /etc/heat/certs/ca.crt + clients_heat: + ca_file: /etc/heat/certs/ca.crt + clients_keystone: + ca_file: /etc/heat/certs/ca.crt + +network: + api: + ingress: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "https" + cfn: + ingress: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "https" + cloudwatch: + ingress: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "https" + +pod: + security_context: + heat: + container: + heat_api: + readOnlyRootFilesystem: false + runAsUser: 0 + heat_cfn: + readOnlyRootFilesystem: false + runAsUser: 0 + +endpoints: + identity: + auth: + admin: + cacert: /etc/ssl/certs/openstack-helm.crt + heat: + cacert: /etc/ssl/certs/openstack-helm.crt + heat_trustee: + cacert: /etc/ssl/certs/openstack-helm.crt + heat_stack_user: + cacert: /etc/ssl/certs/openstack-helm.crt + test: + cacert: /etc/ssl/certs/openstack-helm.crt + scheme: + default: https + port: + api: + default: 443 + orchestration: + host_fqdn_override: + default: + tls: + secretName: heat-tls-api + issuerRef: + name: ca-issuer + scheme: + default: https + port: + api: + public: 443 + cloudformation: + host_fqdn_override: + default: + tls: + secretName: heat-tls-cfn + issuerRef: + name: ca-issuer + scheme: + default: https + port: + api: + public: 443 + # Cloudwatch does not get an entry in the keystone service catalog + cloudwatch: + host_fqdn_override: + default: + tls: + secretName: heat-tls-cloudwatch + issuerRef: + name: ca-issuer + kind: Issuer + ingress: + port: + ingress: + default: 443 + +manifests: + certificates: true +... diff --git a/horizon/templates/certificates.yaml b/horizon/templates/certificates.yaml new file mode 100644 index 0000000000..8dbb884a56 --- /dev/null +++ b/horizon/templates/certificates.yaml @@ -0,0 +1,17 @@ +{{/* +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.certificates -}} +{{ dict "envAll" . "service" "dashboard" "type" "internal" | include "helm-toolkit.manifests.certificates" }} +{{- end -}} diff --git a/horizon/templates/deployment.yaml b/horizon/templates/deployment.yaml index 519fb82659..974aaf41ad 100644 --- a/horizon/templates/deployment.yaml +++ b/horizon/templates/deployment.yaml @@ -78,14 +78,14 @@ spec: containerPort: {{ tuple "dashboard" "internal" "web" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} readinessProbe: httpGet: - scheme: HTTP + scheme: {{ tuple "dashboard" "internal" "web" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "dashboard" "internal" "web" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 15 periodSeconds: 10 livenessProbe: httpGet: - scheme: HTTP + scheme: {{ tuple "dashboard" "internal" "web" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: / port: {{ tuple "dashboard" "internal" "web" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} initialDelaySeconds: 180 @@ -129,6 +129,7 @@ spec: subPath: {{ base $policyFile }} readOnly: true {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.dashboard.dashboard.internal "path" "/etc/openstack-dashboard/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_horizon.volumeMounts }}{{ toYaml $mounts_horizon.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp @@ -145,5 +146,6 @@ spec: secret: secretName: horizon-etc defaultMode: 0444 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.dashboard.dashboard.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_horizon.volumes }}{{ toYaml $mounts_horizon.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/horizon/templates/ingress-api.yaml b/horizon/templates/ingress-api.yaml index a713c47bc5..252ac523e1 100644 --- a/horizon/templates/ingress-api.yaml +++ b/horizon/templates/ingress-api.yaml @@ -13,6 +13,11 @@ limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.dashboard.ingress.public }} -{{- $ingressOpts := dict "envAll" . "backendService" "dashboard" "backendServiceType" "dashboard" "backendPort" "web" -}} +{{- $envAll := . }} +{{- $ingressOpts := dict "envAll" $envAll "backendService" "dashboard" "backendServiceType" "dashboard" "backendPort" "web" -}} +{{- $secretName := $envAll.Values.secrets.tls.dashboard.dashboard.internal -}} +{{- if and .Values.manifests.certificates $secretName -}} +{{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.dashboard.host_fqdn_override.default.tls.issuerRef.name -}} +{{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} diff --git a/horizon/values.yaml b/horizon/values.yaml index 1d977f18db..5c8d3093d8 100644 --- a/horizon/values.yaml +++ b/horizon/values.yaml @@ -183,6 +183,7 @@ conf: # values will not work horizon_secret_key: 9aee62c0-5253-4a86-b189-e0fb71fa503c debug: "False" + use_ssl: "False" keystone_multidomain_support: "True" keystone_default_domain: Default disable_password_reveal: "True" @@ -266,6 +267,7 @@ conf: # If Horizon is being served through SSL, then uncomment the following two # settings to better secure the cookies from security exploits + USE_SSL = {{ .Values.conf.horizon.local_settings.config.use_ssl }} CSRF_COOKIE_SECURE = {{ .Values.conf.horizon.local_settings.config.csrf_cookie_secure }} SESSION_COOKIE_SECURE = {{ .Values.conf.horizon.local_settings.config.session_cookie_secure }} @@ -425,8 +427,10 @@ conf: # Disable SSL certificate checks (useful for self-signed certificates): #OPENSTACK_SSL_NO_VERIFY = True + {{- if .Values.manifests.certificates }} # The CA certificate to use to verify SSL connections - #OPENSTACK_SSL_CACERT = '/path/to/cacert.pem' + OPENSTACK_SSL_CACERT = '/etc/openstack-dashboard/certs/ca.crt' + {{- end }} # The OPENSTACK_KEYSTONE_BACKEND settings can be used to identify the # capabilities of the auth backend for Keystone. @@ -2133,6 +2137,7 @@ secrets: dashboard: dashboard: public: horizon-tls-public + internal: horizon-tls-web # typically overridden by environmental # values, but should include all endpoints @@ -2253,6 +2258,7 @@ network_policy: - {} manifests: + certificates: false configmap_bin: true configmap_etc: true deployment: true diff --git a/horizon/values_overrides/tls.yaml b/horizon/values_overrides/tls.yaml new file mode 100644 index 0000000000..82e25d0259 --- /dev/null +++ b/horizon/values_overrides/tls.yaml @@ -0,0 +1,109 @@ +--- +network: + dashboard: + ingress: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "https" +conf: + software: + apache2: + a2enmod: + - headers + - rewrite + - ssl + horizon: + apache: | + + Listen 0.0.0.0:{{ tuple "dashboard" "internal" "web" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy + + SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded + CustomLog /dev/stdout combined env=!forwarded + CustomLog /dev/stdout proxy env=forwarded + + + ServerName horizon-int.openstack.svc.cluster.local + RewriteEngine On + RewriteCond %{HTTPS} off + RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L] + + + + ServerName horizon-int.openstack.svc.cluster.local + WSGIScriptReloading On + WSGIDaemonProcess horizon-http processes=5 threads=1 user=horizon group=horizon display-name=%{GROUP} python-path=/var/lib/kolla/venv/lib/python2.7/site-packages + WSGIProcessGroup horizon-http + WSGIScriptAlias / /var/www/cgi-bin/horizon/django.wsgi + WSGIPassAuthorization On + + RewriteEngine On + RewriteCond %{REQUEST_METHOD} !^(POST|PUT|GET|DELETE|PATCH) + RewriteRule .* - [F] + + + Require all granted + + + Alias /static /var/www/html/horizon + + SetHandler static + + + = 2.4> + ErrorLogFormat "%{cu}t %M" + + ErrorLog /dev/stdout + TransferLog /dev/stdout + + SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded + CustomLog /dev/stdout combined env=!forwarded + CustomLog /dev/stdout proxy env=forwarded + + ErrorLog /dev/stdout + SSLEngine on + SSLCertificateFile /etc/openstack-dashboard/certs/tls.crt + SSLCertificateKeyFile /etc/openstack-dashboard/certs/tls.key + SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 + SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 + SSLHonorCipherOrder on + + local_settings: + config: + use_ssl: "True" + csrf_cookie_secure: "True" + enforce_password_check: "True" + session_cookie_secure: "True" + session_cookie_httponly: "True" +endpoints: + identity: + auth: + admin: + cacert: /etc/ssl/certs/openstack-helm.crt + scheme: + default: https + port: + api: + default: 443 + dashboard: + host_fqdn_override: + default: + tls: + secretName: horizon-tls-web + issuerRef: + name: ca-issuer + scheme: + default: https + public: https + port: + web: + default: 443 + public: 443 + ingress: + port: + ingress: + default: 443 +manifests: + certificates: true +... diff --git a/keystone/templates/bin/_keystone-api.sh.tpl b/keystone/templates/bin/_keystone-api.sh.tpl index 5d4286a976..d7350674e7 100644 --- a/keystone/templates/bin/_keystone-api.sh.tpl +++ b/keystone/templates/bin/_keystone-api.sh.tpl @@ -51,6 +51,10 @@ function start () { } function stop () { + if [ -f /etc/apache2/envvars ]; then + # Loading Apache2 ENV variables + source /etc/apache2/envvars + fi {{ .Values.conf.software.apache2.binary }} -k graceful-stop } diff --git a/keystone/templates/certificates.yaml b/keystone/templates/certificates.yaml new file mode 100644 index 0000000000..d545771e86 --- /dev/null +++ b/keystone/templates/certificates.yaml @@ -0,0 +1,17 @@ +{{/* +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.certificates -}} +{{ dict "envAll" . "service" "identity" "type" "internal" | include "helm-toolkit.manifests.certificates" }} +{{- end -}} diff --git a/keystone/templates/deployment-api.yaml b/keystone/templates/deployment-api.yaml index 03891187d7..f58e42d39c 100644 --- a/keystone/templates/deployment-api.yaml +++ b/keystone/templates/deployment-api.yaml @@ -14,7 +14,7 @@ limitations under the License. {{- define "apiProbeTemplate" }} httpGet: - scheme: HTTP + scheme: {{ tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} path: /v3/ port: {{ tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} {{- end }} @@ -147,6 +147,7 @@ spec: {{- end }} - name: keystone-credential-keys mountPath: {{ .Values.conf.keystone.credential.key_repository }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal "path" "/etc/keystone/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_keystone_api.volumeMounts }}{{ toYaml $mounts_keystone_api.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp @@ -180,5 +181,6 @@ spec: - name: keystone-credential-keys secret: secretName: keystone-credential-keys +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_keystone_api.volumes }}{{ toYaml $mounts_keystone_api.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/keystone/templates/ingress-api.yaml b/keystone/templates/ingress-api.yaml index bf40e31127..7bdcee60c2 100644 --- a/keystone/templates/ingress-api.yaml +++ b/keystone/templates/ingress-api.yaml @@ -13,6 +13,11 @@ limitations under the License. */}} {{- if and .Values.manifests.ingress_api .Values.network.api.ingress.public }} -{{- $ingressOpts := dict "envAll" . "backendServiceType" "identity" "backendPort" "ks-pub" -}} +{{- $envAll := . }} +{{- $ingressOpts := dict "envAll" $envAll "backendServiceType" "identity" "backendPort" "ks-pub" -}} +{{- $secretName := $envAll.Values.secrets.tls.identity.api.internal -}} +{{- if and .Values.manifests.certificates $secretName -}} +{{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.identity.host_fqdn_override.default.tls.issuerRef.name -}} +{{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} diff --git a/keystone/templates/job-bootstrap.yaml b/keystone/templates/job-bootstrap.yaml index c874746cdd..db222426ed 100644 --- a/keystone/templates/job-bootstrap.yaml +++ b/keystone/templates/job-bootstrap.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "keystone" "keystoneUser" .Values.bootstrap.ks_user "logConfigFile" .Values.conf.keystone.DEFAULT.log_config_append -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $bootstrapJob "tlsSecret" .Values.secrets.tls.identity.api.internal -}} +{{- end -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} diff --git a/keystone/templates/pod-rally-test.yaml b/keystone/templates/pod-rally-test.yaml index 12c1eeb331..569e8c3c78 100644 --- a/keystone/templates/pod-rally-test.yaml +++ b/keystone/templates/pod-rally-test.yaml @@ -50,8 +50,9 @@ spec: mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} env: -{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME @@ -66,7 +67,7 @@ spec: {{ tuple $envAll "test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} env: -{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} @@ -89,6 +90,7 @@ spec: readOnly: true - name: rally-db mountPath: /var/lib/rally +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{ if $mounts_tests.volumeMounts }}{{ toYaml $mounts_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp @@ -103,5 +105,6 @@ spec: defaultMode: 0555 - name: rally-db emptyDir: {} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.identity.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{ if $mounts_tests.volumes }}{{ toYaml $mounts_tests.volumes | indent 4 }}{{ end }} {{- end }} diff --git a/keystone/values.yaml b/keystone/values.yaml index 4ed00ffc30..6aacce7fe2 100644 --- a/keystone/values.yaml +++ b/keystone/values.yaml @@ -1070,6 +1070,7 @@ secrets: identity: api: public: keystone-tls-public + internal: keystone-tls-api # typically overridden by environmental # values, but should include all endpoints @@ -1235,6 +1236,7 @@ endpoints: default: 80 manifests: + certificates: false configmap_bin: true configmap_etc: true cron_credential_rotate: true diff --git a/keystone/values_overrides/tls.yaml b/keystone/values_overrides/tls.yaml new file mode 100644 index 0000000000..5aaa7cf3dc --- /dev/null +++ b/keystone/values_overrides/tls.yaml @@ -0,0 +1,80 @@ +--- +network: + api: + ingress: + annotations: + nginx.ingress.kubernetes.io/rewrite-target: null + nginx.ingress.kubernetes.io/backend-protocol: "https" +pod: + security_context: + keystone: + pod: + runAsUser: 0 + container: + keystone_api: + readOnlyRootFilesystem: false + allowPrivilegeEscalation: false +conf: + software: + apache2: + a2enmod: + - ssl + wsgi_keystone: | + {{- $portInt := tuple "identity" "internal" "api" $ | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + {{- $vh := tuple "identity" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} + + Listen 0.0.0.0:{{ $portInt }} + + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy + + SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded + CustomLog /dev/stdout combined env=!forwarded + CustomLog /dev/stdout proxy env=forwarded + + + ServerName {{ printf "%s.%s.svc.%s" "keystone-api" .Release.Namespace .Values.endpoints.cluster_domain_suffix }} + WSGIDaemonProcess keystone-public processes=1 threads=1 user=keystone group=keystone display-name=%{GROUP} + WSGIProcessGroup keystone-public + WSGIScriptAlias / /var/www/cgi-bin/keystone/keystone-wsgi-public + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + = 2.4> + ErrorLogFormat "%{cu}t %M" + + ErrorLog /dev/stdout + + SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded + CustomLog /dev/stdout combined env=!forwarded + CustomLog /dev/stdout proxy env=forwarded + + SSLEngine on + SSLCertificateFile /etc/keystone/certs/tls.crt + SSLCertificateKeyFile /etc/keystone/certs/tls.key + SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 + SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 + SSLHonorCipherOrder on + +endpoints: + identity: + auth: + admin: + cacert: /etc/ssl/certs/openstack-helm.crt + test: + cacert: /etc/ssl/certs/openstack-helm.crt + host_fqdn_override: + default: + tls: + secretName: keystone-tls-api + issuerRef: + name: ca-issuer + kind: Issuer + scheme: + default: https + public: https + port: + api: + default: 443 +manifests: + certificates: true +... diff --git a/neutron/templates/bin/_neutron-rpc-server.sh.tpl b/neutron/templates/bin/_neutron-rpc-server.sh.tpl new file mode 100644 index 0000000000..f9a40e83e9 --- /dev/null +++ b/neutron/templates/bin/_neutron-rpc-server.sh.tpl @@ -0,0 +1,30 @@ +#!/bin/bash + +{{/* +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 +COMMAND="${@:-start}" + +function start () { + exec neutron-rpc-server \ + --config-file /etc/neutron/neutron.conf \ + --config-file /etc/neutron/plugins/ml2/ml2_conf.ini +} + +function stop () { + kill -TERM 1 +} + +$COMMAND diff --git a/neutron/templates/bin/_neutron-server.sh.tpl b/neutron/templates/bin/_neutron-server.sh.tpl index 83ca918658..039dd4fa99 100644 --- a/neutron/templates/bin/_neutron-server.sh.tpl +++ b/neutron/templates/bin/_neutron-server.sh.tpl @@ -18,6 +18,55 @@ set -ex COMMAND="${@:-start}" function start () { +{{- if .Values.manifests.certificates }} + add_config="" +{{- if .Values.conf.plugins.taas.taas.enabled }} + add_config+='taas_plugin.ini;' +{{- end }} +{{- if ( has "sriov" .Values.network.backend ) }} + add_config+='sriov_agent.ini;' +{{- end }} +{{- if .Values.conf.plugins.l2gateway }} + add_config+='l2gw_plugin.ini;' +{{- end }} + + export OS_NEUTRON_CONFIG_FILES=${add_config} + + for WSGI_SCRIPT in neutron-api; do + cp -a $(type -p ${WSGI_SCRIPT}) /var/www/cgi-bin/neutron/ + done + + if [ -f /etc/apache2/envvars ]; then + # Loading Apache2 ENV variables + source /etc/apache2/envvars + mkdir -p ${APACHE_RUN_DIR} + fi + +{{- if .Values.conf.software.apache2.a2enmod }} + {{- range .Values.conf.software.apache2.a2enmod }} + a2enmod {{ . }} + {{- end }} +{{- end }} + +{{- if .Values.conf.software.apache2.a2ensite }} + {{- range .Values.conf.software.apache2.a2ensite }} + a2ensite {{ . }} + {{- end }} +{{- end }} + +{{- if .Values.conf.software.apache2.a2dismod }} + {{- range .Values.conf.software.apache2.a2dismod }} + a2dismod {{ . }} + {{- end }} +{{- end }} + + if [ -f /var/run/apache2/apache2.pid ]; then + # Remove the stale pid for debian/ubuntu images + rm -f /var/run/apache2/apache2.pid + fi + # Starts Apache2 + exec {{ .Values.conf.software.apache2.binary }} {{ .Values.conf.software.apache2.start_parameters }} +{{- else }} exec neutron-server \ --config-file /etc/neutron/neutron.conf \ {{- if ( has "tungstenfabric" .Values.network.backend ) }} @@ -34,10 +83,18 @@ function start () { {{- if .Values.conf.plugins.l2gateway }} \ --config-file /etc/neutron/l2gw_plugin.ini {{- end }} +{{- end }} } function stop () { +{{- if .Values.manifests.certificates }} + if [ -f /etc/apache2/envvars ]; then + source /etc/apache2/envvars + fi + {{ .Values.conf.software.apache2.binary }} -k graceful-stop +{{- else }} kill -TERM 1 +{{- end }} } $COMMAND diff --git a/neutron/templates/certificates.yaml b/neutron/templates/certificates.yaml new file mode 100644 index 0000000000..f65396d0f8 --- /dev/null +++ b/neutron/templates/certificates.yaml @@ -0,0 +1,17 @@ +{{/* +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.certificates -}} +{{ dict "envAll" . "service" "network" "type" "internal" | include "helm-toolkit.manifests.certificates" }} +{{- end -}} diff --git a/neutron/templates/configmap-bin.yaml b/neutron/templates/configmap-bin.yaml index 3cb1ee4a24..8ae7ff337e 100644 --- a/neutron/templates/configmap-bin.yaml +++ b/neutron/templates/configmap-bin.yaml @@ -81,6 +81,10 @@ data: {{ tuple "bin/_neutron-bagpipe-bgp.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-bagpipe-bgp-init.sh: | {{ tuple "bin/_neutron-bagpipe-bgp-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} +{{- if .Values.manifests.certificates }} + neutron-rpc-server.sh: | +{{ tuple "bin/_neutron-rpc-server.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} +{{- end }} neutron-server.sh: | {{ tuple "bin/_neutron-server.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} neutron-ironic-agent.sh: | diff --git a/neutron/templates/configmap-etc.yaml b/neutron/templates/configmap-etc.yaml index 719f82c586..f046712d9d 100644 --- a/neutron/templates/configmap-etc.yaml +++ b/neutron/templates/configmap-etc.yaml @@ -272,6 +272,10 @@ data: rootwrap.conf: {{ $envAll.Values.conf.rootwrap | b64enc }} auto_bridge_add: {{ toJson $envAll.Values.conf.auto_bridge_add | b64enc }} dpdk.conf: {{ toJson $envAll.Values.conf.ovs_dpdk | b64enc }} +{{- if .Values.manifests.certificates }} +{{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.mpm_event "key" "mpm_event.conf" "format" "Secret" ) | indent 2 }} +{{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_neutron_server "key" "wsgi-server.conf" "format" "Secret" ) | indent 2 }} +{{- end }} {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }} {{- $filePrefix := replace "_" "-" $key }} {{ printf "%s.filters" $filePrefix }}: {{ $value.content | b64enc }} diff --git a/neutron/templates/daemonset-metadata-agent.yaml b/neutron/templates/daemonset-metadata-agent.yaml index ca897a28cb..258d558774 100644 --- a/neutron/templates/daemonset-metadata-agent.yaml +++ b/neutron/templates/daemonset-metadata-agent.yaml @@ -189,6 +189,7 @@ spec: mountPath: /run/netns mountPropagation: Bidirectional {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_metadata.metadata.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_neutron_metadata_agent.volumeMounts }}{{ toYaml $mounts_neutron_metadata_agent.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp @@ -211,6 +212,7 @@ spec: hostPath: path: /run/netns {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_metadata.metadata.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_neutron_metadata_agent.volumes }}{{ toYaml $mounts_neutron_metadata_agent.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} diff --git a/neutron/templates/deployment-server.yaml b/neutron/templates/deployment-server.yaml index 74c9d3f18d..6403b92fd8 100644 --- a/neutron/templates/deployment-server.yaml +++ b/neutron/templates/deployment-server.yaml @@ -177,10 +177,64 @@ spec: mountPath: /etc/neutron/policy.json subPath: policy.json readOnly: true + {{- if .Values.manifests.certificates }} + - name: wsgi-neutron + mountPath: /var/www/cgi-bin/neutron + - name: neutron-etc + mountPath: {{ .Values.conf.software.apache2.site_dir }}/wsgi-server.conf + subPath: wsgi-server.conf + readOnly: true + - name: neutron-etc + mountPath: {{ .Values.conf.software.apache2.mods_dir }}/mpm_event.conf + subPath: mpm_event.conf + readOnly: true + {{ end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.network.server.internal "path" "/etc/neutron/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_neutron_server.volumeMounts }}{{ toYaml $mounts_neutron_server.volumeMounts | indent 12 }}{{ end }} +{{- if .Values.manifests.certificates }} + - name: neutron-rpc-server +{{ tuple $envAll "neutron_rpc_server" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.rpc_server | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} +{{ dict "envAll" $envAll "application" "neutron_server" "container" "neutron_rpc_server" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} +{{ dict "envAll" $envAll "component" "server" "container" "server" "type" "readiness" "probeTemplate" (include "serverReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} +{{ dict "envAll" $envAll "component" "server" "container" "server" "type" "liveness" "probeTemplate" (include "serverLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} + command: + - /tmp/neutron-rpc-server.sh + - start + lifecycle: + preStop: + exec: + command: + - /tmp/neutron-rpc-server.sh + - stop + volumeMounts: + - name: neutron-bin + mountPath: /tmp/neutron-rpc-server.sh + subPath: neutron-rpc-server.sh + readOnly: true + - name: neutron-etc + mountPath: /etc/neutron/neutron.conf + subPath: neutron.conf + readOnly: true + {{- if .Values.conf.neutron.DEFAULT.log_config_append }} + - name: neutron-etc + mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }} + subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }} + readOnly: true + {{- end }} + - name: neutron-etc + mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini + subPath: ml2_conf.ini + readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.network.server.internal "path" "/etc/neutron/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} +{{- end }} volumes: - name: pod-tmp emptyDir: {} + {{- if .Values.manifests.certificates }} + - name: wsgi-neutron + emptyDir: {} + {{- end }} - name: pod-var-neutron emptyDir: {} - name: neutron-bin @@ -195,5 +249,6 @@ spec: - name: neutron-plugin-shared emptyDir: {} {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.network.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_neutron_server.volumes }}{{ toYaml $mounts_neutron_server.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/neutron/templates/ingress-server.yaml b/neutron/templates/ingress-server.yaml index bd444b9115..6e6eb735db 100644 --- a/neutron/templates/ingress-server.yaml +++ b/neutron/templates/ingress-server.yaml @@ -13,6 +13,11 @@ limitations under the License. */}} {{- if and .Values.manifests.ingress_server .Values.network.server.ingress.public }} -{{- $ingressOpts := dict "envAll" . "backendService" "server" "backendServiceType" "network" "backendPort" "q-api" -}} +{{- $envAll := . }} +{{- $ingressOpts := dict "envAll" $envAll "backendService" "server" "backendServiceType" "network" "backendPort" "q-api" -}} +{{- $secretName := $envAll.Values.secrets.tls.network.server.internal -}} +{{- if and .Values.manifests.certificates $secretName }} +{{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.network.host_fqdn_override.default.tls.issuerRef.name -}} +{{- end }} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} diff --git a/neutron/templates/job-bootstrap.yaml b/neutron/templates/job-bootstrap.yaml index b3c8287c66..d3edb310ba 100644 --- a/neutron/templates/job-bootstrap.yaml +++ b/neutron/templates/job-bootstrap.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} {{- $bootstrapJob := dict "envAll" . "serviceName" "neutron" "keystoneUser" .Values.bootstrap.ks_user "logConfigFile" .Values.conf.neutron.DEFAULT.log_config_append -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $bootstrapJob "tlsSecret" .Values.secrets.tls.network.server.internal -}} +{{- end -}} {{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} {{- end }} diff --git a/neutron/templates/job-ks-endpoints.yaml b/neutron/templates/job-ks-endpoints.yaml index 6493fd30e5..d045dec387 100644 --- a/neutron/templates/job-ks-endpoints.yaml +++ b/neutron/templates/job-ks-endpoints.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "neutron" "serviceTypes" ( tuple "network" ) -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.network.server.internal -}} +{{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} diff --git a/neutron/templates/job-ks-service.yaml b/neutron/templates/job-ks-service.yaml index 9afd0368cc..9e9d537686 100644 --- a/neutron/templates/job-ks-service.yaml +++ b/neutron/templates/job-ks-service.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "neutron" "serviceTypes" ( tuple "network" ) -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.network.server.internal -}} +{{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} diff --git a/neutron/templates/job-ks-user.yaml b/neutron/templates/job-ks-user.yaml index f80551c519..6976ad9fea 100644 --- a/neutron/templates/job-ks-user.yaml +++ b/neutron/templates/job-ks-user.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "neutron" -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.network.server.internal -}} +{{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} diff --git a/neutron/templates/pod-rally-test.yaml b/neutron/templates/pod-rally-test.yaml index 7e1f7254a1..042b9e954a 100644 --- a/neutron/templates/pod-rally-test.yaml +++ b/neutron/templates/pod-rally-test.yaml @@ -51,8 +51,9 @@ spec: mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.network.server.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} env: -{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME @@ -66,7 +67,7 @@ spec: - name: {{ .Release.Name }}-reset {{ tuple $envAll "purge_test" | include "helm-toolkit.snippets.image" | indent 6 }} env: -{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} @@ -95,13 +96,14 @@ spec: readOnly: true - name: pod-tmp mountPath: /tmp/pod-tmp +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.network.server.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{ end }} containers: - name: neutron-test {{ tuple $envAll "test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} env: -{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} @@ -124,6 +126,7 @@ spec: readOnly: true - name: rally-db mountPath: /var/lib/rally +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.network.server.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{ if $mounts_tests.volumeMounts }}{{ toYaml $mounts_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp @@ -138,5 +141,6 @@ spec: defaultMode: 0555 - name: rally-db emptyDir: {} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.network.server.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{ if $mounts_tests.volumes }}{{ toYaml $mounts_tests.volumes | indent 4 }}{{ end }} {{- end }} diff --git a/neutron/values.yaml b/neutron/values.yaml index 730d55d094..1041419c2f 100644 --- a/neutron/values.yaml +++ b/neutron/values.yaml @@ -31,6 +31,7 @@ images: ks_service: docker.io/openstackhelm/heat:stein-ubuntu_bionic ks_endpoints: docker.io/openstackhelm/heat:stein-ubuntu_bionic neutron_server: docker.io/openstackhelm/neutron:stein-ubuntu_bionic + neutron_rpc_server: docker.io/openstackhelm/neutron:stein-ubuntu_bionic neutron_dhcp: docker.io/openstackhelm/neutron:stein-ubuntu_bionic neutron_metadata: docker.io/openstackhelm/neutron:stein-ubuntu_bionic neutron_l3: docker.io/openstackhelm/neutron:stein-ubuntu_bionic @@ -473,6 +474,7 @@ pod: capabilities: add: - SYS_MODULE + - SYS_CHROOT runAsUser: 0 readOnlyRootFilesystem: true neutron_lb_agent_init: @@ -497,6 +499,7 @@ pod: capabilities: add: - SYS_MODULE + - SYS_CHROOT runAsUser: 0 readOnlyRootFilesystem: true neutron_ovs_agent_init: @@ -2179,9 +2182,13 @@ secrets: admin: neutron-rabbitmq-admin neutron: neutron-rabbitmq-user tls: + compute_metadata: + metadata: + internal: metadata-tls-metadata network: server: public: neutron-tls-public + internal: neutron-tls-server # typically overridden by environmental # values, but should include all endpoints @@ -2468,6 +2475,7 @@ network_policy: - {} manifests: + certificates: false configmap_bin: true configmap_etc: true daemonset_dhcp_agent: true diff --git a/neutron/values_overrides/rocky-ubuntu_bionic.yaml b/neutron/values_overrides/rocky-ubuntu_bionic.yaml index 858b298334..a0def9e187 100644 --- a/neutron/values_overrides/rocky-ubuntu_bionic.yaml +++ b/neutron/values_overrides/rocky-ubuntu_bionic.yaml @@ -16,5 +16,6 @@ images: neutron_netns_cleanup_cron: "docker.io/openstackhelm/neutron:rocky-ubuntu_bionic" neutron_openvswitch_agent: "docker.io/openstackhelm/neutron:rocky-ubuntu_bionic" neutron_server: "docker.io/openstackhelm/neutron:rocky-ubuntu_bionic" + neutron_rpc_server: "docker.io/openstackhelm/neutron:rocky-ubuntu_bionic" neutron_bagpipe_bgp: "docker.io/openstackhelm/neutron:rocky-ubuntu_bionic" ... diff --git a/neutron/values_overrides/tls.yaml b/neutron/values_overrides/tls.yaml new file mode 100644 index 0000000000..d9f609e6f2 --- /dev/null +++ b/neutron/values_overrides/tls.yaml @@ -0,0 +1,145 @@ +--- +network: + server: + ingress: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "https" +pod: + security_context: + neutron_server: + pod: + runAsUser: 0 + container: + neutron_server: + readOnlyRootFilesystem: false + neutron_rpc_server: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false + resources: + rpc_server: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" +conf: + software: + apache2: + binary: apache2 + start_parameters: -DFOREGROUND + conf_dir: /etc/apache2/conf-enabled + site_dir: /etc/apache2/sites-available + mods_dir: /etc/apache2/mods-available + a2enmod: + - ssl + a2dismod: null + a2ensite: + - wsgi-server + mpm_event: | + + ServerLimit 1024 + StartServers 32 + MinSpareThreads 32 + MaxSpareThreads 256 + ThreadsPerChild 25 + MaxRequestsPerChild 128 + ThreadLimit 720 + + wsgi_neutron_server: | + + Require all granted + + + {{- $portInt := tuple "network" "internal" "api" $ | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + Listen {{ $portInt }} + + ServerName {{ printf "%s.%s.svc.%s" "neutron-server" .Release.Namespace .Values.endpoints.cluster_domain_suffix }} + WSGIDaemonProcess neutron-server processes=1 threads=1 user=neutron display-name=%{GROUP} + WSGIProcessGroup neutron-server + WSGIScriptAlias / /var/www/cgi-bin/neutron/neutron-api + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + AllowEncodedSlashes On + = 2.4> + ErrorLogFormat "%{cu}t %M" + + SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded + ErrorLog /dev/stdout + CustomLog /dev/stdout combined env=!forwarded + CustomLog /dev/stdout proxy env=forwarded + + SSLEngine on + SSLCertificateFile /etc/neutron/certs/tls.crt + SSLCertificateKeyFile /etc/neutron/certs/tls.key + SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 + SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 + SSLHonorCipherOrder on + + Alias /networking /var/www/cgi-bin/neutron/neutron-api + + SetHandler wsgi-script + Options +ExecCGI + WSGIProcessGroup neutron-server + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + + + WSGISocketPrefix /var/run/apache2 + neutron: + nova: + cafile: /etc/neutron/certs/ca.crt + keystone_authtoken: + cafile: /etc/neutron/certs/ca.crt + metadata_agent: + DEFAULT: + auth_ca_cert: /etc/ssl/certs/openstack-helm.crt + nova_metadata_port: 443 + nova_metadata_protocol: https +endpoints: + compute: + scheme: + default: https + port: + api: + public: 443 + compute_metadata: + scheme: + default: https + port: + metadata: + public: 443 + identity: + auth: + admin: + cacert: /etc/ssl/certs/openstack-helm.crt + neutron: + cacert: /etc/ssl/certs/openstack-helm.crt + nova: + cacert: /etc/ssl/certs/openstack-helm.crt + test: + cacert: /etc/ssl/certs/openstack-helm.crt + scheme: + default: https + port: + api: + default: 443 + network: + host_fqdn_override: + default: + tls: + secretName: neutron-tls-server + issuerRef: + name: ca-issuer + scheme: + default: https + port: + api: + public: 443 + ingress: + port: + ingress: + default: 443 +manifests: + certificates: true +... diff --git a/neutron/values_overrides/train-ubuntu_bionic.yaml b/neutron/values_overrides/train-ubuntu_bionic.yaml index 001fb20389..7cb270c4c5 100644 --- a/neutron/values_overrides/train-ubuntu_bionic.yaml +++ b/neutron/values_overrides/train-ubuntu_bionic.yaml @@ -15,5 +15,6 @@ images: neutron_metadata: "docker.io/openstackhelm/neutron:train-ubuntu_bionic" neutron_openvswitch_agent: "docker.io/openstackhelm/neutron:train-ubuntu_bionic" neutron_server: "docker.io/openstackhelm/neutron:train-ubuntu_bionic" + neutron_rpc_server: "docker.io/openstackhelm/neutron:train-ubuntu_bionic" neutron_bagpipe_bgp: "docker.io/openstackhelm/neutron:train-ubuntu_bionic" ... diff --git a/nova/templates/bin/_nova-api-metadata.sh.tpl b/nova/templates/bin/_nova-api-metadata.sh.tpl index 246a11c646..18195f26d0 100644 --- a/nova/templates/bin/_nova-api-metadata.sh.tpl +++ b/nova/templates/bin/_nova-api-metadata.sh.tpl @@ -18,13 +18,51 @@ set -ex COMMAND="${@:-start}" function start () { +{{- if .Values.manifests.certificates }} + for WSGI_SCRIPT in nova-metadata-wsgi; do + cp -a $(type -p ${WSGI_SCRIPT}) /var/www/cgi-bin/nova/ + done + + if [ -f /etc/apache2/envvars ]; then + # Loading Apache2 ENV variables + source /etc/apache2/envvars + mkdir -p ${APACHE_RUN_DIR} + fi + +{{- if .Values.conf.software.apache2.a2enmod }} + {{- range .Values.conf.software.apache2.a2enmod }} + a2enmod {{ . }} + {{- end }} +{{- end }} + +{{- if .Values.conf.software.apache2.a2dismod }} + {{- range .Values.conf.software.apache2.a2dismod }} + a2dismod {{ . }} + {{- end }} +{{- end }} + + if [ -f /var/run/apache2/apache2.pid ]; then + # Remove the stale pid for debian/ubuntu images + rm -f /var/run/apache2/apache2.pid + fi + # Starts Apache2 + exec {{ .Values.conf.software.apache2.binary }} {{ .Values.conf.software.apache2.start_parameters }} +{{- else }} exec nova-api-metadata \ --config-file /etc/nova/nova.conf \ --config-file /tmp/pod-shared/nova-api-metadata.ini +{{- end }} } function stop () { +{{- if .Values.manifests.certificates }} + if [ -f /etc/apache2/envvars ]; then + source /etc/apache2/envvars + fi + {{ .Values.conf.software.apache2.binary }} -k graceful-stop +{{- else }} kill -TERM 1 +{{- end }} } $COMMAND diff --git a/nova/templates/bin/_nova-api.sh.tpl b/nova/templates/bin/_nova-api.sh.tpl index 95fcb130b1..c62de9a6e2 100644 --- a/nova/templates/bin/_nova-api.sh.tpl +++ b/nova/templates/bin/_nova-api.sh.tpl @@ -18,12 +18,51 @@ set -ex COMMAND="${@:-start}" function start () { +{{- if .Values.manifests.certificates }} + for WSGI_SCRIPT in nova-api-wsgi; do + cp -a $(type -p ${WSGI_SCRIPT}) /var/www/cgi-bin/nova/ + done + + if [ -f /etc/apache2/envvars ]; then + # Loading Apache2 ENV variables + source /etc/apache2/envvars + mkdir -p ${APACHE_RUN_DIR} + fi + +{{- if .Values.conf.software.apache2.a2enmod }} + {{- range .Values.conf.software.apache2.a2enmod }} + a2enmod {{ . }} + {{- end }} +{{- end }} + +{{- if .Values.conf.software.apache2.a2dismod }} + {{- range .Values.conf.software.apache2.a2dismod }} + a2dismod {{ . }} + {{- end }} +{{- end }} + + + if [ -f /var/run/apache2/apache2.pid ]; then + # Remove the stale pid for debian/ubuntu images + rm -f /var/run/apache2/apache2.pid + fi + # Starts Apache2 + exec {{ .Values.conf.software.apache2.binary }} {{ .Values.conf.software.apache2.start_parameters }} +{{- else }} exec nova-api-os-compute \ --config-file /etc/nova/nova.conf +{{- end }} } function stop () { +{{- if .Values.manifests.certificates }} + if [ -f /etc/apache2/envvars ]; then + source /etc/apache2/envvars + fi + {{ .Values.conf.software.apache2.binary }} -k graceful-stop +{{- else }} kill -TERM 1 +{{- end }} } $COMMAND diff --git a/nova/templates/bin/_nova-placement-api.sh.tpl b/nova/templates/bin/_nova-placement-api.sh.tpl index 2173399310..762af448fd 100644 --- a/nova/templates/bin/_nova-placement-api.sh.tpl +++ b/nova/templates/bin/_nova-placement-api.sh.tpl @@ -46,6 +46,9 @@ function start () { } function stop () { + if [ -f /etc/apache2/envvars ]; then + source /etc/apache2/envvars + fi {{ .Values.conf.software.apache2.binary }} -k graceful-stop } diff --git a/nova/templates/certificates.yaml b/nova/templates/certificates.yaml new file mode 100644 index 0000000000..3bf6c8db86 --- /dev/null +++ b/nova/templates/certificates.yaml @@ -0,0 +1,27 @@ +{{/* +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.certificates -}} +{{ dict "envAll" . "service" "compute" "type" "internal" | include "helm-toolkit.manifests.certificates" }} +{{- if .Values.manifests.deployment_novncproxy }} +{{ dict "envAll" . "service" "compute_novnc_proxy" "type" "internal" | include "helm-toolkit.manifests.certificates" }} +{{- end }} +{{- if .Values.manifests.deployment_placement }} +{{ dict "envAll" . "service" "placement" "type" "internal" | include "helm-toolkit.manifests.certificates" }} +{{- end }} +{{ dict "envAll" . "service" "compute_metadata" "type" "internal" | include "helm-toolkit.manifests.certificates" }} +{{- if .Values.manifests.deployment_spiceproxy }} +{{ dict "envAll" . "service" "compute_spice_proxy" "type" "internal" | include "helm-toolkit.manifests.certificates" }} +{{- end }} +{{- end -}} diff --git a/nova/templates/configmap-etc.yaml b/nova/templates/configmap-etc.yaml index 5f3ab414a5..2cb202df22 100644 --- a/nova/templates/configmap-etc.yaml +++ b/nova/templates/configmap-etc.yaml @@ -265,6 +265,11 @@ data: nova-ironic.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.nova_ironic | b64enc }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_placement "key" "wsgi-nova-placement.conf" "format" "Secret" ) | indent 2 }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.ssh "key" "ssh-config" "format" "Secret" ) | indent 2 }} +{{- if .Values.manifests.certificates }} +{{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.mpm_event "key" "mpm_event.conf" "format" "Secret" ) | indent 2 }} +{{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_nova_api "key" "wsgi-api.conf" "format" "Secret" ) | indent 2 }} +{{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.wsgi_nova_metadata "key" "wsgi-metadata.conf" "format" "Secret" ) | indent 2 }} +{{- end }} {{- if .Values.conf.security }} {{- include "helm-toolkit.snippets.values_template_renderer" (dict "envAll" $envAll "template" .Values.conf.security "key" "security.conf" "format" "Secret" ) | indent 2 }} {{- end }} diff --git a/nova/templates/cron-job-service-cleaner.yaml b/nova/templates/cron-job-service-cleaner.yaml index 0d897b8ef0..d26499752b 100644 --- a/nova/templates/cron-job-service-cleaner.yaml +++ b/nova/templates/cron-job-service-cleaner.yaml @@ -53,7 +53,7 @@ spec: {{ tuple $envAll "nova_service_cleaner" | include "helm-toolkit.snippets.image" | indent 14 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.service_cleaner | include "helm-toolkit.snippets.kubernetes_resources" | indent 14 }} env: -{{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.nova }} +{{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.nova "useCA" .Values.manifests.certificates}} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 14 }} {{- end }} command: diff --git a/nova/templates/daemonset-compute.yaml b/nova/templates/daemonset-compute.yaml index a37bf1ee52..94aae13165 100644 --- a/nova/templates/daemonset-compute.yaml +++ b/nova/templates/daemonset-compute.yaml @@ -240,6 +240,10 @@ spec: value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" +{{- if .Values.manifests.certificates }} + - name: REQUESTS_CA_BUNDLE + value: "/etc/nova/certs/ca.crt" +{{- end }} {{ dict "envAll" $envAll "component" "compute" "container" "default" "type" "liveness" "probeTemplate" (include "novaComputeLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} {{ dict "envAll" $envAll "component" "compute" "container" "default" "type" "readiness" "probeTemplate" (include "novaComputeReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} command: @@ -377,6 +381,7 @@ spec: subPath: tf-plugin.pth readOnly: true {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_compute.volumeMounts }}{{ toYaml $mounts_nova_compute.volumeMounts | indent 12 }}{{ end }} {{- if .Values.network.sshd.enabled }} - name: nova-compute-ssh @@ -390,6 +395,10 @@ spec: value: {{ include "helm-toolkit.utils.joinListWithComma" .Values.ssh.key_types | quote }} - name: SSH_PORT value: {{ .Values.network.ssh.port | quote }} +{{- if .Values.manifests.certificates }} + - name: REQUESTS_CA_BUNDLE + value: "/etc/nova/certs/ca.crt" +{{- end }} ports: - containerPort: {{ .Values.network.ssh.port }} command: @@ -412,6 +421,7 @@ spec: mountPath: /tmp/ssh-start.sh subPath: ssh-start.sh readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ end }} volumes: - name: pod-tmp @@ -481,6 +491,7 @@ spec: - name: tf-plugin-bin emptyDir: {} {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_compute.volumes }}{{ toYaml $mounts_nova_compute.volumes | indent 8 }}{{ end }} {{- end }} {{- end }} diff --git a/nova/templates/deployment-api-metadata.yaml b/nova/templates/deployment-api-metadata.yaml index 1db588fc7f..824ac76721 100644 --- a/nova/templates/deployment-api-metadata.yaml +++ b/nova/templates/deployment-api-metadata.yaml @@ -166,10 +166,27 @@ spec: - name: pod-shared mountPath: /tmp/pod-shared readOnly: true + {{- if .Values.manifests.certificates }} + - name: wsgi-nova + mountPath: /var/www/cgi-bin/nova + - name: nova-etc + mountPath: {{ .Values.conf.software.apache2.conf_dir }}/wsgi-metadata.conf + subPath: wsgi-metadata.conf + readOnly: true + - name: nova-etc + mountPath: {{ .Values.conf.software.apache2.mods_dir }}/mpm_event.conf + subPath: mpm_event.conf + readOnly: true + {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_metadata.metadata.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_api_metadata.volumeMounts }}{{ toYaml $mounts_nova_api_metadata.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} + {{- if .Values.manifests.certificates }} + - name: wsgi-nova + emptyDir: {} + {{- end }} - name: nova-bin configMap: name: nova-bin @@ -180,5 +197,6 @@ spec: defaultMode: 0444 - name: pod-shared emptyDir: {} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_metadata.metadata.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_api_metadata.volumes }}{{ toYaml $mounts_nova_api_metadata.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/nova/templates/deployment-api-osapi.yaml b/nova/templates/deployment-api-osapi.yaml index 25f1a893ef..998f817fe5 100644 --- a/nova/templates/deployment-api-osapi.yaml +++ b/nova/templates/deployment-api-osapi.yaml @@ -114,10 +114,27 @@ spec: mountPath: /etc/nova/api_audit_map.conf subPath: api_audit_map.conf readOnly: true + {{- if .Values.manifests.certificates }} + - name: wsgi-nova + mountPath: /var/www/cgi-bin/nova + - name: nova-etc + mountPath: {{ .Values.conf.software.apache2.conf_dir }}/wsgi-api.conf + subPath: wsgi-api.conf + readOnly: true + - name: nova-etc + mountPath: {{ .Values.conf.software.apache2.mods_dir }}/mpm_event.conf + subPath: mpm_event.conf + readOnly: true + {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_api_osapi.volumeMounts }}{{ toYaml $mounts_nova_api_osapi.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp emptyDir: {} + {{- if .Values.manifests.certificates }} + - name: wsgi-nova + emptyDir: {} + {{- end }} - name: pod-var-nova emptyDir: {} - name: nova-bin @@ -128,5 +145,6 @@ spec: secret: secretName: nova-etc defaultMode: 0444 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_api_osapi.volumes}}{{ toYaml $mounts_nova_api_osapi.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/nova/templates/deployment-conductor.yaml b/nova/templates/deployment-conductor.yaml index b553e70603..01658abce0 100644 --- a/nova/templates/deployment-conductor.yaml +++ b/nova/templates/deployment-conductor.yaml @@ -88,6 +88,10 @@ spec: value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" +{{- if .Values.manifests.certificates }} + - name: REQUESTS_CA_BUNDLE + value: "/etc/nova/certs/ca.crt" +{{- end }} command: - /tmp/nova-conductor.sh volumeMounts: @@ -115,6 +119,7 @@ spec: mountPath: /etc/nova/policy.yaml subPath: policy.yaml readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" "certs" (tuple "ca.crt") | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_conductor.volumeMounts }}{{ toYaml $mounts_nova_conductor.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp @@ -127,5 +132,6 @@ spec: secret: secretName: nova-etc defaultMode: 0444 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_conductor.volumes }}{{ toYaml $mounts_nova_conductor.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/nova/templates/deployment-novncproxy.yaml b/nova/templates/deployment-novncproxy.yaml index 1ddf571a0c..81837b2035 100644 --- a/nova/templates/deployment-novncproxy.yaml +++ b/nova/templates/deployment-novncproxy.yaml @@ -139,6 +139,7 @@ spec: readOnly: true - name: pod-shared mountPath: /tmp/pod-shared +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_novnc_proxy.novncproxy.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_novncproxy.volumeMounts }}{{ toYaml $mounts_nova_novncproxy.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp @@ -155,5 +156,6 @@ spec: emptyDir: {} - name: pod-shared emptyDir: {} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_novnc_proxy.novncproxy.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_novncproxy.volumes }}{{ toYaml $mounts_nova_novncproxy.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/nova/templates/deployment-placement.yaml b/nova/templates/deployment-placement.yaml index c20c60c2d2..58c9021dc9 100644 --- a/nova/templates/deployment-placement.yaml +++ b/nova/templates/deployment-placement.yaml @@ -120,6 +120,7 @@ spec: subPath: security.conf readOnly: true {{- end }} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.placement.placement.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_placement.volumeMounts }}{{ toYaml $mounts_nova_placement.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp @@ -134,5 +135,6 @@ spec: secret: secretName: nova-etc defaultMode: 0444 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.placement.placement.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_placement.volumes }}{{ toYaml $mounts_nova_placement.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/nova/templates/deployment-scheduler.yaml b/nova/templates/deployment-scheduler.yaml index b843cd3d57..a889c40d8d 100644 --- a/nova/templates/deployment-scheduler.yaml +++ b/nova/templates/deployment-scheduler.yaml @@ -88,6 +88,10 @@ spec: value: "{{ .Values.pod.probes.rpc_timeout }}" - name: RPC_PROBE_RETRIES value: "{{ .Values.pod.probes.rpc_retries }}" +{{- if .Values.manifests.certificates }} + - name: REQUESTS_CA_BUNDLE + value: "/etc/nova/certs/ca.crt" +{{- end }} command: - /tmp/nova-scheduler.sh volumeMounts: @@ -115,6 +119,7 @@ spec: mountPath: /etc/nova/policy.yaml subPath: policy.yaml readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_scheduler.volumeMounts }}{{ toYaml $mounts_nova_scheduler.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp @@ -127,5 +132,6 @@ spec: secret: secretName: nova-etc defaultMode: 0444 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_scheduler.volumes }}{{ toYaml $mounts_nova_scheduler.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/nova/templates/deployment-spiceproxy.yaml b/nova/templates/deployment-spiceproxy.yaml index 5968e40ceb..98046a01a2 100644 --- a/nova/templates/deployment-spiceproxy.yaml +++ b/nova/templates/deployment-spiceproxy.yaml @@ -138,6 +138,7 @@ spec: readOnly: true - name: pod-shared mountPath: /tmp/pod-shared +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_spice_proxy.spiceproxy.internal "path" "/etc/nova/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_nova_spiceproxy.volumeMounts }}{{ toYaml $mounts_nova_spiceproxy.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp @@ -154,5 +155,6 @@ spec: emptyDir: {} - name: pod-shared emptyDir: {} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_spice_proxy.spiceproxy.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_nova_spiceproxy.volumes }}{{ toYaml $mounts_nova_spiceproxy.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/nova/templates/ingress-metadata.yaml b/nova/templates/ingress-metadata.yaml index 8344831fef..36eb8647dd 100644 --- a/nova/templates/ingress-metadata.yaml +++ b/nova/templates/ingress-metadata.yaml @@ -13,6 +13,11 @@ limitations under the License. */}} {{- if and .Values.manifests.ingress_metadata .Values.network.metadata.ingress.public }} -{{- $ingressOpts := dict "envAll" . "backendService" "metadata" "backendServiceType" "compute_metadata" "backendPort" "n-meta" -}} +{{- $envAll := . -}} +{{- $ingressOpts := dict "envAll" $envAll "backendService" "metadata" "backendServiceType" "compute_metadata" "backendPort" "n-meta" -}} +{{- $secretName := $envAll.Values.secrets.tls.compute_metadata.metadata.internal -}} +{{- if and .Values.manifests.certificates $secretName }} +{{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.compute_metadata.host_fqdn_override.default.tls.issuerRef.name -}} +{{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} diff --git a/nova/templates/ingress-novncproxy.yaml b/nova/templates/ingress-novncproxy.yaml index 0875774f96..cad53cf306 100644 --- a/nova/templates/ingress-novncproxy.yaml +++ b/nova/templates/ingress-novncproxy.yaml @@ -13,6 +13,11 @@ limitations under the License. */}} {{- if and .Values.manifests.ingress_novncproxy .Values.network.novncproxy.ingress.public }} -{{- $ingressOpts := dict "envAll" . "backendService" "novncproxy" "backendServiceType" "compute_novnc_proxy" "backendPort" "n-novnc" -}} +{{- $envAll := . }} +{{- $ingressOpts := dict "envAll" $envAll "backendService" "novncproxy" "backendServiceType" "compute_novnc_proxy" "backendPort" "n-novnc" -}} +{{- $secretName := $envAll.Values.secrets.tls.compute_novnc_proxy.novncproxy.internal -}} +{{- if and .Values.manifests.certificates $secretName }} +{{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.compute_novnc_proxy.host_fqdn_override.default.tls.issuerRef.name -}} +{{- end }} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} diff --git a/nova/templates/ingress-osapi.yaml b/nova/templates/ingress-osapi.yaml index b851e9df05..b78f80f438 100644 --- a/nova/templates/ingress-osapi.yaml +++ b/nova/templates/ingress-osapi.yaml @@ -13,6 +13,11 @@ limitations under the License. */}} {{- if and .Values.manifests.ingress_osapi .Values.network.osapi.ingress.public }} -{{- $ingressOpts := dict "envAll" . "backendService" "osapi" "backendServiceType" "compute" "backendPort" "n-api" -}} +{{- $envAll := . -}} +{{- $ingressOpts := dict "envAll" $envAll "backendService" "osapi" "backendServiceType" "compute" "backendPort" "n-api" -}} +{{- $secretName := $envAll.Values.secrets.tls.compute.osapi.internal -}} +{{- if and .Values.manifests.certificates $secretName }} +{{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.compute.host_fqdn_override.default.tls.issuerRef.name -}} +{{- end }} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} diff --git a/nova/templates/ingress-placement.yaml b/nova/templates/ingress-placement.yaml index 8f7b71cde5..28b0f0d3c0 100644 --- a/nova/templates/ingress-placement.yaml +++ b/nova/templates/ingress-placement.yaml @@ -13,6 +13,11 @@ limitations under the License. */}} {{- if and .Values.manifests.ingress_placement .Values.network.placement.ingress.public }} -{{- $ingressOpts := dict "envAll" . "backendService" "placement" "backendServiceType" "placement" "backendPort" "p-api" -}} +{{- $envAll := . -}} +{{- $ingressOpts := dict "envAll" $envAll "backendService" "placement" "backendServiceType" "placement" "backendPort" "p-api" -}} +{{- $secretName := $envAll.Values.secrets.tls.placement.placement.internal -}} +{{- if and .Values.manifests.certificates $secretName }} +{{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.placement.host_fqdn_override.default.tls.issuerRef.name -}} +{{- end }} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} diff --git a/nova/templates/job-bootstrap.yaml b/nova/templates/job-bootstrap.yaml index 45dfac1ccd..036a25a2c8 100644 --- a/nova/templates/job-bootstrap.yaml +++ b/nova/templates/job-bootstrap.yaml @@ -63,7 +63,7 @@ spec: imagePullPolicy: {{ $envAll.Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: -{{- with $env := dict "ksUserSecret" ( index $envAll.Values.secrets.identity $keystoneUser ) }} +{{- with $env := dict "ksUserSecret" ( index $envAll.Values.secrets.identity $keystoneUser ) "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: WAIT_PERCENTAGE @@ -91,6 +91,7 @@ spec: mountPath: {{ $logConfigFile | quote }} subPath: {{ base $logConfigFile | quote }} readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} @@ -104,6 +105,7 @@ spec: secret: secretName: {{ $configMapEtc | quote }} defaultMode: 0444 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 diff --git a/nova/templates/job-cell-setup.yaml b/nova/templates/job-cell-setup.yaml index 0e31b0a290..d0683c9b5c 100644 --- a/nova/templates/job-cell-setup.yaml +++ b/nova/templates/job-cell-setup.yaml @@ -42,7 +42,7 @@ spec: {{ tuple $envAll "nova_cell_setup_init" | include "helm-toolkit.snippets.image" | indent 10 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.cell_setup | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} env: -{{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} command: @@ -54,6 +54,7 @@ spec: mountPath: /tmp/cell-setup-init.sh subPath: cell-setup-init.sh readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal (tuple "ca.crt") | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} containers: - name: nova-cell-setup {{ tuple $envAll "nova_cell_setup" | include "helm-toolkit.snippets.image" | indent 10 }} @@ -96,4 +97,5 @@ spec: configMap: name: nova-bin defaultMode: 0555 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} diff --git a/nova/templates/job-ks-endpoints.yaml b/nova/templates/job-ks-endpoints.yaml index c9177499a0..3d9530e0c0 100644 --- a/nova/templates/job-ks-endpoints.yaml +++ b/nova/templates/job-ks-endpoints.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "nova" "serviceTypes" ( tuple "compute" ) -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.compute.osapi.internal -}} +{{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} diff --git a/nova/templates/job-ks-placement-endpoints.yaml b/nova/templates/job-ks-placement-endpoints.yaml index d907e77219..2147f3cf1d 100644 --- a/nova/templates/job-ks-placement-endpoints.yaml +++ b/nova/templates/job-ks-placement-endpoints.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_placement_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "placement" "configMapBin" "nova-bin" "serviceTypes" ( tuple "placement" ) -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.placement.placement.internal -}} +{{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} diff --git a/nova/templates/job-ks-placement-service.yaml b/nova/templates/job-ks-placement-service.yaml index aa85c77f16..c2c8865c39 100644 --- a/nova/templates/job-ks-placement-service.yaml +++ b/nova/templates/job-ks-placement-service.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_placement_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "placement" "configMapBin" "nova-bin" "serviceTypes" ( tuple "placement" ) -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.placement.placement.internal -}} +{{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} diff --git a/nova/templates/job-ks-placement-user.yaml b/nova/templates/job-ks-placement-user.yaml index d24e540ce8..035c2f025f 100644 --- a/nova/templates/job-ks-placement-user.yaml +++ b/nova/templates/job-ks-placement-user.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_placement_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "placement" "serviceUser" "placement" "configMapBin" "nova-bin" -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.placement.placement.internal -}} +{{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} diff --git a/nova/templates/job-ks-service.yaml b/nova/templates/job-ks-service.yaml index 123da41596..1d4f4e2191 100644 --- a/nova/templates/job-ks-service.yaml +++ b/nova/templates/job-ks-service.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "nova" "serviceTypes" ( tuple "compute" ) -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.compute.osapi.internal -}} +{{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} diff --git a/nova/templates/job-ks-user.yaml b/nova/templates/job-ks-user.yaml index c2f8df3653..4fff45560d 100644 --- a/nova/templates/job-ks-user.yaml +++ b/nova/templates/job-ks-user.yaml @@ -14,5 +14,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "nova" -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.compute.osapi.internal -}} +{{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} diff --git a/nova/templates/pod-rally-test.yaml b/nova/templates/pod-rally-test.yaml index fc161abf1d..eabe8b6c2e 100644 --- a/nova/templates/pod-rally-test.yaml +++ b/nova/templates/pod-rally-test.yaml @@ -50,8 +50,9 @@ spec: mountPath: /tmp/ks-user.sh subPath: ks-user.sh readOnly: true +{{ dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} env: -{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} - name: SERVICE_OS_SERVICE_NAME @@ -66,7 +67,7 @@ spec: {{ tuple $envAll "test" | include "helm-toolkit.snippets.image" | indent 6 }} {{ tuple $envAll $envAll.Values.pod.resources.jobs.tests | include "helm-toolkit.snippets.kubernetes_resources" | indent 6 }} env: -{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" .Values.secrets.identity.admin "useCA" .Values.manifests.certificates}} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 8 }} {{- end }} {{- with $env := dict "ksUserSecret" .Values.secrets.identity.test }} @@ -89,6 +90,7 @@ spec: readOnly: true - name: rally-db mountPath: /var/lib/rally +{{ dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 8 }} {{ if $mounts_tests.volumeMounts }}{{ toYaml $mounts_tests.volumeMounts | indent 8 }}{{ end }} volumes: - name: pod-tmp @@ -103,5 +105,6 @@ spec: defaultMode: 0555 - name: rally-db emptyDir: {} +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute.osapi.internal | include "helm-toolkit.snippets.tls_volume" | indent 4 }} {{ if $mounts_tests.volumes }}{{ toYaml $mounts_tests.volumes | indent 4 }}{{ end }} {{- end }} diff --git a/nova/values.yaml b/nova/values.yaml index 5e1b575a8b..1462cb5fe4 100644 --- a/nova/values.yaml +++ b/nova/values.yaml @@ -1858,12 +1858,22 @@ secrets: compute: osapi: public: nova-tls-public + internal: nova-tls-api compute_novnc_proxy: novncproxy: public: nova-novncproxy-tls-public + internal: nova-novncproxy-tls-proxy placement: placement: public: placement-tls-public + internal: placement-tls-api + compute_metadata: + metadata: + public: metadata-tls-public + internal: metadata-tls-metadata + compute_spice_proxy: + spiceproxy: + internal: nova-tls-spiceproxy # typically overridden by environmental # values, but should include all endpoints @@ -2696,6 +2706,7 @@ network_policy: - {} manifests: + certificates: false configmap_bin: true configmap_etc: true cron_job_cell_setup: true diff --git a/nova/values_overrides/tls.yaml b/nova/values_overrides/tls.yaml new file mode 100644 index 0000000000..7df4dd82e9 --- /dev/null +++ b/nova/values_overrides/tls.yaml @@ -0,0 +1,242 @@ +--- +network: + osapi: + ingress: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "https" + metadata: + ingress: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "https" + placement: + ingress: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "https" + novncproxy: + ingress: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "https" +conf: + mpm_event: | + + ServerLimit 1024 + StartServers 32 + MinSpareThreads 32 + MaxSpareThreads 256 + ThreadsPerChild 25 + MaxRequestsPerChild 128 + ThreadLimit 720 + + wsgi_nova_api: | + {{- $portInt := tuple "compute" "internal" "api" $ | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + Listen {{ $portInt }} + + ServerName {{ printf "%s.%s.svc.%s" "nova-api" .Release.Namespace .Values.endpoints.cluster_domain_suffix }} + WSGIDaemonProcess nova-api processes=1 threads=1 user=nova display-name=%{GROUP} + WSGIProcessGroup nova-api + WSGIScriptAlias / /var/www/cgi-bin/nova/nova-api-wsgi + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + AllowEncodedSlashes On + = 2.4> + ErrorLogFormat "%{cu}t %M" + + SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded + ErrorLog /dev/stdout + CustomLog /dev/stdout combined env=!forwarded + CustomLog /dev/stdout proxy env=forwarded + + SSLEngine on + SSLCertificateFile /etc/nova/certs/tls.crt + SSLCertificateKeyFile /etc/nova/certs/tls.key + SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 + SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 + SSLHonorCipherOrder on + + wsgi_nova_metadata: | + {{- $portInt := tuple "compute_metadata" "internal" "metadata" $ | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + Listen {{ $portInt }} + + ServerName {{ printf "%s.%s.svc.%s" "nova-metadata" .Release.Namespace .Values.endpoints.cluster_domain_suffix }} + WSGIDaemonProcess nova-metadata processes=1 threads=1 user=nova display-name=%{GROUP} + WSGIProcessGroup nova-metadata + WSGIScriptAlias / /var/www/cgi-bin/nova/nova-metadata-wsgi + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + AllowEncodedSlashes On + = 2.4> + ErrorLogFormat "%{cu}t %M" + + SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded + ErrorLog /dev/stdout + CustomLog /dev/stdout combined env=!forwarded + CustomLog /dev/stdout proxy env=forwarded + + SSLEngine on + SSLCertificateFile /etc/nova/certs/tls.crt + SSLCertificateKeyFile /etc/nova/certs/tls.key + SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 + SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 + SSLHonorCipherOrder on + + software: + apache2: + a2enmod: + - ssl + wsgi_placement: | + Listen 0.0.0.0:{{ tuple "placement" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy + + SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded + CustomLog /dev/stdout combined env=!forwarded + CustomLog /dev/stdout proxy env=forwarded + + + WSGIDaemonProcess placement-api processes=4 threads=1 user=nova group=nova display-name=%{GROUP} + WSGIProcessGroup placement-api + WSGIScriptAlias / /var/www/cgi-bin/nova/nova-placement-api + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + = 2.4> + ErrorLogFormat "%{cu}t %M" + + ErrorLog /dev/stdout + + SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded + CustomLog /dev/stdout combined env=!forwarded + CustomLog /dev/stdout proxy env=forwarded + + SSLEngine on + SSLCertificateFile /etc/nova/certs/tls.crt + SSLCertificateKeyFile /etc/nova/certs/tls.key + SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 + SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 + SSLHonorCipherOrder on + + + Alias /placement /var/www/cgi-bin/nova/nova-placement-api + + SetHandler wsgi-script + Options +ExecCGI + + WSGIProcessGroup placement-api + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + + nova: + glance: + cafile: /etc/nova/certs/ca.crt + ironic: + cafile: /etc/nova/certs/ca.crt + neutron: + cafile: /etc/nova/certs/ca.crt + keystone_authtoken: + cafile: /etc/nova/certs/ca.crt + cinder: + cafile: /etc/nova/certs/ca.crt + placement: + cafile: /etc/nova/certs/ca.crt + keystone: + cafile: /etc/nova/certs/ca.crt +endpoints: + identity: + auth: + admin: + cacert: /etc/ssl/certs/openstack-helm.crt + nova: + cacert: /etc/ssl/certs/openstack-helm.crt + neutron: + cacert: /etc/ssl/certs/openstack-helm.crt + placement: + cacert: /etc/ssl/certs/openstack-helm.crt + test: + cacert: /etc/ssl/certs/openstack-helm.crt + scheme: + default: https + port: + api: + default: 443 + image: + scheme: + default: https + port: + api: + public: 443 + compute: + host_fqdn_override: + default: + tls: + secretName: nova-tls-api + issuerRef: + name: ca-issuer + scheme: + default: 'https' + port: + api: + public: 443 + compute_metadata: + host_fqdn_override: + default: + tls: + secretName: metadata-tls-metadata + issuerRef: + name: ca-issuer + scheme: + default: https + port: + metadata: + public: 443 + compute_novnc_proxy: + host_fqdn_override: + default: + tls: + secretName: nova-novncproxy-tls-proxy + issuerRef: + name: ca-issuer + scheme: + default: https + port: + novnc_proxy: + public: 443 + compute_spice_proxy: + host_fqdn_override: + default: + tls: + secretName: nova-tls-spiceproxy + issuerRef: + name: ca-issuer + scheme: + default: https + placement: + host_fqdn_override: + default: + tls: + secretName: placement-tls-api + issuerRef: + name: ca-issuer + scheme: + default: https + port: + api: + public: 443 + network: + scheme: + default: https + port: + api: + public: 443 +pod: + security_context: + nova: + container: + nova_api: + runAsUser: 0 + readOnlyRootFilesystem: false + nova_osapi: + runAsUser: 0 + readOnlyRootFilesystem: false +manifests: + certificates: true +... diff --git a/placement/templates/bin/_placement-api.sh.tpl b/placement/templates/bin/_placement-api.sh.tpl index 7c5acb35d1..2b1b12d143 100644 --- a/placement/templates/bin/_placement-api.sh.tpl +++ b/placement/templates/bin/_placement-api.sh.tpl @@ -49,6 +49,9 @@ function start () { } function stop () { + if [ -f /etc/apache2/envvars ]; then + source /etc/apache2/envvars + fi {{ .Values.conf.software.apache2.binary }} -k graceful-stop } diff --git a/placement/templates/certificates.yaml b/placement/templates/certificates.yaml new file mode 100644 index 0000000000..ada7fde1b3 --- /dev/null +++ b/placement/templates/certificates.yaml @@ -0,0 +1,17 @@ +{{/* +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.certificates -}} +{{ dict "envAll" . "service" "placement" "type" "internal" | include "helm-toolkit.manifests.certificates" }} +{{- end -}} diff --git a/placement/templates/deployment.yaml b/placement/templates/deployment.yaml index 65bbf6d089..1d63b34c5b 100644 --- a/placement/templates/deployment.yaml +++ b/placement/templates/deployment.yaml @@ -106,6 +106,7 @@ spec: mountPath: /etc/apache2/conf-enabled/wsgi-placement.conf subPath: wsgi-placement.conf readOnly: true +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.placement.api.internal "path" "/etc/placement/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} {{ if $mounts_placement.volumeMounts }}{{ toYaml $mounts_placement.volumeMounts | indent 12 }}{{ end }} volumes: - name: pod-tmp @@ -120,5 +121,6 @@ spec: secret: secretName: placement-etc defaultMode: 0444 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.placement.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{ if $mounts_placement.volumes }}{{ toYaml $mounts_placement.volumes | indent 8 }}{{ end }} {{- end }} diff --git a/placement/templates/ingress.yaml b/placement/templates/ingress.yaml index 38f17d9b7e..68ce111a55 100644 --- a/placement/templates/ingress.yaml +++ b/placement/templates/ingress.yaml @@ -15,6 +15,11 @@ limitations under the License. */}} {{- if and .Values.manifests.ingress .Values.network.api.ingress.public }} -{{- $ingressOpts := dict "envAll" . "backendServiceType" "placement" "backendPort" "p-api" -}} +{{- $envAll := . -}} +{{- $ingressOpts := dict "envAll" $envAll "backendServiceType" "placement" "backendPort" "p-api" -}} +{{- $secretName := $envAll.Values.secrets.tls.placement.api.internal -}} +{{- if and .Values.manifests.certificates $secretName -}} +{{- $_ := set $ingressOpts "certIssuer" .Values.endpoints.placement.host_fqdn_override.default.tls.issuerRef.name -}} +{{- end -}} {{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} {{- end }} diff --git a/placement/templates/job-db-migrate.yaml b/placement/templates/job-db-migrate.yaml index b021213663..61ddc63faa 100644 --- a/placement/templates/job-db-migrate.yaml +++ b/placement/templates/job-db-migrate.yaml @@ -43,7 +43,7 @@ spec: command: - /tmp/db-migrate.sh env: -{{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin }} +{{- with $env := dict "ksUserSecret" $envAll.Values.secrets.identity.admin "useCA" .Values.manifests.certificates }} {{- include "helm-toolkit.snippets.keystone_openrc_env_vars" $env | indent 12 }} {{- end }} - name: NOVA_API_USER @@ -73,6 +73,7 @@ spec: mountPath: /etc/placement/placement.conf subPath: placement.conf readOnly: true +{{ dict "enabled" .Values.manifests.certificates "name" $envAll.Values.secrets.tls.placement.api.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} volumes: - name: pod-tmp emptyDir: {} @@ -84,4 +85,5 @@ spec: secret: secretName: placement-etc defaultMode: 0444 +{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.placement.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} {{- end }} diff --git a/placement/templates/job-ks-endpoints.yaml b/placement/templates/job-ks-endpoints.yaml index 19269f95c8..ce5f634705 100644 --- a/placement/templates/job-ks-endpoints.yaml +++ b/placement/templates/job-ks-endpoints.yaml @@ -16,5 +16,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_endpoints }} {{- $ksServiceJob := dict "envAll" . "serviceName" "placement" "serviceTypes" ( tuple "placement" ) -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.placement.api.internal -}} +{{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_endpoints" }} {{- end }} diff --git a/placement/templates/job-ks-service.yaml b/placement/templates/job-ks-service.yaml index 87151af01f..ee6b896649 100644 --- a/placement/templates/job-ks-service.yaml +++ b/placement/templates/job-ks-service.yaml @@ -16,5 +16,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_service }} {{- $ksServiceJob := dict "envAll" . "serviceName" "placement" "serviceTypes" ( tuple "placement" ) -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.placement.api.internal -}} +{{- end -}} {{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} {{- end }} diff --git a/placement/templates/job-ks-user.yaml b/placement/templates/job-ks-user.yaml index 1dd4d11db8..70d9207450 100644 --- a/placement/templates/job-ks-user.yaml +++ b/placement/templates/job-ks-user.yaml @@ -16,5 +16,8 @@ limitations under the License. {{- if .Values.manifests.job_ks_user }} {{- $ksUserJob := dict "envAll" . "serviceName" "placement" -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.placement.api.internal -}} +{{- end -}} {{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} {{- end }} diff --git a/placement/values.yaml b/placement/values.yaml index 7367958e36..a0ae93e7e2 100644 --- a/placement/values.yaml +++ b/placement/values.yaml @@ -415,6 +415,7 @@ secrets: placement: api: public: placement-tls-public + internal: placement-tls-api dependencies: dynamic: @@ -471,6 +472,7 @@ dependencies: service: oslo_db manifests: + certificates: false configmap_bin: true configmap_etc: true deployment: true diff --git a/placement/values_overrides/tls.yaml b/placement/values_overrides/tls.yaml new file mode 100644 index 0000000000..b2906032e4 --- /dev/null +++ b/placement/values_overrides/tls.yaml @@ -0,0 +1,78 @@ +--- +network: + api: + ingress: + annotations: + nginx.ingress.kubernetes.io/backend-protocol: "https" +conf: + software: + apache2: + a2enmod: + - ssl + placement: + keystone_authtoken: + cafile: /etc/placement/certs/ca.crt + wsgi_placement: | + Listen 0.0.0.0:{{ tuple "placement" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy + SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded + CustomLog /dev/stdout combined env=!forwarded + CustomLog /dev/stdout proxy env=forwarded + + ServerName {{ printf "%s.%s.svc.%s" "placement-api" .Release.Namespace .Values.endpoints.cluster_domain_suffix }} + WSGIDaemonProcess placement-api processes=4 threads=1 user=placement group=placement display-name=%{GROUP} + WSGIProcessGroup placement-api + WSGIScriptAlias / /var/www/cgi-bin/placement/placement-api + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + = 2.4> + ErrorLogFormat "%{cu}t %M" + + ErrorLog /dev/stdout + SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded + CustomLog /dev/stdout combined env=!forwarded + CustomLog /dev/stdout proxy env=forwarded + + SSLEngine on + SSLCertificateFile /etc/placement/certs/tls.crt + SSLCertificateKeyFile /etc/placement/certs/tls.key + SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 + SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256 + SSLHonorCipherOrder on + + Alias /placement /var/www/cgi-bin/placement/placement-api + + SetHandler wsgi-script + Options +ExecCGI + WSGIProcessGroup placement-api + WSGIApplicationGroup %{GLOBAL} + WSGIPassAuthorization On + +endpoints: + identity: + auth: + admin: + cacert: /etc/ssl/certs/openstack-helm.crt + placement: + cacert: /etc/ssl/certs/openstack-helm.crt + scheme: + default: https + port: + api: + default: 443 + placement: + host_fqdn_override: + default: + tls: + secretName: placement-tls-api + issuerRef: + name: ca-issuer + scheme: + default: https + port: + api: + public: 443 +manifests: + certificates: true +... diff --git a/tools/deployment/common/setup-client.sh b/tools/deployment/common/setup-client.sh index 84e19ba29f..395054b5e3 100755 --- a/tools/deployment/common/setup-client.sh +++ b/tools/deployment/common/setup-client.sh @@ -20,19 +20,36 @@ sudo -H -E pip3 install \ sudo -H mkdir -p /etc/openstack sudo -H chown -R $(id -un): /etc/openstack -tee /etc/openstack/clouds.yaml << EOF -clouds: - openstack_helm: - region_name: RegionOne - identity_api_version: 3 - auth: - username: 'admin' - password: 'password' - project_name: 'admin' - project_domain_name: 'default' - user_domain_name: 'default' - auth_url: 'http://keystone.openstack.svc.cluster.local/v3' +FEATURE_GATE="tls"; if [[ ${FEATURE_GATES//,/ } =~ (^|[[:space:]])${FEATURE_GATE}($|[[:space:]]) ]]; then + tee /etc/openstack/clouds.yaml << EOF + clouds: + openstack_helm: + region_name: RegionOne + identity_api_version: 3 + cacert: /etc/openstack-helm/certs/ca/ca.pem + auth: + username: 'admin' + password: 'password' + project_name: 'admin' + project_domain_name: 'default' + user_domain_name: 'default' + auth_url: 'https://keystone.openstack.svc.cluster.local/v3' EOF +else + tee /etc/openstack/clouds.yaml << EOF + clouds: + openstack_helm: + region_name: RegionOne + identity_api_version: 3 + auth: + username: 'admin' + password: 'password' + project_name: 'admin' + project_domain_name: 'default' + user_domain_name: 'default' + auth_url: 'http://keystone.openstack.svc.cluster.local/v3' +EOF +fi #NOTE: Build helm-toolkit, most charts depend on helm-toolkit make helm-toolkit diff --git a/tools/deployment/component/ceph/ceph.sh b/tools/deployment/component/ceph/ceph.sh index 1763740edc..da7e4e52d3 100755 --- a/tools/deployment/component/ceph/ceph.sh +++ b/tools/deployment/component/ceph/ceph.sh @@ -14,6 +14,8 @@ set -xe +export CEPH_ENABLED=true + #NOTE: Lint and package chart export HELM_CHART_ROOT_PATH="${HELM_CHART_ROOT_PATH:="${OSH_INFRA_PATH:="../openstack-helm-infra"}"}" for CHART in ceph-mon ceph-osd ceph-client ceph-provisioners; do diff --git a/tools/deployment/component/compute-kit/compute-kit.sh b/tools/deployment/component/compute-kit/compute-kit.sh index a6d2652c2e..da8ca2843e 100755 --- a/tools/deployment/component/compute-kit/compute-kit.sh +++ b/tools/deployment/component/compute-kit/compute-kit.sh @@ -13,8 +13,8 @@ # under the License. set -xe - : ${CEPH_ENABLED:=false} - : ${RUN_HELM_TESTS:="yes"} +: ${CEPH_ENABLED:=false} +: ${RUN_HELM_TESTS:="yes"} #NOTE: Get the overrides to use for placement, should placement be deployed. case "${OPENSTACK_RELEASE}" in diff --git a/tools/deployment/component/heat/heat.sh b/tools/deployment/component/heat/heat.sh index 9f6f32b325..43a670d305 100755 --- a/tools/deployment/component/heat/heat.sh +++ b/tools/deployment/component/heat/heat.sh @@ -32,5 +32,12 @@ helm upgrade --install heat ./heat \ #NOTE: Validate Deployment info export OS_CLOUD=openstack_helm openstack service list +openstack endpoint list sleep 30 #NOTE(portdirect): Wait for ingress controller to update rules and restart Nginx -openstack orchestration service list + +openstack --os-interface internal orchestration service list + +FEATURE_GATE="tls"; if [[ ${FEATURE_GATES//,/ } =~ (^|[[:space:]])${FEATURE_GATE}($|[[:space:]]) ]]; then + curl --cacert /etc/openstack-helm/certs/ca/ca.pem -L https://heat.openstack.svc.cluster.local + curl --cacert /etc/openstack-helm/certs/ca/ca.pem -L https://heat-api.openstack.svc.cluster.local:8004 +fi diff --git a/tools/deployment/component/horizon/horizon.sh b/tools/deployment/component/horizon/horizon.sh index 7c1a685e5f..b311c3c561 100755 --- a/tools/deployment/component/horizon/horizon.sh +++ b/tools/deployment/component/horizon/horizon.sh @@ -33,3 +33,8 @@ helm upgrade --install horizon ./horizon \ helm status horizon helm test horizon + +FEATURE_GATE="tls"; if [[ ${FEATURE_GATES//,/ } =~ (^|[[:space:]])${FEATURE_GATE}($|[[:space:]]) ]]; then + curl --cacert /etc/openstack-helm/certs/ca/ca.pem -L https://horizon.openstack.svc.cluster.local + curl --cacert /etc/openstack-helm/certs/ca/ca.pem -L https://horizon-int.openstack.svc.cluster.local +fi diff --git a/tools/deployment/component/keystone/keystone.sh b/tools/deployment/component/keystone/keystone.sh index bb9ffc3b38..f32bd815e3 100755 --- a/tools/deployment/component/keystone/keystone.sh +++ b/tools/deployment/component/keystone/keystone.sh @@ -64,3 +64,8 @@ fi # Delete the test pod if it still exists kubectl delete pods -l application=keystone,release_group=keystone,component=test --namespace=openstack --ignore-not-found helm test keystone --timeout 900 + +FEATURE_GATE="tls"; if [[ ${FEATURE_GATES//,/ } =~ (^|[[:space:]])${FEATURE_GATE}($|[[:space:]]) ]]; then + curl --cacert /etc/openstack-helm/certs/ca/ca.pem -L https://keystone.openstack.svc.cluster.local + curl --cacert /etc/openstack-helm/certs/ca/ca.pem -L https://keystone-api.openstack.svc.cluster.local:5000 +fi diff --git a/tools/scripts/tls/cert-manager.sh b/tools/scripts/tls/cert-manager.sh index 5c8c741bc8..42463be12a 100755 --- a/tools/scripts/tls/cert-manager.sh +++ b/tools/scripts/tls/cert-manager.sh @@ -63,6 +63,61 @@ EOF cfssl gencert -initca ca-csr.json | cfssljson -bare ca - check_cert ca.pem ca-key.pem + +cat > cfssl.json < intermediate-ca.json <