|
| 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. |
0 commit comments