Skip to content

Commit 7693ea3

Browse files
committed
Document DNSZone and enable Designate in E2E
Add the DNSZone user guide and regenerated CRD reference documentation. Enable Designate services in the E2E workflow so DNSZone KUTTL suites can run in CI.
1 parent 4990ba0 commit 7693ea3

4 files changed

Lines changed: 287 additions & 1 deletion

File tree

.github/workflows/e2e.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,18 @@ jobs:
4242
conf_overrides: |
4343
enable_plugin neutron https://github.com/openstack/neutron ${{ matrix.openstack_version }}
4444
enable_plugin manila https://github.com/openstack/manila ${{ matrix.openstack_version }}
45+
enable_plugin designate https://github.com/openstack/designate ${{ matrix.openstack_version }}
4546
4647
[[post-config|/etc/nova/nova.conf]]
4748
[filter_scheduler]
4849
enabled_filters = ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter,SameHostFilter,DifferentHostFilter,SimpleCIDRAffinityFilter,JsonFilter
4950
51+
- name: Verify Designate CLI
52+
run: |
53+
openstack zone list
54+
env:
55+
OS_CLOUD: devstack
56+
5057
- name: Deploy a Kind Cluster
5158
uses: helm/kind-action@ef37e7f390d99f746eb8b610417061a60e82a6cc # tag=v1.14.0
5259
with:

