Skip to content

Commit 652f3dc

Browse files
committed
ingress: Move zone_id to provider internal
1 parent 8fee5d3 commit 652f3dc

File tree

6 files changed

+167
-117
lines changed

6 files changed

+167
-117
lines changed

custom-domain/dstack-ingress/DNS_PROVIDERS.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ This guide explains how to configure dstack-ingress to work with different DNS p
1919

2020
### Optional Variables
2121

22-
- `DNS_ZONE_ID` - Pre-configured zone ID (auto-detected if not provided)
2322
- `SET_CAA` - Enable CAA record setup (default: false)
2423
- `PORT` - HTTPS port (default: 443)
2524
- `TXT_PREFIX` - Prefix for TXT records (default: "_tapp-address")
@@ -85,7 +84,6 @@ If you're currently using the Cloudflare-only version:
8584
8685
1. **No changes needed for Cloudflare users** - The default behavior remains Cloudflare
8786
2. **For other providers** - Add the `DNS_PROVIDER` environment variable and provider-specific credentials
88-
3. **Zone ID changes** - The variable `CLOUDFLARE_ZONE_ID` is now `DNS_ZONE_ID` (auto-detected if not set)
8987

9088
## Troubleshooting
9189

custom-domain/dstack-ingress/scripts/dns_manager.py

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,25 @@
11
#!/usr/bin/env python3
22

3+
from dns_providers import DNSProviderFactory
34
import argparse
45
import os
56
import sys
67

78
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
89

9-
from dns_providers import DNSProviderFactory
10-
1110

1211
def main():
1312
parser = argparse.ArgumentParser(
1413
description="Manage DNS records across multiple providers"
1514
)
1615
parser.add_argument(
1716
"action",
18-
choices=["get_zone_id", "set_cname", "set_alias", "set_txt", "set_caa"],
17+
choices=["set_cname", "set_alias", "set_txt", "set_caa"],
1918
help="Action to perform",
2019
)
2120
parser.add_argument("--domain", required=True, help="Domain name")
2221
parser.add_argument("--provider", help="DNS provider (cloudflare, linode)")
23-
parser.add_argument("--zone-id", help="Zone ID (if already known)")
22+
# Zone ID is now handled internally by each provider
2423
parser.add_argument(
2524
"--content", help="Record content (target for alias/CNAME, value for TXT/CAA)"
2625
)
@@ -35,51 +34,42 @@ def main():
3534
# Create DNS provider instance
3635
provider = DNSProviderFactory.create_provider(args.provider)
3736

38-
# Get zone ID if not provided
39-
zone_id = args.zone_id
40-
if not zone_id:
41-
zone_id = provider.get_zone_id(args.domain)
42-
if not zone_id:
43-
print(
44-
f"Error: Could not find zone for domain {args.domain}",
45-
file=sys.stderr,
46-
)
47-
sys.exit(1)
48-
49-
if args.action == "get_zone_id":
50-
print(zone_id) # Output zone ID for shell script to capture
51-
52-
elif args.action == "set_cname":
53-
# Legacy action - redirects to set_alias for backward compatibility
37+
if args.action == "set_cname":
5438
if not args.content:
55-
print("Error: --content is required for CNAME records", file=sys.stderr)
39+
print("Error: --content is required for CNAME records",
40+
file=sys.stderr)
5641
sys.exit(1)
5742

58-
success = provider.set_alias_record(zone_id, args.domain, args.content)
43+
success = provider.set_alias_record(args.domain, args.content)
5944
if not success:
60-
print(f"Failed to set alias record for {args.domain}", file=sys.stderr)
45+
print(
46+
f"Failed to set alias record for {args.domain}", file=sys.stderr)
6147
sys.exit(1)
6248
print(f"Successfully set alias record for {args.domain}")
6349

6450
elif args.action == "set_alias":
6551
if not args.content:
66-
print("Error: --content is required for alias records", file=sys.stderr)
52+
print("Error: --content is required for alias records",
53+
file=sys.stderr)
6754
sys.exit(1)
6855

69-
success = provider.set_alias_record(zone_id, args.domain, args.content)
56+
success = provider.set_alias_record(args.domain, args.content)
7057
if not success:
71-
print(f"Failed to set alias record for {args.domain}", file=sys.stderr)
58+
print(
59+
f"Failed to set alias record for {args.domain}", file=sys.stderr)
7260
sys.exit(1)
7361
print(f"Successfully set alias record for {args.domain}")
7462

7563
elif args.action == "set_txt":
7664
if not args.content:
77-
print("Error: --content is required for TXT records", file=sys.stderr)
65+
print("Error: --content is required for TXT records",
66+
file=sys.stderr)
7867
sys.exit(1)
7968

