diff --git a/documentation/provider/gidinet.md b/documentation/provider/gidinet.md index 9e82c1b256..25535c48c0 100644 --- a/documentation/provider/gidinet.md +++ b/documentation/provider/gidinet.md @@ -123,13 +123,20 @@ Allowed TTL values (in seconds): ### Nameservers -Gidinet's default nameservers are: +Gidinet offers two DNS tiers with different nameserver sets. + +**Free tier (default):** - `dnsl1.gidinet.com` - `dnsl2.gidinet.com` -**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. +**Premium DNS:** +- `dns1.gidinet.com` +- `dns2.gidinet.com` +- `dns3.gidinet.com` +- `dns4.gidinet.com` +- `dns5.gidinet.com` -To manage nameserver delegation, use Gidinet as a **registrar** with the `NAMESERVER()` function: +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: {% code title="dnsconfig.js" %} ```javascript @@ -137,14 +144,31 @@ var REG_GIDINET = NewRegistrar("gidinet"); var DSP_GIDINET = NewDnsProvider("gidinet"); D("example.com", REG_GIDINET, DnsProvider(DSP_GIDINET), - NAMESERVER("dnsl1.gidinet.com."), - NAMESERVER("dnsl2.gidinet.com."), A("test", "1.2.3.4"), ); ``` {% endcode %} -This uses the Core API's `domainNameServersChange` method to update the nameservers at the registry level. +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: + +{% code title="dnsconfig.js" %} +```javascript +var REG_GIDINET = NewRegistrar("gidinet"); +var DSP_GIDINET = NewDnsProvider("gidinet"); + +D("premium.example", REG_GIDINET, + DnsProvider(DSP_GIDINET, 0), + GIDINET_PREMIUM_NS(), + A("test", "1.2.3.4"), +); +``` +{% endcode %} + +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. + +When used as a registrar, Gidinet updates the nameservers at the registry level via the Core API's `domainNameServersChange` method. + +**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. ### Zone creation diff --git a/pkg/js/helpers.js b/pkg/js/helpers.js index 6fec6e92df..acc1b93de0 100644 --- a/pkg/js/helpers.js +++ b/pkg/js/helpers.js @@ -1490,6 +1490,28 @@ function HEDNS_DDNS_KEY(key) { return { hedns_dynamic: 'on', hedns_ddns_key: key }; } +// Gidinet aliases: + +// GIDINET_PREMIUM_NS(): Emit NAMESERVER records for Gidinet premium DNS +// (dns1..dns5.gidinet.com). Use together with DnsProvider(DNS_GIDINET, 0) +// so the free-tier defaults from GetNameservers are skipped. +// +// Usage: +// D("premium.example", REG_GIDINET, +// DnsProvider(DNS_GIDINET, 0), +// GIDINET_PREMIUM_NS(), +// A("www", "1.2.3.4"), +// ); +function GIDINET_PREMIUM_NS() { + return [ + NAMESERVER('dns1.gidinet.com.'), + NAMESERVER('dns2.gidinet.com.'), + NAMESERVER('dns3.gidinet.com.'), + NAMESERVER('dns4.gidinet.com.'), + NAMESERVER('dns5.gidinet.com.'), + ]; +} + // CUSTOM, PROVIDER SPECIFIC RECORD TYPES function _validateCloudflareRedirect(value) { diff --git a/providers/gidinet/gidinetProvider.go b/providers/gidinet/gidinetProvider.go index f211424dc2..e8e8f73642 100644 --- a/providers/gidinet/gidinetProvider.go +++ b/providers/gidinet/gidinetProvider.go @@ -97,11 +97,15 @@ func NewGidinet(m map[string]string, metadata json.RawMessage) (providers.DNSSer return api, nil } -// GetNameservers returns the nameservers for a domain. -// Returns empty because apex NS records cannot be managed via the DNS API - -// they are managed by the registrar. Use REG_GIDINET with NAMESERVER() instead. +// GetNameservers returns the static Gidinet DNS nameservers used by every +// zone hosted on the platform. Returning them here lets dnscontrol suggest +// the correct delegation to the registrar without requiring an explicit +// NAMESERVER() in the zone file. func (c *gidinetProvider) GetNameservers(domain string) ([]*models.Nameserver, error) { - return nil, nil + return models.ToNameservers([]string{ + "dnsl1.gidinet.com", + "dnsl2.gidinet.com", + }) } // 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 { // filterApexNS removes NS records at the apex from dc.Records. // Gidinet does not support modifying apex NS records via the DNS API - they are -// managed by the registrar. Use REG_GIDINET with NAMESERVER() to manage them. +// managed by the registrar. Apex NS records synthesized from dc.Nameservers +// (auto-injected by GetNameservers or declared via NAMESERVER()) are dropped +// silently since they are handled by the registrar side. Any other apex NS +// record is dropped with a warning because it cannot be honored by the +// Gidinet DNS API. func filterApexNS(dc *models.DomainConfig) { + expected := make(map[string]bool, len(dc.Nameservers)) + for _, ns := range dc.Nameservers { + expected[strings.TrimSuffix(ns.Name, ".")] = true + } + newList := make([]*models.RecordConfig, 0, len(dc.Records)) for _, rec := range dc.Records { if rec.Type == "NS" && rec.GetLabelFQDN() == dc.Name { - 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()) + target := strings.TrimSuffix(rec.GetTargetField(), ".") + if !expected[target] { + printer.Warnf("GIDINET does not support modifying NS records at apex. %s will not be added.\n", rec.GetTargetField()) + } continue } newList = append(newList, rec)