website/docs/crd-reference.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,11 @@ _Appears in:_
585585
| Field | Description | Default | Validation |
586586
| --- | --- | --- | --- |
587587
| `name` _[OpenStackName](#openstackname)_ | name of the existing resource | | MaxLength: 255 <br />MinLength: 1 <br />Pattern: `^[^,]+$` <br />Optional: \{\} <br /> |
588+
| `email` _string_ | email of the existing resource | | Format: email <br />MaxLength: 255 <br />Optional: \{\} <br /> |
588589
| `description` _string_ | description of the existing resource | | MaxLength: 255 <br />MinLength: 1 <br />Optional: \{\} <br /> |
590+
| `ttl` _integer_ | ttl of the existing resource | | Maximum: 2.147483647e+09 <br />Minimum: 1 <br />Optional: \{\} <br /> |
591+
| `type` _[DNSZoneType](#dnszonetype)_ | type of the existing resource | | Enum: [PRIMARY SECONDARY] <br />Optional: \{\} <br /> |
592+
| `masters` _string array_ | masters of the existing resource | | MaxItems: 32 <br />items:MaxLength: 255 <br />Optional: \{\} <br /> |
589593

590594

591595
#### DNSZoneImport
@@ -622,7 +626,11 @@ _Appears in:_
622626
| Field | Description | Default | Validation |
623627
| --- | --- | --- | --- |
624628
| `name` _[OpenStackName](#openstackname)_ | name will be the name of the created resource. If not specified, the<br />name of the ORC object will be used. | | MaxLength: 255 <br />MinLength: 1 <br />Pattern: `^[^,]+$` <br />Optional: \{\} <br /> |
629+
| `email` _string_ | email is the email address of the administrator for the zone. | | Format: email <br />MaxLength: 255 <br />Optional: \{\} <br /> |
625630
| `description` _string_ | description is a human-readable description for the resource. | | MaxLength: 255 <br />MinLength: 1 <br />Optional: \{\} <br /> |
631+
| `ttl` _integer_ | ttl is the Time To Live for the zone in seconds. | | Maximum: 2.147483647e+09 <br />Minimum: 1 <br />Optional: \{\} <br /> |
632+
| `type` _[DNSZoneType](#dnszonetype)_ | type is the type of the zone. | PRIMARY | Enum: [PRIMARY SECONDARY] <br />Optional: \{\} <br /> |
633+
| `masters` _string array_ | masters specifies zone masters if this is a secondary zone. | | MaxItems: 32 <br />items:MaxLength: 255 <br />Optional: \{\} <br /> |
626634

627635

628636
#### DNSZoneResourceStatus
@@ -639,7 +647,13 @@ _Appears in:_
639647
| Field | Description | Default | Validation |
640648
| --- | --- | --- | --- |
641649
| `name` _string_ | name is a Human-readable name for the resource. Might not be unique. | | MaxLength: 1024 <br />Optional: \{\} <br /> |
650+
| `email` _string_ | email is the email contact of the zone. | | MaxLength: 1024 <br />Optional: \{\} <br /> |
642651
| `description` _string_ | description is a human-readable description for the resource. | | MaxLength: 1024 <br />Optional: \{\} <br /> |
652+
| `ttl` _integer_ | ttl is the Time to Live for the zone in seconds. | | Optional: \{\} <br /> |
653+
| `type` _string_ | type is the type of the zone. | | MaxLength: 255 <br />Optional: \{\} <br /> |
654+
| `masters` _string array_ | masters specifies zone masters if this is a secondary zone. | | MaxItems: 32 <br />items:MaxLength: 255 <br />Optional: \{\} <br /> |
655+
| `transferredAt` _[Time](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#time-v1-meta)_ | transferredAt is the last time an update was retrieved from the master servers. | | Optional: \{\} <br /> |
656+
| `status` _string_ | status is the status of the resource. | | MaxLength: 255 <br />Optional: \{\} <br /> |
643657

644658

645659
#### DNSZoneSpec
@@ -680,6 +694,25 @@ _Appears in:_
680694
| `resource` _[DNSZoneResourceStatus](#dnszoneresourcestatus)_ | resource contains the observed state of the OpenStack resource. | | Optional: \{\} <br /> |
681695

682696

697+
#### DNSZoneType
698+
699+
_Underlying type:_ _string_
700+
701+
702+
703+
_Validation:_
704+
- Enum: [PRIMARY SECONDARY]
705+
706+
_Appears in:_
707+
- [DNSZoneFilter](#dnszonefilter)
708+
- [DNSZoneResourceSpec](#dnszoneresourcespec)
709+
710+
| Field | Description |
711+
| --- | --- |
712+
| `PRIMARY` | |
713+
| `SECONDARY` | |
714+
715+
683716
#### Domain
684717

685718

website/docs/user-guide/dnszone.md

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
# DNS Zones (DNSZone)
2+
3+
The `DNSZone` resource manages DNS zones in OpenStack Designate. It allows you to declaratively create, update, and delete primary and secondary DNS zones, or import existing zones for read-only access.
4+
5+
---
6+
7+
## Core Concepts
8+
9+
In OpenStack Designate, a DNS zone holds DNS records (such as A, AAAA, MX, TXT, etc.). ORC supports both **PRIMARY** and **SECONDARY** zones:
10+
* **PRIMARY** zones are master zones where DNS records are managed directly within OpenStack Designate.
11+
* **SECONDARY** zones are read-only copies of zones that automatically perform zone transfers from external master DNS servers.
12+
13+
### Domain Name Syntax
14+
All DNS zone names in OpenStack Designate and ORC **must end with a trailing period** (e.g., `example.com.`). This is enforced by Kubernetes API validation rules.
15+
16+
---
17+
18+
## Management Policies
19+
20+
Like all ORC resources, `DNSZone` supports two management policies: `managed` and `unmanaged`.
21+
22+
### 1. Managed Zone (Default)
23+
24+
In the `managed` policy, ORC handles the entire lifecycle of the DNS zone in OpenStack Designate.
25+
* **Creation**: ORC creates the zone if it does not exist.
26+
* **Update**: ORC synchronizes specifications (like description, email, TTL, and masters) to Designate. (Note: `name` and `type` are immutable).
27+
* **Deletion**: On deletion of the Kubernetes resource, the corresponding Designate zone is deleted (unless `managedOptions.onDelete` is set to `detach`).
28+
29+
#### Option A: Managed Primary Zone
30+
31+
```yaml
32+
apiVersion: openstack.k-orc.cloud/v1alpha1
33+
kind: DNSZone
34+
metadata:
35+
name: primary-zone
36+
spec:
37+
cloudCredentialsRef:
38+
secretName: openstack-clouds
39+
cloudName: openstack
40+
managementPolicy: managed
41+
resource:
42+
# name specifies the name of the DNS Zone. Must end with a period.
43+
# Defaults to the ORC object name if not specified.
44+
# Immutable after creation.
45+
name: primary.example.com.
46+
47+
# email is the email address of the administrator for the zone.
48+
# Required for PRIMARY zones. Must be omitted for SECONDARY zones.
49+
email: admin@example.com
50+
51+
# description is a human-readable description for the DNS Zone.
52+
description: "Complete managed primary DNS zone example"
53+
54+
# ttl is the Time To Live for the zone in seconds.
55+
ttl: 3600
56+
57+
# type specifies the type of the zone. Can be 'PRIMARY' or 'SECONDARY'.
58+
# Immutable after creation.
59+
type: PRIMARY
60+
```
61+
62+
#### Option B: Managed Secondary Zone
63+
64+
```yaml
65+
apiVersion: openstack.k-orc.cloud/v1alpha1
66+
kind: DNSZone
67+
metadata:
68+
name: secondary-zone
69+
spec:
70+
cloudCredentialsRef:
71+
secretName: openstack-clouds
72+
cloudName: openstack
73+
managementPolicy: managed
74+
resource:
75+
# name specifies the name of the DNS Zone. Must end with a period.
76+
name: secondary.example.com.
77+
78+
# type specifies the type of the zone.
79+
type: SECONDARY
80+
81+
# masters specifies zone masters from which zone transfers are performed.
82+
# Required for SECONDARY zones. Must be omitted for PRIMARY zones.
83+
masters:
84+
- 192.0.2.1
85+
- 192.0.2.2
86+
87+
description: "Complete managed secondary DNS zone example"
88+
ttl: 3600
89+
```
90+
91+
### 2. Unmanaged Import Workflow
92+
93+
In the `unmanaged` policy, ORC imports an existing DNS zone from OpenStack Designate. ORC will **never** modify or delete the OpenStack resource; it is imported for read-only status propagation.
94+
95+
You can import an existing zone using either its **ID (UUID)** or by matching its **properties (filters)**.
96+
97+
#### Option A: Import by ID
98+
Use this option when you know the exact UUID of the existing zone.
99+
100+
```yaml
101+
apiVersion: openstack.k-orc.cloud/v1alpha1
102+
kind: DNSZone
103+
metadata:
104+
name: imported-zone-by-id
105+
spec:
106+
cloudCredentialsRef:
107+
secretName: openstack-clouds
108+
cloudName: openstack
109+
managementPolicy: unmanaged
110+
import:
111+
id: "12345678-1234-1234-1234-1234567890ab"
112+
```
113+
114+
#### Option B: Import by Filter
115+
Use this option when you want to look up an existing zone based on its properties. The filter **must resolve to exactly one resource** in OpenStack Designate, otherwise ORC will enter an error state.
116+
117+
```yaml
118+
apiVersion: openstack.k-orc.cloud/v1alpha1
119+
kind: DNSZone
120+
metadata:
121+
name: imported-zone-by-filter
122+
spec:
123+
cloudCredentialsRef:
124+
secretName: openstack-clouds
125+
cloudName: openstack
126+
managementPolicy: unmanaged
127+
import:
128+
filter:
129+
name: existing-zone.example.com.
130+
email: admin@example.com
131+
ttl: 3600
132+
```
133+
134+
---
135+
136+
## Validation Rules & Immutability
137+
138+
The `DNSZone` Custom Resource Definition (CRD) implements strict validation via Common Expression Language (CEL) and OpenAPI schemas:
139+
140+
* **Name Validation**:
141+
* Must end with a trailing period (`.`).
142+
* Immutable. Once created, you cannot change the zone name in the specification.
143+
* Defaults to the ORC object name (with a trailing period appended by the user) if not explicitly set.
144+
* **Type Validation**:
145+
* Allowed values are `PRIMARY` and `SECONDARY`.
146+
* Immutable. Once created, you cannot change the zone type.
147+
* **Email Validation**:
148+
* Required when `type` is `PRIMARY`.
149+
* Must be omitted (not specified) when `type` is `SECONDARY`.
150+
* Must be a valid email format.
151+
* Maximum length of `255` characters.
152+
* **Masters Validation**:
153+
* Required when `type` is `SECONDARY` (must specify at least one master IP address).
154+
* Must be omitted (not specified) when `type` is `PRIMARY`.
155+
* Maximum of `32` items, each with a maximum length of `255` characters.
156+
* **TTL Validation**:
157+
* Must be an integer between `1` and `2147483647` (inclusive).
158+
* **Description Validation**:
159+
* Length must be between `1` and `255` characters.
160+
161+
---
162+
163+
## Status Conditions
164+
165+
To check the reconciliation and readiness of your `DNSZone`, inspect its status conditions:
166+
167+
```bash
168+
kubectl get dnszone primary-zone -o yaml
169+
```
170+
171+
### 1. `Available` Condition
172+
* `True`: The DNS zone is created and active (`ACTIVE` status in Designate).
173+
* `False`: The DNS zone is not ready for use. Common reasons include:
174+
* `Progressing`: The zone is currently in a `PENDING` state in Designate. ORC is actively polling until it transitions to `ACTIVE`.
175+
* `UnrecoverableError`: The zone is in an `ERROR` state in Designate, or the import configuration points to a non-existent ID or filter.
176+
* `InvalidConfiguration`: The configuration is invalid or there was an authentication/client issue.
177+
178+
### 2. `Progressing` Condition
179+
* `True`: ORC is still performing operations or polling for updates (e.g., waiting for the zone to become `ACTIVE` from a `PENDING` state).
180+
* `False`: ORC has completed reconciliation. The spec matches the observed status or a terminal error has been reached.
181+
182+
---
183+
184+
## Troubleshooting
185+
186+
Here are common issues you might encounter with `DNSZone` resources and how to solve them:
187+
188+
### 1. Validation Failures on Creation
189+
190+
**Symptom:**
191+
When applying the YAML, you get an API rejection error:
192+
```
193+
Error from server (BadRequest): error when creating "dnszone.yaml": DNSZone.openstack.k-orc.cloud "my-zone" is invalid: spec.resource.name: Invalid value: "my-zone": name must end with a period
194+
```
195+
196+
**Solution:**
197+
Ensure that your `spec.resource.name` ends with a period (e.g., `my-zone.example.com.`). If you omit `spec.resource.name`, the controller will default to the Kubernetes object name, but the name must still be valid as a DNS Zone name (ending in a `.`). Therefore, if you omit `spec.resource.name`, the Kubernetes object's name itself is used, but because Kubernetes resource names cannot end with a period, you must explicitly specify `spec.resource.name` with the trailing period.
198+
199+
---
200+
201+
### 2. Zone Creation Hangs or Enters Terminal Error (409 Conflict)
202+
203+
**Symptom:**
204+
The resource reports `Available=False` and `Progressing=False` with a message containing:
205+
```
206+
Conflicting zone already exists in OpenStack Designate
207+
```
208+
209+
**Cause:**
210+
A DNS Zone with the same domain name already exists in the target OpenStack tenant. Designate does not allow duplicate zone names.
211+
212+
**Solution:**
213+
* If you want to take over and manage this existing zone, you should change your `managementPolicy` to `unmanaged` and use the `import` mechanism.
214+
* If you want to create a new managed zone, choose a unique domain name.
215+
216+
---
217+
218+
### 3. Unmanaged Import Fails to Find Zone
219+
220+
**Symptom:**
221+
The imported `DNSZone` is stuck in an error state with the message:
222+
```
223+
referenced resource does not exist in OpenStack
224+
```
225+
226+
**Solution:**
227+
* Verify that the ID in `spec.import.id` is correct and matches an existing zone in Designate.
228+
* If importing by `spec.import.filter`, verify that the filter matches **exactly one** zone. If it matches zero or multiple zones, the import will fail. Use the OpenStack CLI to verify:
229+
```bash
230+
openstack zone list --name existing-zone.example.com.
231+
```
232+
233+
---
234+
235+
### 4. Zone stuck in PENDING status
236+
237+
**Symptom:**
238+
`Available` is `False`, `Progressing` is `True`, and the message is `Waiting for resource to become available in OpenStack`.
239+
240+
**Cause:**
241+
Designate is asynchronously processing the zone creation/update or communicating with backend DNS nameservers.
242+
243+
**Solution:**
244+
This is normal behavior. ORC is actively polling OpenStack. Wait a few moments for Designate to transition the zone status to `ACTIVE`. If it remains in this state for a prolonged period, check the Designate API service status and your OpenStack logs.

website/mkdocs.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ nav:
77
- Getting Started:
88
- Installation: installation.md
99
- Quick Start: getting-started.md
10-
- User Guide: user-guide/index.md
10+
- User Guide:
11+
- Overview: user-guide/index.md
12+
- DNS Zones: user-guide/dnszone.md
1113
- CRD Reference: crd-reference.md
1214
- Troubleshooting: troubleshooting.md
1315
- Contributing:

0 commit comments

Comments
 (0)