80-
success = provider.set_txt_record(zone_id, args.domain, args.content)
69+
success = provider.set_txt_record(args.domain, args.content)
8170
if not success:
82-
print(f"Failed to set TXT record for {args.domain}", file=sys.stderr)
71+
print(
72+
f"Failed to set TXT record for {args.domain}", file=sys.stderr)
8373
sys.exit(1)
8474
print(f"Successfully set TXT record for {args.domain}")
8575

@@ -92,10 +82,11 @@ def main():
9282
sys.exit(1)
9383

9484
success = provider.set_caa_record(
95-
zone_id, args.domain, args.caa_tag, args.caa_value
85+
args.domain, args.caa_tag, args.caa_value
9686
)
9787
if not success:
98-
print(f"Failed to set CAA record for {args.domain}", file=sys.stderr)
88+
print(
89+
f"Failed to set CAA record for {args.domain}", file=sys.stderr)
9990
sys.exit(1)
10091
print(f"Successfully set CAA record for {args.domain}")
10192

custom-domain/dstack-ingress/scripts/dns_providers/base.py

Lines changed: 20 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -69,26 +69,13 @@ def suitable(cls) -> bool:
6969
"""Check if the current environment is suitable for this DNS provider."""
7070
return os.environ.get(cls.DETECT_ENV) is not None
7171

72-
@abstractmethod
73-
def get_zone_id(self, domain: str) -> Optional[str]:
74-
"""Get the zone ID for a domain.
75-
76-
Args:
77-
domain: The domain name
78-
79-
Returns:
80-
The zone ID if found, None otherwise
81-
"""
82-
pass
83-
8472
@abstractmethod
8573
def get_dns_records(
86-
self, zone_id: str, name: str, record_type: Optional[RecordType] = None
74+
self, name: str, record_type: Optional[RecordType] = None
8775
) -> List[DNSRecord]:
8876
"""Get DNS records for a domain.
8977
9078
Args:
91-
zone_id: The zone ID
9279
name: The record name
9380
record_type: Optional record type filter
9481
@@ -98,11 +85,10 @@ def get_dns_records(
9885
pass
9986

10087
@abstractmethod
101-
def create_dns_record(self, zone_id: str, record: DNSRecord) -> bool:
88+
def create_dns_record(self, record: DNSRecord) -> bool:
10289
"""Create a DNS record.
10390
10491
Args:
105-
zone_id: The zone ID
10692
record: The DNS record to create
10793
10894
Returns:
@@ -111,24 +97,23 @@ def create_dns_record(self, zone_id: str, record: DNSRecord) -> bool:
11197
pass
11298

11399
@abstractmethod
114-
def delete_dns_record(self, zone_id: str, record_id: str) -> bool:
100+
def delete_dns_record(self, record_id: str, domain: str) -> bool:
115101
"""Delete a DNS record.
116102
117103
Args:
118-
zone_id: The zone ID
119104
record_id: The record ID to delete
105+
domain: The domain name (for zone lookup)
120106
121107
Returns:
122108
True if successful, False otherwise
123109
"""
124110
pass
125111

