diff --git a/doc/source/chart/openstack_charts.rst b/doc/source/chart/openstack_charts.rst index 2526699e11..35c4d12d11 100644 --- a/doc/source/chart/openstack_charts.rst +++ b/doc/source/chart/openstack_charts.rst @@ -12,6 +12,7 @@ OpenStack charts options cyborg cloudkitty designate + freezer glance heat horizon diff --git a/doc/source/install/openstack.rst b/doc/source/install/openstack.rst index 2c6e43b187..da50a3bdc1 100644 --- a/doc/source/install/openstack.rst +++ b/doc/source/install/openstack.rst @@ -476,3 +476,23 @@ To deploy the Blazar service run the following: $(helm osh get-values-overrides -p ${OVERRIDES_DIR} -c blazar ${FEATURES}) helm osh wait-for-pods openstack + +Freezer +~~~~~~~ + +Freezer is a disaster recovery and backup-as-a-service component for OpenStack. +It provides a way to back up various resources, such as virtual machine instances, +databases, and file systems. + +It allows users to schedule backups, restore data, and manage the lifecycle of their +backups to ensure data protection and business continuity within an OpenStack cloud. + +To deploy the OpenStack Freezer, use the following: + +.. code-block:: bash + + helm upgrade --install freezer openstack-helm/freezer \ + --namespace=openstack \ + $(helm osh get-values-overrides -p ${OVERRIDES_DIR} -c freezer ${FEATURES}) + + helm osh wait-for-pods openstack diff --git a/freezer/Chart.yaml b/freezer/Chart.yaml new file mode 100644 index 0000000000..14d0dc6753 --- /dev/null +++ b/freezer/Chart.yaml @@ -0,0 +1,39 @@ +# 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. + +--- +apiVersion: v2 +name: freezer +description: OpenStack Freezer backup and disaster recovery service +type: application +version: 0.1.0 +appVersion: "2025.1" +home: https://docs.openstack.org/freezer/latest +icon: https://opendev.org/openstack/freezer/src/branch/master/freezer_logo.jpg +sources: + - https://opendev.org/openstack/freezer + - https://opendev.org/openstack/freezer-api +keywords: + - openstack + - backup + - restore + - helm +maintainers: + - name: OpenStack Helm Team + email: openstack-helm@lists.openstack.org +annotations: + "helm.sh/hook-weight": "-5" +dependencies: + - name: helm-toolkit + repository: file://../helm-toolkit + version: ">= 0.1.0" +... diff --git a/freezer/templates/bin/_bootstrap.sh.tpl b/freezer/templates/bin/_bootstrap.sh.tpl new file mode 100644 index 0000000000..c325824d8c --- /dev/null +++ b/freezer/templates/bin/_bootstrap.sh.tpl @@ -0,0 +1,19 @@ +#!/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 + +{{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} diff --git a/freezer/templates/bin/_db-sync.sh.tpl b/freezer/templates/bin/_db-sync.sh.tpl new file mode 100644 index 0000000000..e8adbe51b3 --- /dev/null +++ b/freezer/templates/bin/_db-sync.sh.tpl @@ -0,0 +1,19 @@ +#!/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 + +freezer-manage --config-file /etc/freezer/freezer.conf db sync diff --git a/freezer/templates/bin/_freezer-api.sh.tpl b/freezer/templates/bin/_freezer-api.sh.tpl new file mode 100644 index 0000000000..b996ba734c --- /dev/null +++ b/freezer/templates/bin/_freezer-api.sh.tpl @@ -0,0 +1,27 @@ +#!/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 freezer-api --config-file /etc/freezer/freezer.conf +} +function stop () { + kill -TERM 1 +} +$COMMAND diff --git a/freezer/templates/configmap-bin.yaml b/freezer/templates/configmap-bin.yaml new file mode 100644 index 0000000000..6a6f6dcce0 --- /dev/null +++ b/freezer/templates/configmap-bin.yaml @@ -0,0 +1,45 @@ +{{/* +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.configmap_bin }} +{{- $envAll := . }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: freezer-bin +data: +{{- if .Values.images.local_registry.active }} + image-repo-sync.sh: | +{{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} +{{- end }} +{{- if .Values.bootstrap.enabled }} + bootstrap.sh: | +{{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} +{{- end }} + db-init.py: | +{{- include "helm-toolkit.scripts.db_init" . | indent 4 }} + db-sync.sh: | +{{ tuple "bin/_db-sync.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + db-drop.py: | +{{- include "helm-toolkit.scripts.db_drop" . | indent 4 }} + freezer-api.sh: | +{{ tuple "bin/_freezer-api.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + ks-service.sh: | +{{- include "helm-toolkit.scripts.keystone_service" . | indent 4 }} + ks-endpoints.sh: | +{{- include "helm-toolkit.scripts.keystone_endpoints" . | indent 4 }} + ks-user.sh: | +{{- include "helm-toolkit.scripts.keystone_user" . | indent 4 }} +{{- end }} diff --git a/freezer/templates/configmap-etc.yaml b/freezer/templates/configmap-etc.yaml new file mode 100644 index 0000000000..c9f1ae2361 --- /dev/null +++ b/freezer/templates/configmap-etc.yaml @@ -0,0 +1,72 @@ +{{/* +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.configmap_etc }} +{{- $envAll := . }} + +{{- if empty .Values.conf.freezer.keystone_authtoken.auth_uri -}} +{{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.freezer.keystone_authtoken "auth_uri" -}} +{{- end -}} +{{- if empty .Values.conf.freezer.keystone_authtoken.auth_url -}} +{{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup" | set .Values.conf.freezer.keystone_authtoken "auth_url" -}} +{{- end -}} + +{{- if empty .Values.conf.freezer.keystone_authtoken.region_name -}} +{{- $_ := set .Values.conf.freezer.keystone_authtoken "region_name" .Values.endpoints.identity.auth.freezer.region_name -}} +{{- end -}} +{{- if empty .Values.conf.freezer.keystone_authtoken.project_name -}} +{{- $_ := set .Values.conf.freezer.keystone_authtoken "project_name" .Values.endpoints.identity.auth.freezer.project_name -}} +{{- end -}} +{{- if empty .Values.conf.freezer.keystone_authtoken.project_domain_name -}} +{{- $_ := set .Values.conf.freezer.keystone_authtoken "project_domain_name" .Values.endpoints.identity.auth.freezer.project_domain_name -}} +{{- end -}} +{{- if empty .Values.conf.freezer.keystone_authtoken.user_domain_name -}} +{{- $_ := set .Values.conf.freezer.keystone_authtoken "user_domain_name" .Values.endpoints.identity.auth.freezer.user_domain_name -}} +{{- end -}} +{{- if empty .Values.conf.freezer.keystone_authtoken.username -}} +{{- $_ := set .Values.conf.freezer.keystone_authtoken "username" .Values.endpoints.identity.auth.freezer.username -}} +{{- end -}} +{{- if empty .Values.conf.freezer.keystone_authtoken.password -}} +{{- $_ := set .Values.conf.freezer.keystone_authtoken "password" .Values.endpoints.identity.auth.freezer.password -}} +{{- end -}} + +{{- if empty .Values.conf.freezer.database.connection -}} +{{- $_ := tuple "oslo_db" "internal" "freezer" "mysql" . | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" | set .Values.conf.freezer.database "connection" -}} +{{- end -}} + +{{- if and (empty .Values.conf.logging.handler_fluent) (has "fluent" .Values.conf.logging.handlers.keys) -}} +{{- $fluentd_host := tuple "fluentd" "internal" $envAll | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} +{{- $fluentd_port := tuple "fluentd" "internal" "service" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} +{{- $fluent_args := printf "('%s.%s', '%s', %s)" .Release.Namespace .Release.Name $fluentd_host $fluentd_port }} +{{- $handler_fluent := dict "class" "fluent.handler.FluentHandler" "formatter" "fluent" "args" $fluent_args -}} +{{- $_ := set .Values.conf.logging "handler_fluent" $handler_fluent -}} +{{- end -}} + +{{- if and (empty .Values.conf.logging.formatter_fluent) (has "fluent" .Values.conf.logging.formatters.keys) -}} +{{- $formatter_fluent := dict "class" "oslo_log.formatters.FluentFormatter" -}} +{{- $_ := set .Values.conf.logging "formatter_fluent" $formatter_fluent -}} +{{- end -}} +--- +apiVersion: v1 +kind: Secret +metadata: + name: freezer-etc +type: Opaque +data: + freezer.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.freezer | b64enc }} + api-paste.ini: {{ include "helm-toolkit.utils.to_ini" .Values.conf.paste | b64enc }} + policy.yaml: {{ toYaml .Values.conf.policy | b64enc }} + logging.conf: {{ include "helm-toolkit.utils.to_oslo_conf" .Values.conf.logging | b64enc }} +{{- end }} +... diff --git a/freezer/templates/deployment-api.yaml b/freezer/templates/deployment-api.yaml new file mode 100644 index 0000000000..2af217883d --- /dev/null +++ b/freezer/templates/deployment-api.yaml @@ -0,0 +1,130 @@ +{{/* +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. +*/}} +{{- define "probeTemplate" }} +{{- $health_path := tuple "backup" "healthcheck" "internal" . | include "helm-toolkit.endpoints.keystone_endpoint_path_lookup" }} +httpGet: + scheme: {{ tuple "backup" "service" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_scheme_lookup" | upper }} + path: {{ $health_path }} + port: {{ tuple "backup" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} +{{- end }} +{{- if .Values.manifests.deployment_api }} +{{- $envAll := . }} + +{{- $mounts_freezer_api := .Values.pod.mounts.freezer_api.freezer_api }} +{{- $mounts_freezer_api_init := .Values.pod.mounts.freezer_api.init_container }} + +{{- $serviceAccountName := "freezer-api" }} +{{ tuple $envAll "api" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: freezer-api + annotations: + {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }} + labels: +{{ tuple $envAll "freezer" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} +spec: + replicas: {{ .Values.pod.replicas.api }} + selector: + matchLabels: +{{ tuple $envAll "freezer" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} +{{ tuple $envAll | include "helm-toolkit.snippets.kubernetes_upgrades_deployment" | indent 2 }} + template: + metadata: + labels: +{{ tuple $envAll "freezer" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} + annotations: +{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }} + configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }} + configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }} +{{ tuple "freezer_api" . | include "helm-toolkit.snippets.custom_pod_annotations" | indent 8 }} +{{ dict "envAll" $envAll "podName" "freezer-api" "containerNames" (list "init" "freezer-api") | include "helm-toolkit.snippets.kubernetes_mandatory_access_control_annotation" | indent 8 }} + spec: +{{ dict "envAll" $envAll "application" "freezer" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }} +{{ tuple "freezer_api" . | include "helm-toolkit.snippets.kubernetes_pod_priority_class" | indent 6 }} +{{ tuple "freezer_api" . | include "helm-toolkit.snippets.kubernetes_pod_runtime_class" | indent 6 }} + serviceAccountName: {{ $serviceAccountName }} + affinity: +{{ tuple $envAll "freezer" "api" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} + nodeSelector: + {{ .Values.labels.api.node_selector_key }}: {{ .Values.labels.api.node_selector_value }} +{{ if $envAll.Values.pod.tolerations.freezer.enabled }} +{{ tuple $envAll "freezer" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }} +{{ end }} + terminationGracePeriodSeconds: {{ .Values.pod.lifecycle.termination_grace_period.api.timeout | default "30" }} + initContainers: +{{ tuple $envAll "api" $mounts_freezer_api_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} + containers: + - name: freezer-api +{{ tuple $envAll "freezer_api" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} +{{ dict "envAll" $envAll "application" "freezer" "container" "freezer_api" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }} +{{ dict "envAll" $envAll "component" "api" "container" "freezer_api" "type" "readiness" "probeTemplate" (include "probeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} +{{ dict "envAll" $envAll "component" "api" "container" "freezer_api" "type" "liveness" "probeTemplate" (include "probeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }} + command: + - /tmp/freezer-api.sh + - start + env: +{{- if or .Values.manifests.certificates .Values.tls.identity }} + - name: REQUESTS_CA_BUNDLE + value: "/etc/freezer/certs/ca.crt" +{{- end }} + lifecycle: + preStop: + exec: + command: + - /tmp/freezer-api.sh + - stop + ports: + - name: freezer-api + containerPort: {{ tuple "backup" "internal" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + volumeMounts: + - name: freezer-bin + mountPath: /tmp/freezer-api.sh + subPath: freezer-api.sh + readOnly: true + - name: freezer-etc + mountPath: /etc/freezer/freezer.conf + subPath: freezer.conf + readOnly: true + - name: freezer-etc + mountPath: /etc/freezer/api-paste.ini + subPath: api-paste.ini + readOnly: true + - name: freezer-etc + mountPath: /etc/freezer/logging.conf + subPath: logging.conf + readOnly: true + - name: freezer-etc + mountPath: /etc/freezer/policy.yaml + subPath: policy.yaml + readOnly: true +{{ if $mounts_freezer_api.volumeMounts }}{{ toYaml $mounts_freezer_api.volumeMounts | indent 12 }}{{ end }} +{{- dict "enabled" .Values.tls.oslo_db "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal "path" "/etc/mysql/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} +{{- dict "enabled" .Values.tls.identity "name" .Values.secrets.tls.backup.api.internal "path" "/etc/freezer/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }} + volumes: + - name: freezer-bin + configMap: + name: freezer-bin + defaultMode: 0555 + - name: freezer-etc + secret: + secretName: freezer-etc + defaultMode: 0444 +{{- dict "enabled" .Values.tls.oslo_db "name" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} +{{- dict "enabled" .Values.tls.identity "name" .Values.secrets.tls.backup.api.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }} +{{ if $mounts_freezer_api.volumes }}{{ toYaml $mounts_freezer_api.volumes | indent 8 }} +{{ end }} +{{- end }} diff --git a/freezer/templates/ingress-api.yaml b/freezer/templates/ingress-api.yaml new file mode 100644 index 0000000000..54f9d047e9 --- /dev/null +++ b/freezer/templates/ingress-api.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 and .Values.manifests.ingress_api .Values.network.api.ingress.public }} +{{- $ingressOpts := dict "envAll" . "backendServiceType" "backup" "backendPort" "f-api" -}} +{{ $ingressOpts | include "helm-toolkit.manifests.ingress" }} +{{- end }} diff --git a/freezer/templates/job-bootstrap.yaml b/freezer/templates/job-bootstrap.yaml new file mode 100644 index 0000000000..c1fdde076b --- /dev/null +++ b/freezer/templates/job-bootstrap.yaml @@ -0,0 +1,21 @@ +{{/* +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 and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} +{{- $bootstrapJob := dict "envAll" . "serviceName" "freezer" "keystoneUser" .Values.bootstrap.ks_user -}} +{{- if .Values.pod.tolerations.freezer.enabled -}} +{{- $_ := set $bootstrapJob "tolerationsEnabled" true -}} +{{- end -}} +{{ $bootstrapJob | include "helm-toolkit.manifests.job_bootstrap" }} +{{- end }} diff --git a/freezer/templates/job-db-drop.yaml b/freezer/templates/job-db-drop.yaml new file mode 100644 index 0000000000..f4e73454ad --- /dev/null +++ b/freezer/templates/job-db-drop.yaml @@ -0,0 +1,24 @@ +{{/* +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/}} + +{{- if .Values.manifests.job_db_drop }} +{{- $dbDropJob := dict "envAll" . "serviceName" "freezer" -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $dbDropJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} +{{- end -}} +{{- if .Values.pod.tolerations.freezer.enabled -}} +{{- $_ := set $dbDropJob "tolerationsEnabled" true -}} +{{- end -}} +{{ $dbDropJob | include "helm-toolkit.manifests.job_db_drop_mysql" }} +{{- end }} diff --git a/freezer/templates/job-db-init.yaml b/freezer/templates/job-db-init.yaml new file mode 100644 index 0000000000..26b5067b48 --- /dev/null +++ b/freezer/templates/job-db-init.yaml @@ -0,0 +1,32 @@ +{{/* +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. +*/}} + +{{- define "metadata.annotations.job.db_init" }} +helm.sh/hook: post-install,post-upgrade +helm.sh/hook-weight: "-5" +{{- end }} + +{{- if .Values.manifests.job_db_init }} +{{- $dbInitJob := dict "envAll" . "serviceName" "freezer" -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $dbInitJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} +{{- end -}} +{{- if .Values.helm3_hook }} +{{- $_ := set $dbInitJob "jobAnnotations" (include "metadata.annotations.job.db_init" . | fromYaml) }} +{{- end }} +{{- if .Values.pod.tolerations.freezer.enabled -}} +{{- $_ := set $dbInitJob "tolerationsEnabled" true -}} +{{- end -}} +{{ $dbInitJob | include "helm-toolkit.manifests.job_db_init_mysql" }} +{{- end }} diff --git a/freezer/templates/job-db-sync.yaml b/freezer/templates/job-db-sync.yaml new file mode 100644 index 0000000000..3c061f838c --- /dev/null +++ b/freezer/templates/job-db-sync.yaml @@ -0,0 +1,32 @@ +{{/* +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. +*/}} + +{{- define "metadata.annotations.job.db_sync" }} +helm.sh/hook: post-install,post-upgrade +helm.sh/hook-weight: "-4" +{{- end }} + +{{- if .Values.manifests.job_db_sync }} +{{- $dbSyncJob := dict "envAll" . "serviceName" "freezer" "podVolMounts" .Values.pod.mounts.freezer_db_sync.freezer_db_sync.volumeMounts "podVols" .Values.pod.mounts.freezer_db_sync.freezer_db_sync.volumes -}} +{{- if .Values.manifests.certificates -}} +{{- $_ := set $dbSyncJob "dbAdminTlsSecret" .Values.endpoints.oslo_db.auth.admin.secret.tls.internal -}} +{{- end -}} +{{- if .Values.helm3_hook }} +{{- $_ := set $dbSyncJob "jobAnnotations" (include "metadata.annotations.job.db_sync" . | fromYaml) }} +{{- end }} +{{- if .Values.pod.tolerations.freezer.enabled -}} +{{- $_ := set $dbSyncJob "tolerationsEnabled" true -}} +{{- end -}} +{{ $dbSyncJob | include "helm-toolkit.manifests.job_db_sync" }} +{{- end }} diff --git a/freezer/templates/job-image-repo-sync.yaml b/freezer/templates/job-image-repo-sync.yaml new file mode 100644 index 0000000000..5f9859c3e8 --- /dev/null +++ b/freezer/templates/job-image-repo-sync.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. +*/}} + +{{- define "metadata.annotations.job.repo_sync" }} +{{- if .Values.helm3_hook }} +helm.sh/hook: post-install,post-upgrade +{{- end }} +{{- end }} + +{{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} +{{- $imageRepoSyncJob := dict "envAll" . "serviceName" "freezer" "jobAnnotations" (include "metadata.annotations.job.repo_sync" . | fromYaml) -}} +{{- if .Values.pod.tolerations.freezer.enabled -}} +{{- $_ := set $imageRepoSyncJob "tolerationsEnabled" true -}} +{{- end -}} +{{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} +{{- end }} diff --git a/freezer/templates/job-ks-endpoints.yaml b/freezer/templates/job-ks-endpoints.yaml new file mode 100644 index 0000000000..e58ada40f6 --- /dev/null +++ b/freezer/templates/job-ks-endpoints.yaml @@ -0,0 +1,32 @@ +{{/* +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. +*/}} + +{{- define "metadata.annotations.job.ks_endpoints" }} +helm.sh/hook: post-install,post-upgrade +helm.sh/hook-weight: "-2" +{{- end }} + +{{- if .Values.manifests.job_ks_endpoints }} +{{- $ksEndpointsJob := dict "envAll" . "serviceName" "freezer" "serviceTypes" ( tuple "backup" ) -}} +{{- if or .Values.manifests.certificates .Values.tls.identity -}} +{{- $_ := set $ksEndpointsJob "tlsSecret" .Values.secrets.tls.backup.api.internal -}} +{{- end -}} +{{- if .Values.helm3_hook }} +{{- $_ := set $ksEndpointsJob "jobAnnotations" (include "metadata.annotations.job.ks_endpoints" . | fromYaml) }} +{{- end }} +{{- if .Values.pod.tolerations.freezer.enabled -}} +{{- $_ := set $ksEndpointsJob "tolerationsEnabled" true -}} +{{- end -}} +{{ $ksEndpointsJob | include "helm-toolkit.manifests.job_ks_endpoints" }} +{{- end }} diff --git a/freezer/templates/job-ks-service.yaml b/freezer/templates/job-ks-service.yaml new file mode 100644 index 0000000000..c82215ca93 --- /dev/null +++ b/freezer/templates/job-ks-service.yaml @@ -0,0 +1,32 @@ +{{/* +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. +*/}} + +{{- define "metadata.annotations.job.ks_service" }} +helm.sh/hook: post-install,post-upgrade +helm.sh/hook-weight: "-3" +{{- end }} + +{{- if .Values.manifests.job_ks_service }} +{{- $ksServiceJob := dict "envAll" . "serviceName" "freezer" "serviceTypes" ( tuple "backup" ) -}} +{{- if or .Values.manifests.certificates .Values.tls.identity -}} +{{- $_ := set $ksServiceJob "tlsSecret" .Values.secrets.tls.backup.api.internal -}} +{{- end -}} +{{- if .Values.helm3_hook }} +{{- $_ := set $ksServiceJob "jobAnnotations" (include "metadata.annotations.job.ks_service" . | fromYaml) }} +{{- end }} +{{- if .Values.pod.tolerations.freezer.enabled -}} +{{- $_ := set $ksServiceJob "tolerationsEnabled" true -}} +{{- end -}} +{{ $ksServiceJob | include "helm-toolkit.manifests.job_ks_service" }} +{{- end }} \ No newline at end of file diff --git a/freezer/templates/job-ks-user.yaml b/freezer/templates/job-ks-user.yaml new file mode 100644 index 0000000000..e03c43084e --- /dev/null +++ b/freezer/templates/job-ks-user.yaml @@ -0,0 +1,32 @@ +{{/* +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. +*/}} + +{{- define "metadata.annotations.job.ks_user" }} +helm.sh/hook: post-install,post-upgrade +helm.sh/hook-weight: "-1" +{{- end }} + +{{- if .Values.manifests.job_ks_user }} +{{- $ksUserJob := dict "envAll" . "serviceName" "freezer" -}} +{{- if or .Values.manifests.certificates .Values.tls.identity -}} +{{- $_ := set $ksUserJob "tlsSecret" .Values.secrets.tls.backup.api.internal -}} +{{- end -}} +{{- if .Values.helm3_hook }} +{{- $_ := set $ksUserJob "jobAnnotations" (include "metadata.annotations.job.ks_user" . | fromYaml) -}} +{{- end }} +{{- if .Values.pod.tolerations.freezer.enabled -}} +{{- $_ := set $ksUserJob "tolerationsEnabled" true -}} +{{- end -}} +{{ $ksUserJob | include "helm-toolkit.manifests.job_ks_user" }} +{{- end }} diff --git a/freezer/templates/pdb-api.yaml b/freezer/templates/pdb-api.yaml new file mode 100644 index 0000000000..1ddd8a8320 --- /dev/null +++ b/freezer/templates/pdb-api.yaml @@ -0,0 +1,34 @@ +{{/* +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.pdb_api }} +{{- $envAll := . }} +--- +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: freezer-api + labels: +{{ tuple $envAll "freezer" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} +spec: +{{- if .Values.pod.lifecycle.disruption_budget.api.min_available }} + minAvailable: {{ .Values.pod.lifecycle.disruption_budget.api.min_available }} +{{- else }} + maxUnavailable: {{ .Values.pod.lifecycle.disruption_budget.api.max_unavailable | default 1 }} +{{- end }} + selector: + matchLabels: +{{ tuple $envAll "freezer" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} +{{- end }} +... diff --git a/freezer/templates/secret-db.yaml b/freezer/templates/secret-db.yaml new file mode 100644 index 0000000000..5d82a110e6 --- /dev/null +++ b/freezer/templates/secret-db.yaml @@ -0,0 +1,35 @@ +{{/* +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.secret_db }} +{{- $envAll := . }} +{{- range $key1, $userClass := tuple "admin" "freezer" }} +{{- $secretName := index $envAll.Values.secrets.oslo_db $userClass }} +{{- $connection := tuple "oslo_db" "internal" $userClass "mysql" $envAll | include "helm-toolkit.endpoints.authenticated_endpoint_uri_lookup" }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ $secretName }} + annotations: +{{ tuple "oslo_db" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} +type: Opaque +data: +{{- if $envAll.Values.manifests.certificates }} + DB_CONNECTION: {{ (printf "%s?charset=utf8&ssl_ca=/etc/mysql/certs/ca.crt&ssl_key=/etc/mysql/certs/tls.key&ssl_cert=/etc/mysql/certs/tls.crt&ssl_verify_cert" $connection ) | b64enc -}} +{{- else }} + DB_CONNECTION: {{ $connection | b64enc -}} +{{- end }} +{{- end }} +{{- end }} diff --git a/freezer/templates/secret-keystone.yaml b/freezer/templates/secret-keystone.yaml new file mode 100644 index 0000000000..49f7ba900e --- /dev/null +++ b/freezer/templates/secret-keystone.yaml @@ -0,0 +1,30 @@ +{{/* +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.secret_keystone }} +{{- $envAll := . }} +{{- range $key1, $userClass := tuple "admin" "freezer" }} +{{- $secretName := index $envAll.Values.secrets.identity $userClass }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ $secretName }} + annotations: +{{ tuple "identity" $userClass $envAll | include "helm-toolkit.snippets.custom_secret_annotations" | indent 4 }} +type: Opaque +data: +{{- tuple $userClass "internal" $envAll | include "helm-toolkit.snippets.keystone_secret_openrc" | indent 2 -}} +{{- end }} +{{- end }} diff --git a/freezer/templates/service-api.yaml b/freezer/templates/service-api.yaml new file mode 100644 index 0000000000..916818b2f5 --- /dev/null +++ b/freezer/templates/service-api.yaml @@ -0,0 +1,37 @@ +{{/* +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.service_api }} +{{- $envAll := . }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ tuple "backup" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} +spec: + ports: + - name: f-api + port: {{ tuple "backup" "service" "api" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + {{ if .Values.network.api.node_port.enabled }} + nodePort: {{ .Values.network.api.node_port.port }} + {{ end }} + selector: +{{ tuple $envAll "freezer" "api" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} + {{ if .Values.network.api.node_port.enabled }} + type: NodePort + {{ if .Values.network.api.external_policy_local }} + externalTrafficPolicy: Local + {{ end }} + {{ end }} +{{- end }} diff --git a/freezer/templates/service-ingress-api.yaml b/freezer/templates/service-ingress-api.yaml new file mode 100644 index 0000000000..e41f9887bb --- /dev/null +++ b/freezer/templates/service-ingress-api.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 and .Values.manifests.service_ingress_api .Values.network.api.ingress.public }} +{{- $serviceIngressOpts := dict "envAll" . "backendServiceType" "backup" -}} +{{ $serviceIngressOpts | include "helm-toolkit.manifests.service_ingress" }} +{{- end }} diff --git a/freezer/values.yaml b/freezer/values.yaml new file mode 100644 index 0000000000..fffea63fb9 --- /dev/null +++ b/freezer/values.yaml @@ -0,0 +1,523 @@ +# 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. + +--- +release_uuid: null + +labels: + api: + node_selector_key: openstack-control-plane + node_selector_value: enabled + job: + node_selector_key: openstack-control-plane + node_selector_value: enabled + +images: + pull_policy: IfNotPresent + tags: + test: docker.io/xrally/xrally-openstack:2.0.0 + bootstrap: quay.io/airshipit/heat:2025.1-ubuntu_jammy + db_init: quay.io/airshipit/heat:2025.1-ubuntu_jammy + db_drop: quay.io/airshipit/heat:2025.1-ubuntu_jammy + ks_user: quay.io/airshipit/heat:2025.1-ubuntu_jammy + ks_service: quay.io/airshipit/heat:2025.1-ubuntu_jammy + ks_endpoints: quay.io/airshipit/heat:2025.1-ubuntu_jammy + freezer_db_sync: quay.io/airshipit/freezer-api:2025.1-ubuntu_jammy + freezer_api: quay.io/airshipit/freezer-api:2025.1-ubuntu_jammy + dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_jammy + image_repo_sync: docker.io/docker:17.07.0 + local_registry: + active: false + exclude: + - dep_check + - image_repo_sync + +endpoints: + cluster_domain_suffix: cluster.local + local_image_registry: + name: docker-registry + namespace: docker-registry + hosts: + default: localhost + internal: docker-registry + node: localhost + host_fqdn_override: + default: null + port: + registry: + node: 5000 + identity: + name: keystone + auth: + admin: + region_name: RegionOne + username: admin + password: password + project_name: admin + user_domain_name: default + project_domain_name: default + interface: internal + freezer: + role: admin,service + region_name: RegionOne + username: freezer + password: password + project_name: service + user_domain_name: service + project_domain_name: service + hosts: + default: keystone + internal: keystone-api + host_fqdn_override: + default: null + path: + default: /v3 + scheme: + default: http + port: + api: + default: 80 + internal: 5000 + backup: + name: freezer + hosts: + default: freezer-api + internal: freezer-api + public: freezer + host_fqdn_override: + default: null + path: + default: / + healthcheck: /healthcheck + scheme: + default: http + port: + api: + default: 9090 + public: 80 + oslo_db: + auth: + admin: + username: root + password: password + secret: + tls: + internal: mariadb-tls-direct + secretNamespace: openstack + freezer: + username: freezer + password: password + secret: freezer-db-password + secretNamespace: openstack + hosts: + default: mariadb + host_fqdn_override: + default: null + path: /freezer + scheme: mysql+pymysql + port: + mysql: + default: 3306 + oslo_cache: + auth: + # NOTE(portdirect): this is used to define the value for keystone + # authtoken cache encryption key, will be set to a random value + # if not specified. + memcache_secret_key: null + hosts: + default: memcached + host_fqdn_override: + default: null + port: + memcache: + default: 11211 + +secrets: + identity: + admin: freezer-keystone-admin + freezer: freezer-keystone-user + oslo_db: + admin: freezer-db-admin + freezer: freezer-db-user + tls: + backup: + api: + public: freezer-tls-public + internal: freezer-tls-internal + nginx: freezer-tls-nginx + nginx_cluster: freezer-tls-nginx-cluster + +bootstrap: + enabled: false + ks_user: freezer + script: "" + +network: + api: + ingress: + public: true + classes: + namespace: "nginx" + cluster: "nginx-cluster" + annotations: + nginx.ingress.kubernetes.io/rewrite-target: / + external_policy_local: false + node_port: + enabled: false + port: 30090 + +dependencies: + dynamic: + common: + local_image_registry: + jobs: + - freezer-image-repo-sync + services: + - endpoint: node + service: local_image_registry + static: + api: + jobs: + - freezer-db-sync + - freezer-ks-user + - freezer-ks-endpoints + services: + - endpoint: internal + service: oslo_db + - endpoint: internal + service: identity + bootstrap: + services: + - endpoint: internal + service: identity + - endpoint: internal + service: backup + db_init: + services: + - endpoint: internal + service: oslo_db + db_sync: + jobs: + - freezer-db-init + services: + - endpoint: internal + service: oslo_db + db_drop: + services: + - endpoint: internal + service: oslo_db + ks_user: + services: + - endpoint: internal + service: identity + ks_service: + services: + - endpoint: internal + service: identity + ks_endpoints: + jobs: + - freezer-ks-service + services: + - endpoint: internal + service: identity + +pod: + probes: + rpc_timeout: 60 + rpc_retries: 2 + api: + freezer_api: + liveness: + enabled: True + params: + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 5 + readiness: + enabled: True + params: + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 5 + security_context: + freezer: + pod: + runAsUser: 42424 + container: + freezer_api: + runAsUser: 0 + affinity: + anti: + type: + default: preferredDuringSchedulingIgnoredDuringExecution + topologyKey: + default: kubernetes.io/hostname + weight: + default: 10 + tolerations: + freezer: + enabled: false + tolerations: + - key: node-role.kubernetes.io/master + operator: Exists + effect: NoSchedule + - key: node-role.kubernetes.io/control-plane + operator: Exists + effect: NoSchedule + disruption_budget: + api: + min_available: 0 + replicas: + api: 1 + lifecycle: + upgrades: + deployments: + revision_history: 3 + pod_replacement_strategy: RollingUpdate + rolling_update: + max_unavailable: 1 + max_surge: 3 + disruption_budget: + api: + min_available: 0 + max_unavailable: 0 + termination_grace_period: + api: + timeout: 30 + resources: + enabled: false + api: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" + jobs: + bootstrap: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" + db_init: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" + db_sync: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" + db_drop: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" + ks_endpoints: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" + ks_service: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" + ks_user: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" + image_repo_sync: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" + mounts: + freezer_api: + init_container: null + freezer_api: + volumeMounts: + volumes: + freezer_bootstrap: + init_container: null + freezer_bootstrap: + volumeMounts: + volumes: + freezer_db_sync: + init_container: null + freezer_db_sync: + volumeMounts: + volumes: + +conf: + freezer: + DEFAULT: + debug: true + log_config_append: /etc/freezer/logging.conf + bind_host: 0.0.0.0 + bind_port: 9090 + paste_deploy: + config_file: api-paste.ini + database: + max_retries: -1 + oslo_policy: + policy_file: /etc/freezer/policy.yaml + storage: + backend: sqlalchemy + driver: sqlalchemy + keystone_authtoken: + auth_version: v3 + auth_type: password + # region_name: RegionOne + # project_domain_name: service + # project_name: service + # user_domain_name: service + # username: freezer + # password: password + # auth_url: http://keystone-api.openstack.svc.cluster.local:5000/v3 + # auth_uri: http://keystone-api.openstack.svc.cluster.local:5000/v3 + + logging: + loggers: + keys: + - root + - freezer + handlers: + keys: + - stdout + - stderr + - "null" + formatters: + keys: + - context + - default + logger_root: + level: WARNING + handlers: "null" + logger_freezer: + level: INFO + handlers: + - stdout + qualname: freezer + logger_amqp: + level: WARNING + handlers: stderr + qualname: amqp + logger_amqplib: + level: WARNING + handlers: stderr + qualname: amqplib + logger_eventletwsgi: + level: WARNING + handlers: stderr + qualname: eventlet.wsgi.server + logger_sqlalchemy: + level: WARNING + handlers: stderr + qualname: sqlalchemy + logger_boto: + level: WARNING + handlers: stderr + qualname: boto + handler_null: + class: logging.NullHandler + formatter: default + args: () + handler_stdout: + class: StreamHandler + args: (sys.stdout,) + formatter: context + handler_stderr: + class: StreamHandler + args: (sys.stderr,) + formatter: context + formatter_context: + class: oslo_log.formatters.ContextFormatter + datefmt: "%Y-%m-%d %H:%M:%S" + formatter_default: + format: "%(message)s" + datefmt: "%Y-%m-%d %H:%M:%S" + paste: + app:api_versions: + paste.app_factory: freezer_api.api.versions:api_versions + app:appv1: + paste.app_factory: freezer_api.service:freezer_appv1_factory + app:appv2: + paste.app_factory: freezer_api.service:freezer_appv2_factory + filter:authtoken: + paste.filter_factory: keystonemiddleware.auth_token:filter_factory + filter:healthcheck: + paste.filter_factory: oslo_middleware:Healthcheck.factory + backends: disable_by_file + disable_by_file_path: /etc/freezer/healthcheck_disable + filter:context: + paste.filter_factory: freezer_api.api.common.middleware:ContextMiddleware.factory + filter:versionsNegotiator: + paste.filter_factory: freezer_api.api.versions:VersionNegotiator.factory + filter:http_proxy_to_wsgi: + paste.filter_factory: oslo_middleware:HTTPProxyToWSGI.factory + pipeline:main: + pipeline: healthcheck http_proxy_to_wsgi versionsNegotiator authtoken context backupapp + pipeline:unauthenticated_freezer_api: + pipeline: http_proxy_to_wsgi healthcheck freezer_app + composite:backupapp: + paste.composite_factory: freezer_api.service:root_app_factory + /: api_versions + /v1: appv1 + /v2: appv2 + +tls: + identity: false + oslo_db: false + +# NOTE(helm_hook): helm_hook might break for helm2 binary. +# set helm3_hook: false when using the helm2 binary. +helm3_hook: true + +manifests: + certificates: false + configmap_bin: true + configmap_etc: true + deployment_api: true + ingress_api: true + job_bootstrap: true + job_db_init: true + job_db_sync: true + job_db_drop: false + job_image_repo_sync: true + job_ks_endpoints: true + job_ks_service: true + job_ks_user: true + pdb_api: true + secret_db: true + secret_keystone: true + service_api: true + service_ingress_api: true +... diff --git a/releasenotes/config.yaml b/releasenotes/config.yaml index 44aa3c51c6..d7cc3f1efe 100644 --- a/releasenotes/config.yaml +++ b/releasenotes/config.yaml @@ -32,6 +32,7 @@ sections: - [flannel, flannel Chart] - [fluentbit, fluentbit Chart] - [fluentd, fluentd Chart] + - [freezer, freezer Chart] - [glance, glance Chart] - [gnocchi, gnocchi Chart] - [grafana, grafana Chart] diff --git a/releasenotes/notes/freezer-3272cc6ed891f5a3.yaml b/releasenotes/notes/freezer-3272cc6ed891f5a3.yaml new file mode 100644 index 0000000000..d2ae9d9e75 --- /dev/null +++ b/releasenotes/notes/freezer-3272cc6ed891f5a3.yaml @@ -0,0 +1,10 @@ +--- +freezer: > + Added support for Freezer disaster recovery and backup-as-a-service component for OpenStack. It provides a way to back up various resources, such as virtual machine instances, databases, and file systems. It will allow users to schedule backups, restore data, and manage the lifecycle of their backups to ensure data protection and business continuity within an OpenStack cloud. +features: + - | + Introduced Freezer Helm chart with support for: + - Freezer API, Scheduler, Agent service deployment and configuration + - Integration with existing OpenStack identity services + - Support for custom Blazar configuration through values.yaml +... diff --git a/tools/deployment/component/freezer/freezer.sh b/tools/deployment/component/freezer/freezer.sh new file mode 100755 index 0000000000..ec690548cf --- /dev/null +++ b/tools/deployment/component/freezer/freezer.sh @@ -0,0 +1,32 @@ +#!/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 + +#NOTE: Define variables +: ${OSH_HELM_REPO:="../openstack-helm"} +: ${OSH_VALUES_OVERRIDES_PATH:="../openstack-helm/values_overrides"} +: ${OSH_EXTRA_HELM_ARGS_FREEZER:="$(helm osh get-values-overrides ${DOWNLOAD_OVERRIDES:-} -p ${OSH_VALUES_OVERRIDES_PATH} -c freezer ${FEATURES})"} + +#NOTE: Deploy command +helm upgrade --install freezer ${OSH_HELM_REPO}/freezer \ + --namespace openstack \ + --create-namespace \ + --timeout 600s \ + ${OSH_EXTRA_HELM_ARGS:=} \ + ${OSH_EXTRA_HELM_ARGS_FREEZER} + +#NOTE: Wait for deploy +helm osh wait-for-pods openstack + +echo "OpenStack Freezer deployment complete." diff --git a/tools/deployment/component/freezer/freezer_smoke_test.sh b/tools/deployment/component/freezer/freezer_smoke_test.sh new file mode 100755 index 0000000000..45cc76b61f --- /dev/null +++ b/tools/deployment/component/freezer/freezer_smoke_test.sh @@ -0,0 +1,36 @@ +#!/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 + +#NOTE: Install freezer client and check if it works +( + cd ${HOME} + rm -rf freezer + git clone https://opendev.org/openstack/freezer.git -b stable/${OPENSTACK_RELEASE} + cd freezer + sudo pip install -r requirements.txt + sudo python3 setup.py install +) + +unset OS_DOMAIN_NAME +export OS_AUTH_URL=http://keystone.openstack.svc.cluster.local/v3 +export OS_PROJECT_NAME=admin +export OS_USERNAME=admin +export OS_PASSWORD=password +export OS_PROJECT_DOMAIN_NAME=default +export OS_USER_DOMAIN_NAME=default +export OS_IDENTITY_API_VERSION=3 +export OS_AUTH_VERSION=3 + +freezer job-list diff --git a/values_overrides/freezer/2025.1-ubuntu_jammy.yaml b/values_overrides/freezer/2025.1-ubuntu_jammy.yaml new file mode 100644 index 0000000000..0d45ec04c3 --- /dev/null +++ b/values_overrides/freezer/2025.1-ubuntu_jammy.yaml @@ -0,0 +1,12 @@ +--- +images: + tags: + bootstrap: quay.io/airshipit/heat:2025.1-ubuntu_jammy + db_init: quay.io/airshipit/heat:2025.1-ubuntu_jammy + db_drop: quay.io/airshipit/heat:2025.1-ubuntu_jammy + ks_user: quay.io/airshipit/heat:2025.1-ubuntu_jammy + ks_service: quay.io/airshipit/heat:2025.1-ubuntu_jammy + ks_endpoints: quay.io/airshipit/heat:2025.1-ubuntu_jammy + freezer_db_sync: quay.io/airshipit/freezer-api:2025.1-ubuntu_jammy + freezer_api: quay.io/airshipit/freezer-api:2025.1-ubuntu_jammy +... diff --git a/values_overrides/freezer/2025.1-ubuntu_noble.yaml b/values_overrides/freezer/2025.1-ubuntu_noble.yaml new file mode 100644 index 0000000000..19517f002f --- /dev/null +++ b/values_overrides/freezer/2025.1-ubuntu_noble.yaml @@ -0,0 +1,12 @@ +--- +images: + tags: + bootstrap: quay.io/airshipit/heat:2025.1-ubuntu_noble + db_init: quay.io/airshipit/heat:2025.1-ubuntu_noble + db_drop: quay.io/airshipit/heat:2025.1-ubuntu_noble + ks_user: quay.io/airshipit/heat:2025.1-ubuntu_noble + ks_service: quay.io/airshipit/heat:2025.1-ubuntu_noble + ks_endpoints: quay.io/airshipit/heat:2025.1-ubuntu_noble + freezer_db_sync: quay.io/airshipit/freezer-api:2025.1-ubuntu_noble + freezer_api: quay.io/airshipit/freezer-api:2025.1-ubuntu_noble +... diff --git a/zuul.d/2025.1.yaml b/zuul.d/2025.1.yaml index 772be48397..54ac3abcff 100644 --- a/zuul.d/2025.1.yaml +++ b/zuul.d/2025.1.yaml @@ -107,4 +107,15 @@ openstack_release: "2025.1" container_distro_name: ubuntu container_distro_version: jammy + +- job: + name: openstack-helm-freezer-2025-1-ubuntu_jammy + parent: openstack-helm-freezer + nodeset: openstack-helm-3nodes-ubuntu_jammy + timeout: 10800 + vars: + osh_params: + openstack_release: "2025.1" + container_distro_name: ubuntu + container_distro_version: jammy ... diff --git a/zuul.d/base.yaml b/zuul.d/base.yaml index 681c05f342..3c27742694 100644 --- a/zuul.d/base.yaml +++ b/zuul.d/base.yaml @@ -562,6 +562,7 @@ name: openstack-helm-cloudkitty parent: openstack-helm-deploy timeout: 7200 + abstract: true vars: gate_scripts: - ./tools/deployment/common/prepare-bashrc.sh @@ -578,4 +579,22 @@ - ./tools/deployment/component/compute-kit/libvirt.sh - ./tools/deployment/component/compute-kit/compute-kit.sh - ./tools/deployment/component/cloudkitty/cloudkitty.sh + +- job: + name: openstack-helm-freezer + parent: openstack-helm-deploy + timeout: 10800 + abstract: true + vars: + gate_scripts: + - ./tools/deployment/common/prepare-bashrc.sh + - ./tools/deployment/common/prepare-k8s.sh + - ./tools/deployment/common/prepare-charts.sh + - ./tools/deployment/common/setup-client.sh + - export VOLUME_HELM_ARGS="--set volume.enabled=false"; ./tools/deployment/component/common/rabbitmq.sh + - ./tools/deployment/db/mariadb.sh + - ./tools/deployment/component/common/memcached.sh + - ./tools/deployment/component/keystone/keystone.sh + - ./tools/deployment/component/freezer/freezer.sh + - ./tools/deployment/component/freezer/freezer_smoke_test.sh ... diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml index 65e96428bd..7b5c91caf4 100644 --- a/zuul.d/project.yaml +++ b/zuul.d/project.yaml @@ -65,4 +65,5 @@ - openstack-helm-watcher-2025-1-ubuntu_jammy # 3 nodes - openstack-helm-blazar-2025-1-ubuntu_jammy # 3 nodes - openstack-helm-cloudkitty-2025-1-ubuntu_jammy # 3 nodes + - openstack-helm-freezer-2025-1-ubuntu_jammy # 3 nodes ...