Skip to content

Commit c93f116

Browse files
authored
GIDINET: Auto-suggest nameservers and add premium DNS helper (#4203)
## Summary - **`GetNameservers` now returns the static free-tier Gidinet nameservers** (`dnsl1/dnsl2.gidinet.com`). Previously it returned `nil, nil`, which meant DNSControl could not derive registrar delegation from the DNS provider for Gidinet-hosted zones. With this change, zones declared as `D(..., REG_GIDINET, DnsProvider(DSP_GIDINET), ...)` get correct NS suggestions automatically, matching the behavior of providers like Cloudflare or netcup. - **New `GIDINET_PREMIUM_NS()` JS helper** that emits `NAMESERVER("dns1..dns5.gidinet.com.")` for zones on Gidinet's premium DNS tier. Intended to be paired with `DnsProvider(DSP_GIDINET, 0)` so the free-tier defaults from `GetNameservers` are skipped and only the five premium nameservers drive the delegation. - **`filterApexNS` now drops apex NS records silently when they were synthesized from `dc.Nameservers`** (either auto-injected by `GetNameservers` or declared via `NAMESERVER()`), since `AddNSRecords` adds those to `dc.Records` automatically. Previously it warned on every preview once `GetNameservers` began returning values. Truly unexpected apex NS targets (e.g. a stray `NS("@", "something-else.")`) still emit a warning because the Gidinet DNS API cannot honor them. - **Documentation updated** to describe both tiers and the `GIDINET_PREMIUM_NS()` usage pattern. ## Motivation Before this change, a zone served by Gidinet DNS required a redundant `NS_GIDINET()`-style block of explicit `NAMESERVER()` calls just so `REG_GIDINET` could propose the correct delegation. Users hit a no-op/warning loop where the registrar had nothing to compare against and/or where apex NS records raised spurious warnings. Gidinet's nameservers are static per-tier, so returning them from `GetNameservers` is safe and matches the convention used by other providers. ## Test plan - [x] `go test ./...` - [x] `go vet ./...` - [x] `gofmt -l providers/gidinet/ pkg/js/` - [x] `dnscontrol check` on a real Gidinet-hosted configuration - [x] `dnscontrol preview` on a free-tier zone: registrar correctly proposes `dnsl1/dnsl2.gidinet.com` delegation without explicit `NAMESERVER()` in the zone file; no spurious apex-NS warnings. - [ ] `dnscontrol preview` on a premium-tier zone using `DnsProvider(DSP_GIDINET, 0) + GIDINET_PREMIUM_NS()` (pending availability of a premium zone for the author to validate end-to-end). - [x] IR inspection (`print-ir`) on a synthetic premium-tier config confirms the helper expands to the five `NAMESERVER("dns1..5.gidinet.com.")` entries. ## Notes - No interface or API changes. - Backwards compatible: zones that already include explicit `NAMESERVER("dnsl1/dnsl2…")` records still work (the registrar-side dedup already handles duplicates).
1 parent b55ad79 commit c93f116

3 files changed

Lines changed: 74 additions & 12 deletions

File tree

documentation/provider/gidinet.md

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,28 +123,52 @@ Allowed TTL values (in seconds):
123123

124124
### Nameservers
125125

126-
Gidinet's default nameservers are:
126+
Gidinet offers two DNS tiers with different nameserver sets.
127+
128+
**Free tier (default):**
127129
- `dnsl1.gidinet.com`
128130
- `dnsl2.gidinet.com`
129131

130-
**Apex NS records are automatically filtered** by the DNS provider with a warning message. Gidinet does not support modifying NS records at the zone apex via the DNS API - they are managed by the registrar.
132+
**Premium DNS:**
133+
- `dns1.gidinet.com`
134+
- `dns2.gidinet.com`
135+
- `dns3.gidinet.com`
136+
- `dns4.gidinet.com`
137+
- `dns5.gidinet.com`
131138

132-
To manage nameserver delegation, use Gidinet as a **registrar** with the `NAMESERVER()` function:
139+
The DNS provider returns the free-tier nameservers via `GetNameservers`, so free-tier zones need no explicit `NAMESERVER(...)` — DNSControl will suggest the correct delegation to the registrar automatically:
133140

134141
{% code title="dnsconfig.js" %}
135142
```javascript
136143
var REG_GIDINET = NewRegistrar("gidinet");
137144
var DSP_GIDINET = NewDnsProvider("gidinet");
138145

139146
D("example.com", REG_GIDINET, DnsProvider(DSP_GIDINET),
140-
NAMESERVER("dnsl1.gidinet.com."),
141-
NAMESERVER("dnsl2.gidinet.com."),
142147
A("test", "1.2.3.4"),
143148
);
144149
```
145150
{% endcode %}
146151

147-
This uses the Core API's `domainNameServersChange` method to update the nameservers at the registry level.
152+
For zones on the **premium DNS** tier, opt out of the free-tier defaults with `DnsProvider(DSP_GIDINET, 0)` and use the `GIDINET_PREMIUM_NS()` helper to emit the five premium `NAMESERVER()` records:
153+
154+
{% code title="dnsconfig.js" %}
155+
```javascript
156+
var REG_GIDINET = NewRegistrar("gidinet");
157+
var DSP_GIDINET = NewDnsProvider("gidinet");
158+
159+
D("premium.example", REG_GIDINET,
160+
DnsProvider(DSP_GIDINET, 0),
161+
GIDINET_PREMIUM_NS(),
162+
A("test", "1.2.3.4"),
163+
);
164+
```
165+
{% endcode %}
166+
167+
The `0` passed to `DnsProvider()` tells DNSControl to skip the provider's auto-injected nameservers for that zone, so only the explicit `NAMESERVER()` records drive the delegation.
168+
169+
When used as a registrar, Gidinet updates the nameservers at the registry level via the Core API's `domainNameServersChange` method.
170+
171+
**Apex NS records are automatically filtered** by the DNS provider with a warning message. Gidinet does not support modifying NS records at the zone apex via the DNS API — they are managed by the registrar. If you use a DNS provider other than Gidinet, declare `NAMESERVER(...)` records (or rely on the other provider's `GetNameservers`) so `REG_GIDINET` can drive the delegation.
148172

149173
### Zone creation
150174

pkg/js/helpers.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,6 +1490,28 @@ function HEDNS_DDNS_KEY(key) {
14901490
return { hedns_dynamic: 'on', hedns_ddns_key: key };
14911491
}
14921492

1493+
// Gidinet aliases:
1494+
1495+
// GIDINET_PREMIUM_NS(): Emit NAMESERVER records for Gidinet premium DNS
1496+
// (dns1..dns5.gidinet.com). Use together with DnsProvider(DNS_GIDINET, 0)
1497+
// so the free-tier defaults from GetNameservers are skipped.
1498+
//
1499+
// Usage:
1500+
// D("premium.example", REG_GIDINET,
1501+
// DnsProvider(DNS_GIDINET, 0),
1502+
// GIDINET_PREMIUM_NS(),
1503+
// A("www", "1.2.3.4"),
1504+
// );
1505+
function GIDINET_PREMIUM_NS() {
1506+
return [
1507+
NAMESERVER('dns1.gidinet.com.'),
1508+
NAMESERVER('dns2.gidinet.com.'),
1509+
NAMESERVER('dns3.gidinet.com.'),
1510+
NAMESERVER('dns4.gidinet.com.'),
1511+
NAMESERVER('dns5.gidinet.com.'),
1512+
];
1513+
}
1514+
14931515
// CUSTOM, PROVIDER SPECIFIC RECORD TYPES
14941516

14951517
function _validateCloudflareRedirect(value) {

providers/gidinet/gidinetProvider.go

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,15 @@ func NewGidinet(m map[string]string, metadata json.RawMessage) (providers.DNSSer
9797
return api, nil
9898
}
9999

100-
// GetNameservers returns the nameservers for a domain.
101-
// Returns empty because apex NS records cannot be managed via the DNS API -
102-
// they are managed by the registrar. Use REG_GIDINET with NAMESERVER() instead.
100+
// GetNameservers returns the static Gidinet DNS nameservers used by every
101+
// zone hosted on the platform. Returning them here lets dnscontrol suggest
102+
// the correct delegation to the registrar without requiring an explicit
103+
// NAMESERVER() in the zone file.
103104
func (c *gidinetProvider) GetNameservers(domain string) ([]*models.Nameserver, error) {
104-
return nil, nil
105+
return models.ToNameservers([]string{
106+
"dnsl1.gidinet.com",
107+
"dnsl2.gidinet.com",
108+
})
105109
}
106110

107111
// GetZoneRecords gets the records of a zone and returns them in RecordConfig format.
@@ -335,12 +339,24 @@ func toGidinetRecord(domain string, rc *models.RecordConfig) *DNSRecord {
335339

336340
// filterApexNS removes NS records at the apex from dc.Records.
337341
// Gidinet does not support modifying apex NS records via the DNS API - they are
338-
// managed by the registrar. Use REG_GIDINET with NAMESERVER() to manage them.
342+
// managed by the registrar. Apex NS records synthesized from dc.Nameservers
343+
// (auto-injected by GetNameservers or declared via NAMESERVER()) are dropped
344+
// silently since they are handled by the registrar side. Any other apex NS
345+
// record is dropped with a warning because it cannot be honored by the
346+
// Gidinet DNS API.
339347
func filterApexNS(dc *models.DomainConfig) {
348+
expected := make(map[string]bool, len(dc.Nameservers))
349+
for _, ns := range dc.Nameservers {
350+
expected[strings.TrimSuffix(ns.Name, ".")] = true
351+
}
352+
340353
newList := make([]*models.RecordConfig, 0, len(dc.Records))
341354
for _, rec := range dc.Records {
342355
if rec.Type == "NS" && rec.GetLabelFQDN() == dc.Name {
343-
printer.Warnf("GIDINET does not support modifying NS records at apex. %s will not be added. Use REG_GIDINET with NAMESERVER() instead.\n", rec.GetTargetField())
356+
target := strings.TrimSuffix(rec.GetTargetField(), ".")
357+
if !expected[target] {
358+
printer.Warnf("GIDINET does not support modifying NS records at apex. %s will not be added.\n", rec.GetTargetField())
359+
}
344360
continue
345361
}
346362
newList = append(newList, rec)

0 commit comments

Comments
 (0)