126112
@abstractmethod
127-
def create_caa_record(self, zone_id: str, caa_record: CAARecord) -> bool:
113+
def create_caa_record(self, caa_record: CAARecord) -> bool:
128114
"""Create a CAA record.
129115
130116
Args:
131-
zone_id: The zone ID
132117
caa_record: The CAA record to create
133118
134119
Returns:
@@ -137,12 +122,11 @@ def create_caa_record(self, zone_id: str, caa_record: CAARecord) -> bool:
137122
pass
138123

139124
def set_a_record(
140-
self, zone_id: str, name: str, ip_address: str, ttl: int = 60, proxied: bool = False
125+
self, name: str, ip_address: str, ttl: int = 60, proxied: bool = False
141126
) -> bool:
142127
"""Set an A record (delete existing and create new).
143128
144129
Args:
145-
zone_id: The zone ID
146130
name: The record name
147131
ip_address: The IP address
148132
ttl: Time to live
@@ -151,14 +135,14 @@ def set_a_record(
151135
Returns:
152136
True if successful, False otherwise
153137
"""
154-
existing_records = self.get_dns_records(zone_id, name, RecordType.A)
138+
existing_records = self.get_dns_records(name, RecordType.A)
155139
for record in existing_records:
156140
# Check if record already exists with same IP
157141
if record.content == ip_address:
158142
print("A record with the same IP already exists")
159143
return True
160144
if record.id:
161-
self.delete_dns_record(zone_id, record.id)
145+
self.delete_dns_record(record.id, name)
162146

163147
new_record = DNSRecord(
164148
id=None,
@@ -168,11 +152,10 @@ def set_a_record(
168152
ttl=ttl,
169153
proxied=proxied,
170154
)
171-
return self.create_dns_record(zone_id, new_record)
155+
return self.create_dns_record(new_record)
172156

173157
def set_alias_record(
174158
self,
175-
zone_id: str,
176159
name: str,
177160
content: str,
178161
ttl: int = 60,
@@ -184,7 +167,6 @@ def set_alias_record(
184167
to use A records instead (e.g., Linode to avoid CAA conflicts).
185168
186169
Args:
187-
zone_id: The zone ID
188170
name: The record name
189171
content: The alias target (domain name)
190172
ttl: Time to live
@@ -193,11 +175,10 @@ def set_alias_record(
193175
Returns:
194176
True if successful, False otherwise
195177
"""
196-
return self.set_cname_record(zone_id, name, content, ttl, proxied)
178+
return self.set_cname_record(name, content, ttl, proxied)
197179

198180
def set_cname_record(
199181
self,
200-
zone_id: str,
201182
name: str,
202183
content: str,
203184
ttl: int = 60,
@@ -209,7 +190,6 @@ def set_cname_record(
209190
to use A records instead (e.g., Linode to avoid CAA conflicts).
210191
211192
Args:
212-
zone_id: The zone ID
213193
name: The record name
214194
content: The alias target (domain name)
215195
ttl: Time to live
@@ -218,14 +198,14 @@ def set_cname_record(
218198
Returns:
219199
True if successful, False otherwise
220200
"""
221-
existing_records = self.get_dns_records(zone_id, name, RecordType.CNAME)
201+
existing_records = self.get_dns_records(name, RecordType.CNAME)
222202
for record in existing_records:
223203
# Check if record already exists with same content
224204
if record.content == content:
225205
print("CNAME record with the same content already exists")
226206
return True
227207
if record.id:
228-
self.delete_dns_record(zone_id, record.id)
208+
self.delete_dns_record(record.id, name)
229209

230210
new_record = DNSRecord(
231211
id=None,
@@ -235,39 +215,37 @@ def set_cname_record(
235215
ttl=ttl,
236216
proxied=proxied,
237217
)
238-
return self.create_dns_record(zone_id, new_record)
218+
return self.create_dns_record(new_record)
239219

240220
def set_txt_record(
241-
self, zone_id: str, name: str, content: str, ttl: int = 60
221+
self, name: str, content: str, ttl: int = 60
242222
) -> bool:
243223
"""Set a TXT record (delete existing and create new).
244224
245225
Args:
246-
zone_id: The zone ID
247226
name: The record name
248227
content: The TXT content
249228
ttl: Time to live
250229
251230
Returns:
252231
True if successful, False otherwise
253232
"""
254-
existing_records = self.get_dns_records(zone_id, name, RecordType.TXT)
233+
existing_records = self.get_dns_records(name, RecordType.TXT)
255234
for record in existing_records:
256235
# Check if record already exists with same content
257236
if record.content == content or record.content == f'"{content}"':
258237
print("TXT record with the same content already exists")
259238
return True
260239
if record.id:
261-
self.delete_dns_record(zone_id, record.id)
240+
self.delete_dns_record(record.id, name)
262241

263242
new_record = DNSRecord(
264243
id=None, name=name, type=RecordType.TXT, content=content, ttl=ttl
265244
)
266-
return self.create_dns_record(zone_id, new_record)
245+
return self.create_dns_record(new_record)
267246

268247
def set_caa_record(
269248
self,
270-
zone_id: str,
271249
name: str,
272250
tag: str,
273251
value: str,
@@ -277,7 +255,6 @@ def set_caa_record(
277255
"""Set a CAA record (delete existing with same tag and create new).
278256
279257
Args:
280-
zone_id: The zone ID
281258
name: The record name
282259
tag: The CAA tag (issue, issuewild, iodef)
283260
value: The CAA value
@@ -287,14 +264,14 @@ def set_caa_record(
287264
Returns:
288265
True if successful, False otherwise
289266
"""
290-
existing_records = self.get_dns_records(zone_id, name, RecordType.CAA)
267+
existing_records = self.get_dns_records(name, RecordType.CAA)
291268
for record in existing_records:
292269
if record.data and record.data.get("tag") == tag:
293270
if record.data.get("value") == value:
294271
print("CAA record with the same content already exists")
295272
return True
296273
if record.id:
297-
self.delete_dns_record(zone_id, record.id)
274+
self.delete_dns_record(record.id, name)
298275

299276
caa_record = CAARecord(name=name, flags=flags, tag=tag, value=value, ttl=ttl)
300-
return self.create_caa_record(zone_id, caa_record)
277+
return self.create_caa_record(caa_record)

0 commit comments

Comments
 (0)