feat: Staffeln support (#588)

Co-authored-by: Oleksandr Kozachenko <okozachenko1203@gmail.com>
Co-authored-by: Mohammed Naser <mnaser@vexxhost.com>
diff --git a/roles/cinder/tasks/main.yml b/roles/cinder/tasks/main.yml
index 540f7e5..617c92b 100644
--- a/roles/cinder/tasks/main.yml
+++ b/roles/cinder/tasks/main.yml
@@ -11,6 +11,7 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations
 # under the License.
+#
 
 - name: Uninstall the legacy HelmRelease
   run_once: true
@@ -36,6 +37,15 @@
         name: "{{ cinder_helm_release_name }}"
         namespace: "{{ cinder_helm_release_namespace }}"
 
+- name: Generate Helm values
+  ansible.builtin.set_fact:
+    _cinder_helm_values: "{{ __cinder_helm_values }}"
+
+- name: Append Helm values (Staffeln)
+  when: atmosphere_staffeln_enabled is defined
+  ansible.builtin.set_fact:
+    _neutron_helm_values: "{{ _cinder_helm_values | combine(__cinder_staffeln_helm_values, recursive=True) }}"
+
 - name: Deploy Helm chart
   run_once: true
   kubernetes.core.helm:
diff --git a/roles/cinder/vars/main.yml b/roles/cinder/vars/main.yml
index e84eaf3..f0d1630 100644
--- a/roles/cinder/vars/main.yml
+++ b/roles/cinder/vars/main.yml
@@ -12,7 +12,7 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-_cinder_helm_values:
+__cinder_helm_values:
   endpoints: "{{ openstack_helm_endpoints }}"
   images:
     tags: "{{ atmosphere_images | vexxhost.atmosphere.openstack_helm_image_tags('cinder') }}"
@@ -21,6 +21,7 @@
       api: 3
       scheduler: 3
   conf:
+    policy: "{{ staffeln_backup_delete_policy if atmosphere_staffeln_enabled is defined else {} }}"
     cinder:
       DEFAULT:
         allowed_direct_url_schemes: cinder
@@ -42,6 +43,11 @@
     job_clean: false
     service_ingress_api: false
 
+__cinder_staffeln_helm_values:
+  conf:
+    policy:
+      backup:delete: "rule:admin_api or (project_id:%(project_id)s and http://staffeln-api:8808/v1/backup?backup_id=%(id)s)"
+
 _cinder_ingress_annotations:
   nginx.ingress.kubernetes.io/proxy-body-size: "0"
   nginx.ingress.kubernetes.io/proxy-request-buffering: "off"
diff --git a/roles/defaults/vars/main.yml b/roles/defaults/vars/main.yml
index eb1603e..c650ad0 100644
--- a/roles/defaults/vars/main.yml
+++ b/roles/defaults/vars/main.yml
@@ -186,6 +186,9 @@
   senlin_engine: quay.io/vexxhost/senlin@sha256:5cb3108dfdeb02a8d910aa2666d8865c772774e431ceaf69391959d87e2b0674 # image-source: quay.io/vexxhost/senlin:zed
   senlin_health_manager: quay.io/vexxhost/senlin@sha256:5cb3108dfdeb02a8d910aa2666d8865c772774e431ceaf69391959d87e2b0674 # image-source: quay.io/vexxhost/senlin:zed
   skopeo: quay.io/skopeo/stable:latest
+  staffeln_db_sync: ghcr.io/vexxhost/staffeln:v2.2.3
+  staffeln_conductor: ghcr.io/vexxhost/staffeln:v2.2.3
+  staffeln_api: ghcr.io/vexxhost/staffeln:v2.2.3
   tempest_run_tests: us-docker.pkg.dev/vexxhost-infra/openstack/tempest:30.1.0-4
   vector: docker.io/timberio/vector:0.27.0-debian
 
diff --git a/roles/openstack_helm_endpoints/defaults/main.yml b/roles/openstack_helm_endpoints/defaults/main.yml
index 61399c2..33aec1c 100644
--- a/roles/openstack_helm_endpoints/defaults/main.yml
+++ b/roles/openstack_helm_endpoints/defaults/main.yml
@@ -521,3 +521,9 @@
 openstack_helm_endpoints_manila_mariadb_password: "{{ undef(hint='You must specify a Manila MariaDB password') }}"
 
                                                                    # ]]]
+# .. envvar:: openstack_helm_endpoints_staffeln_mariadb_password [[[
+#
+# Database password for service
+openstack_helm_endpoints_staffeln_mariadb_password: "{{ undef(hint='You must specify a Staffeln MariaDB password') }}"
+
+                                                                   # ]]]
diff --git a/roles/openstack_helm_endpoints/vars/main.yml b/roles/openstack_helm_endpoints/vars/main.yml
index f0fbb6a..f2356cb 100644
--- a/roles/openstack_helm_endpoints/vars/main.yml
+++ b/roles/openstack_helm_endpoints/vars/main.yml
@@ -534,3 +534,9 @@
     port:
       api:
         public: 443
+
+_openstack_helm_endpoints_staffeln:
+  oslo_db:
+    auth:
+      staffeln:
+        password: "{{ openstack_helm_endpoints_staffeln_mariadb_password }}"
diff --git a/roles/staffeln/README.md b/roles/staffeln/README.md
new file mode 100644
index 0000000..c3b2197
--- /dev/null
+++ b/roles/staffeln/README.md
@@ -0,0 +1 @@
+# `staffeln`
diff --git a/roles/staffeln/defaults/main.yaml b/roles/staffeln/defaults/main.yaml
new file mode 100644
index 0000000..62c30f0
--- /dev/null
+++ b/roles/staffeln/defaults/main.yaml
@@ -0,0 +1,22 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# 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.
+
+staffeln_helm_release_name: staffeln
+staffeln_helm_chart_path: "../../charts/staffeln/"
+staffeln_helm_chart_ref: /usr/local/src/staffeln
+
+staffeln_helm_release_namespace: openstack
+staffeln_helm_values: {}
+staffeln_backup_metadata_key: "__staffeln_backup"
+staffeln_retention_metadata_key: "__staffeln_retention"
diff --git a/roles/staffeln/meta/main.yml b/roles/staffeln/meta/main.yml
new file mode 100644
index 0000000..194d383
--- /dev/null
+++ b/roles/staffeln/meta/main.yml
@@ -0,0 +1,35 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# 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.
+
+galaxy_info:
+  author: VEXXHOST, Inc.
+  description: Ansible role for Vexxhost Staffeln
+  license: Apache-2.0
+  min_ansible_version: 5.5.0
+  standalone: false
+  platforms:
+    - name: Ubuntu
+      versions:
+        - focal
+
+dependencies:
+  - role: defaults
+  - role: openstacksdk
+  - role: openstack_helm_endpoints
+    vars:
+      openstack_helm_endpoints_chart: staffeln
+  - role: vexxhost.kubernetes.upload_helm_chart
+    vars:
+      upload_helm_chart_src: "{{ staffeln_helm_chart_path }}"
+      upload_helm_chart_dest: "{{ staffeln_helm_chart_ref }}"
diff --git a/roles/staffeln/tasks/main.yaml b/roles/staffeln/tasks/main.yaml
new file mode 100644
index 0000000..7e055f3
--- /dev/null
+++ b/roles/staffeln/tasks/main.yaml
@@ -0,0 +1,23 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# 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.
+
+- name: Deploy Helm chart
+  run_once: true
+  kubernetes.core.helm:
+    name: "{{ staffeln_helm_release_name }}"
+    chart_ref: "{{ staffeln_helm_chart_ref }}"
+    release_namespace: "{{ staffeln_helm_release_namespace }}"
+    create_namespace: true
+    kubeconfig: /etc/kubernetes/admin.conf
+    values: "{{ _staffeln_helm_values | combine(staffeln_helm_values, recursive=True) }}"
diff --git a/roles/staffeln/vars/main.yml b/roles/staffeln/vars/main.yml
new file mode 100644
index 0000000..5f26973
--- /dev/null
+++ b/roles/staffeln/vars/main.yml
@@ -0,0 +1,30 @@
+# Copyright (c) 2023 VEXXHOST, Inc.
+#
+# 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.
+
+_staffeln_helm_values:
+  endpoints: "{{ openstack_helm_endpoints }}"
+  images:
+    tags: "{{ atmosphere_images | vexxhost.atmosphere.openstack_helm_image_tags('staffeln') }}"
+  pod:
+    replicas:
+      api: 3
+      conductor: 3
+  conf:
+    staffeln:
+      conductor:
+        backup_metadata_key: "{{staffeln_backup_metadata_key}}"
+        retention_metadata_key: "{{staffeln_retention_metadata_key}}"
+  manifests:
+    ingress_api: false
+    service_ingress_api: false