Restructure Designate CI jobs

So far the Designate and Designate tempest plugin CI jobs definition
was different than most other OSP components. Some of the jobs were
defined in the Designate repository and other in the tempest plugin,
without any clear indication to the correct repository for the job type.

By adopting a modular approach similar to other OpenStack projects,
we'll reduce maintenance overhead and allow contributors to focus on
enhancing Designate rather than debugging CI structure issues.

Goals of this restructure process:
  * Create a clear separation of job definitions between designate and
    designate-tempest-plugin repositories
  * Organize configurations into multiple files instead of single,
    monolithic one

Closes-Bug: #2106143
Change-Id: I77a963f733ff6d04a7cead92655304de80205015
Signed-off-by: Omer <oschwart@redhat.com>
diff --git a/.zuul.yaml b/.zuul.yaml
deleted file mode 100644
index eab10ad..0000000
--- a/.zuul.yaml
+++ /dev/null
@@ -1,50 +0,0 @@
-- job:
-    name: designate-bind9-stable-2025-1
-    parent: designate-bind9
-    nodeset: openstack-single-node-noble
-    override-checkout: stable/2025.1
-
-- job:
-    name: designate-bind9-stable-2024-2
-    parent: designate-bind9
-    nodeset: openstack-single-node-jammy
-    override-checkout: stable/2024.2
-
-- job:
-    name: designate-bind9-stable-2024-1
-    parent: designate-bind9
-    nodeset: openstack-single-node-jammy
-    override-checkout: stable/2024.1
-
-- job:
-    name: designate-bind9-multipool
-    parent: designate-base
-    nodeset: openstack-single-node-jammy
-    vars:
-      devstack_localrc:
-        DESIGNATE_BACKEND_DRIVER: multipool-bind9
-      devstack_local_conf:
-        post-config:
-          "$DESIGNATE_CONF":
-            service:central:
-              scheduler_filters: "pool_id_attribute, in_doubt_default_pool"
-        test-config:
-          "$TEMPEST_CONFIG":
-            dns_feature_enabled:
-              test_multipool_with_delete_opt: True
-      tempest_test_regex: ^designate_tempest_plugin.tests.scenario.v2.test_designate_multipool.DesignateMultiPoolTest
-
-- project:
-    templates:
-      - designate-devstack-jobs
-      - check-requirements
-      - publish-openstack-docs-pti
-      - tempest-plugin-jobs
-      - release-notes-jobs-python3
-    check:
-      jobs:
-        - designate-bind9-stable-2025-1
-        - designate-bind9-stable-2024-2
-        - designate-bind9-stable-2024-1
-        - designate-bind9-multipool
-        - neutron-tempest-plugin-designate-scenario
diff --git a/playbooks/designate-bind9/post.yaml b/playbooks/designate-bind9/post.yaml
new file mode 100644
index 0000000..97beb0b
--- /dev/null
+++ b/playbooks/designate-bind9/post.yaml
@@ -0,0 +1,4 @@
+- hosts: all
+  become: True
+  roles:
+    - bind-logs-conf
diff --git a/playbooks/designate-pdns4/post.yaml b/playbooks/designate-pdns4/post.yaml
new file mode 100644
index 0000000..103755c
--- /dev/null
+++ b/playbooks/designate-pdns4/post.yaml
@@ -0,0 +1,4 @@
+- hosts: all
+  become: True
+  roles:
+    - pdns4-logs-conf
diff --git a/roles/bind-logs-conf/defaults/main.yaml b/roles/bind-logs-conf/defaults/main.yaml
new file mode 100644
index 0000000..f8fb8de
--- /dev/null
+++ b/roles/bind-logs-conf/defaults/main.yaml
@@ -0,0 +1 @@
+stage_dir: "{{ ansible_user_dir }}"
diff --git a/roles/bind-logs-conf/tasks/main.yaml b/roles/bind-logs-conf/tasks/main.yaml
new file mode 100644
index 0000000..9fded23
--- /dev/null
+++ b/roles/bind-logs-conf/tasks/main.yaml
@@ -0,0 +1,38 @@
+- name: Ensure target directory exists
+  file:
+    path: "{{ stage_dir }}/etc/bind"
+    state: directory
+
+- name: Find bind config files
+  find:
+    path: /etc/bind
+    file_type: any
+  register: bind_configs
+
+- name: Dereference bind configs
+  stat:
+    path: "{{ item.path }}"
+  with_items: "{{ bind_configs.files }}"
+  register: bind_configs_deref
+
+- name: Link configurations
+  file:
+    src: "{{ item.stat.lnk_source | default(item.stat.path) }}"
+    dest: "{{ stage_dir }}/etc/bind/{{ item.stat.path | basename }}"
+    state: hard
+  with_items: "{{ bind_configs_deref.results }}"
+  when: item.stat.isreg or item.stat.islnk
+
+# NOTE(frickler) Copied from devstack role export-devstack-journal
+- name: Ensure {{ stage_dir }}/logs exists
+  become: true
+  file:
+    path: "{{ stage_dir }}/logs"
+    state: directory
+    owner: "{{ ansible_user }}"
+
+- name: Collect bind journal
+  become: true
+  shell:
+    cmd: |
+      journalctl -o short-precise --unit named > {{ stage_dir }}/logs/bind9.txt
diff --git a/roles/pdns4-logs-conf/defaults/main.yaml b/roles/pdns4-logs-conf/defaults/main.yaml
new file mode 100644
index 0000000..f8fb8de
--- /dev/null
+++ b/roles/pdns4-logs-conf/defaults/main.yaml
@@ -0,0 +1 @@
+stage_dir: "{{ ansible_user_dir }}"
diff --git a/roles/pdns4-logs-conf/tasks/main.yaml b/roles/pdns4-logs-conf/tasks/main.yaml
new file mode 100644
index 0000000..716274d
--- /dev/null
+++ b/roles/pdns4-logs-conf/tasks/main.yaml
@@ -0,0 +1,38 @@
+- name: Ensure target directory exists
+  file:
+    path: "{{ stage_dir }}/etc/powerdns"
+    state: directory
+
+- name: Find pdns config files
+  find:
+    path: /etc/powerdns
+    file_type: any
+  register: pdns_configs
+
+- name: Dereference pdns4 configs
+  stat:
+    path: "{{ item.path }}"
+  with_items: "{{ pdns_configs.files }}"
+  register: pdns_configs_deref
+
+- name: Link configurations
+  file:
+    src: "{{ item.stat.lnk_source | default(item.stat.path) }}"
+    dest: "{{ stage_dir }}/etc/powerdns/{{ item.stat.path | basename }}"
+    state: hard
+  with_items: "{{ pdns_configs_deref.results }}"
+  when: item.stat.isreg or item.stat.islnk
+
+# NOTE(frickler) Copied from devstack role export-devstack-journal
+- name: Ensure {{ stage_dir }}/logs exists
+  become: true
+  file:
+    path: "{{ stage_dir }}/logs"
+    state: directory
+    owner: "{{ ansible_user }}"
+
+- name: Collect pdns journal
+  become: true
+  shell:
+    cmd: |
+      journalctl -o short-precise --unit pdns > {{ stage_dir }}/logs/pdns.txt.gz
diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml
new file mode 100644
index 0000000..0cc2e66
--- /dev/null
+++ b/zuul.d/jobs.yaml
@@ -0,0 +1,144 @@
+- job:
+    name: designate-core
+    parent: devstack-tempest
+    nodeset: openstack-single-node-noble
+    vars: &base_vars
+      devstack_localrc:
+        DESIGNATE_SERVICE_PORT_DNS: 5322
+        TEMPEST_PLUGINS: /opt/stack/designate-tempest-plugin
+        API_WORKERS: 2
+      devstack_plugins:
+        designate: https://opendev.org/openstack/designate
+        designate-tempest-plugin: https://opendev.org/openstack/designate-tempest-plugin.git
+      devstack_services:
+        designate: true
+        s-account: false
+        s-container: false
+        s-object: false
+        s-proxy: false
+        cinder: false
+        c-api: false
+        c-bak: false
+        c-vol: false
+      tox_envlist: all
+      tempest_test_regex: |
+        designate_tempest_plugin.*
+    required-projects: &base_required_projects
+      - openstack/designate
+      - openstack/designate-dashboard
+      - openstack/designate-tempest-plugin
+      - openstack/python-designateclient
+    timeout: 4200
+    irrelevant-files: &base_irrelevant_files
+      - ^.*\.rst$
+      - ^api-ref/.*$
+      - ^doc/.*$
+      - ^releasenotes/.*$
+
+- job:
+    name: designate-bind9-core
+    post-run: playbooks/designate-bind9/post.yaml
+    parent: designate-core
+
+- job:
+    name: designate-bind9-with-keystone-default-roles
+    post-run: playbooks/designate-bind9/post.yaml
+    parent: designate-core
+    nodeset: openstack-single-node-noble
+    vars:
+      devstack_local_conf:
+        post-config:
+          $DESIGNATE_CONF:
+            oslo_policy:
+              enforce_new_defaults: False
+              enforce_scope: False
+        test-config:
+          "$TEMPEST_CONFIG":
+            dns_feature_enabled:
+              enforce_new_defaults: False
+            enforce_scope:
+              designate: False
+
+- job:
+    name: designate-bind9-core-catalog-zones
+    parent: designate-bind9-core
+    vars:
+      devstack_localrc:
+        DESIGNATE_USE_CATALOG_ZONES: true
+
+- job:
+    name: designate-pdns4-core
+    post-run: playbooks/designate-pdns4/post.yaml
+    parent: designate-core
+    vars:
+      devstack_localrc:
+        DESIGNATE_BACKEND_DRIVER: pdns4
+
+- job:
+    name: designate-pdns4-postgres-core
+    parent: designate-pdns4-core
+    vars:
+      devstack_services:
+        mysql: False
+        postgresql: True
+    voting: false
+
+- job:
+    name: designate-bind9-stable-2024-1
+    parent: designate-bind9-core
+    nodeset: openstack-single-node-jammy
+    override-checkout: stable/2024.1
+
+- job:
+    name: designate-bind9-stable-2024-2
+    parent: designate-bind9-core
+    nodeset: openstack-single-node-jammy
+    override-checkout: stable/2024.2
+
+- job:
+    name: designate-bind9-stable-2025-1
+    parent: designate-bind9-core
+    nodeset: openstack-single-node-noble
+    override-checkout: stable/2025.1
+
+- job:
+    name: designate-bind9-multipool
+    parent: designate-core
+    nodeset: openstack-single-node-noble
+    vars:
+      devstack_localrc:
+        DESIGNATE_BACKEND_DRIVER: multipool-bind9
+      devstack_local_conf:
+        post-config:
+          "$DESIGNATE_CONF":
+            service:central:
+              scheduler_filters: "pool_id_attribute, in_doubt_default_pool"
+        test-config:
+          "$TEMPEST_CONFIG":
+            dns_feature_enabled:
+              test_multipool_with_delete_opt: True
+      tempest_test_regex: ^designate_tempest_plugin.tests.scenario.v2.test_designate_multipool.DesignateMultiPoolTest
+
+# IPv6
+- job:
+    name: designate-core-only-ipv6
+    parent: devstack-tempest-ipv6
+    nodeset: openstack-single-node-noble
+    description: |
+      Designate devstack-tempest base job for IPv6-only deployment
+    irrelevant-files: *base_irrelevant_files
+    required-projects: *base_required_projects
+    vars: *base_vars
+
+- job:
+    name: designate-only-ipv6-bind9
+    post-run: playbooks/designate-bind9/post.yaml
+    parent: designate-core-only-ipv6
+
+- job:
+    name: designate-only-ipv6-pdns4
+    post-run: playbooks/designate-pdns4/post.yaml
+    parent: designate-core-only-ipv6
+    vars:
+      devstack_localrc:
+        DESIGNATE_BACKEND_DRIVER: pdns4
diff --git a/zuul.d/projects.yaml b/zuul.d/projects.yaml
new file mode 100644
index 0000000..e91538b
--- /dev/null
+++ b/zuul.d/projects.yaml
@@ -0,0 +1,36 @@
+- project:
+    templates:
+      - designate-devstack-jobs
+      - check-requirements
+      - publish-openstack-docs-pti
+      - tempest-plugin-jobs
+      - release-notes-jobs-python3
+    check:
+      jobs:
+        - designate-bind9-core
+        - designate-bind9-with-keystone-default-roles
+        - designate-pdns4-core
+        - designate-bind9-stable-2025-1
+        - designate-bind9-stable-2024-2
+        - designate-bind9-stable-2024-1
+        - designate-bind9-multipool
+        - neutron-tempest-plugin-designate-scenario
+        - designate-only-ipv6-pdns4
+        - designate-only-ipv6-bind9
+    queue: designate
+    gate:
+      fail-fast: true
+      jobs:
+        - designate-bind9-core
+        - designate-bind9-with-keystone-default-roles
+        - designate-pdns4-core
+        - designate-bind9-stable-2025-1
+        - designate-bind9-stable-2024-2
+        - designate-bind9-stable-2024-1
+        - designate-bind9-multipool
+        - neutron-tempest-plugin-designate-scenario
+        - designate-only-ipv6-pdns4
+        - designate-only-ipv6-bind9
+    experimental:
+      jobs:
+        - designate-pdns4-postgres-core