diff --git a/cmd/zz_gen_cmd_dnshelp.go b/cmd/zz_gen_cmd_dnshelp.go index 7e3729a1..02492723 100644 --- a/cmd/zz_gen_cmd_dnshelp.go +++ b/cmd/zz_gen_cmd_dnshelp.go @@ -905,7 +905,6 @@ func displayDNSHelp(name string) error { ew.writeln(`Credentials:`) ew.writeln(` - "HOSTINGDE_API_KEY": API key`) - ew.writeln(` - "HOSTINGDE_ZONE_NAME": Zone name in ACE format`) ew.writeln() ew.writeln(`Additional Configuration:`) @@ -913,6 +912,7 @@ func displayDNSHelp(name string) error { ew.writeln(` - "HOSTINGDE_POLLING_INTERVAL": Time between DNS propagation check`) ew.writeln(` - "HOSTINGDE_PROPAGATION_TIMEOUT": Maximum waiting time for DNS propagation`) ew.writeln(` - "HOSTINGDE_TTL": The TTL of the TXT record used for the DNS challenge`) + ew.writeln(` - "HOSTINGDE_ZONE_NAME": Zone name in ACE format`) ew.writeln() ew.writeln(`More information: https://go-acme.github.io/lego/dns/hostingde`) diff --git a/docs/content/dns/zz_gen_hostingde.md b/docs/content/dns/zz_gen_hostingde.md index 3bf8f117..07d1d93f 100644 --- a/docs/content/dns/zz_gen_hostingde.md +++ b/docs/content/dns/zz_gen_hostingde.md @@ -22,7 +22,6 @@ Here is an example bash command using the Hosting.de provider: ```bash HOSTINGDE_API_KEY=xxxxxxxx \ -HOSTINGDE_ZONE_NAME=yyyyy \ lego -email myemail@example.com --dns hostingde --domains my.example.org -run ``` @@ -34,7 +33,6 @@ lego -email myemail@example.com --dns hostingde --domains my.example.org -run | Environment Variable Name | Description | |-----------------------|-------------| | `HOSTINGDE_API_KEY` | API key | -| `HOSTINGDE_ZONE_NAME` | Zone name in ACE format | The environment variable names can be suffixed by `_FILE` to reference a file instead of a value. More information [here](/lego/dns/#configuration-and-credentials). @@ -48,6 +46,7 @@ More information [here](/lego/dns/#configuration-and-credentials). | `HOSTINGDE_POLLING_INTERVAL` | Time between DNS propagation check | | `HOSTINGDE_PROPAGATION_TIMEOUT` | Maximum waiting time for DNS propagation | | `HOSTINGDE_TTL` | The TTL of the TXT record used for the DNS challenge | +| `HOSTINGDE_ZONE_NAME` | Zone name in ACE format | The environment variable names can be suffixed by `_FILE` to reference a file instead of a value. More information [here](/lego/dns/#configuration-and-credentials). diff --git a/providers/dns/hostingde/hostingde.go b/providers/dns/hostingde/hostingde.go index 2b672a3a..f4f03beb 100644 --- a/providers/dns/hostingde/hostingde.go +++ b/providers/dns/hostingde/hostingde.go @@ -58,14 +58,14 @@ type DNSProvider struct { // Credentials must be passed in the environment variables: // HOSTINGDE_ZONE_NAME and HOSTINGDE_API_KEY. func NewDNSProvider() (*DNSProvider, error) { - values, err := env.Get(EnvAPIKey, EnvZoneName) + values, err := env.Get(EnvAPIKey) if err != nil { return nil, fmt.Errorf("hostingde: %w", err) } config := NewDefaultConfig() config.APIKey = values[EnvAPIKey] - config.ZoneName = values[EnvZoneName] + config.ZoneName = env.GetOrFile(EnvZoneName) return NewDNSProviderConfig(config) } @@ -80,10 +80,6 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { return nil, errors.New("hostingde: API key missing") } - if config.ZoneName == "" { - return nil, errors.New("hostingde: Zone Name missing") - } - return &DNSProvider{ config: config, recordIDs: make(map[string]string), @@ -100,14 +96,16 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { func (d *DNSProvider) Present(domain, token, keyAuth string) error { fqdn, value := dns01.GetRecord(domain, keyAuth) + zoneName, err := d.getZoneName(fqdn) + if err != nil { + return fmt.Errorf("hostingde: could not determine zone for domain %q: %w", domain, err) + } + // get the ZoneConfig for that domain zonesFind := ZoneConfigsFindRequest{ - Filter: Filter{ - Field: "zoneName", - Value: d.config.ZoneName, - }, - Limit: 1, - Page: 1, + Filter: Filter{Field: "zoneName", Value: zoneName}, + Limit: 1, + Page: 1, } zonesFind.AuthToken = d.config.APIKey @@ -115,7 +113,7 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { if err != nil { return fmt.Errorf("hostingde: %w", err) } - zoneConfig.Name = d.config.ZoneName + zoneConfig.Name = zoneName rec := []DNSRecord{{ Type: "TXT", @@ -154,6 +152,11 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error { func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { fqdn, value := dns01.GetRecord(domain, keyAuth) + zoneName, err := d.getZoneName(fqdn) + if err != nil { + return fmt.Errorf("hostingde: could not determine zone for domain %q: %w", domain, err) + } + rec := []DNSRecord{{ Type: "TXT", Name: dns01.UnFqdn(fqdn), @@ -162,12 +165,9 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { // get the ZoneConfig for that domain zonesFind := ZoneConfigsFindRequest{ - Filter: Filter{ - Field: "zoneName", - Value: d.config.ZoneName, - }, - Limit: 1, - Page: 1, + Filter: Filter{Field: "zoneName", Value: zoneName}, + Limit: 1, + Page: 1, } zonesFind.AuthToken = d.config.APIKey @@ -175,7 +175,7 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { if err != nil { return fmt.Errorf("hostingde: %w", err) } - zoneConfig.Name = d.config.ZoneName + zoneConfig.Name = zoneName req := ZoneUpdateRequest{ ZoneConfig: *zoneConfig, @@ -194,3 +194,20 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error { } return nil } + +func (d *DNSProvider) getZoneName(fqdn string) (string, error) { + if d.config.ZoneName != "" { + return d.config.ZoneName, nil + } + + zoneName, err := dns01.FindZoneByFqdn(fqdn) + if err != nil { + return "", err + } + + if zoneName == "" { + return "", errors.New("empty zone name") + } + + return dns01.UnFqdn(zoneName), nil +} diff --git a/providers/dns/hostingde/hostingde.toml b/providers/dns/hostingde/hostingde.toml index 72654cfd..361f6466 100644 --- a/providers/dns/hostingde/hostingde.toml +++ b/providers/dns/hostingde/hostingde.toml @@ -6,15 +6,14 @@ Since = "v1.1.0" Example = ''' HOSTINGDE_API_KEY=xxxxxxxx \ -HOSTINGDE_ZONE_NAME=yyyyy \ lego -email myemail@example.com --dns hostingde --domains my.example.org -run ''' [Configuration] [Configuration.Credentials] HOSTINGDE_API_KEY = "API key" - HOSTINGDE_ZONE_NAME = "Zone name in ACE format" [Configuration.Additional] + HOSTINGDE_ZONE_NAME = "Zone name in ACE format" HOSTINGDE_POLLING_INTERVAL = "Time between DNS propagation check" HOSTINGDE_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation" HOSTINGDE_TTL = "The TTL of the TXT record used for the DNS challenge" diff --git a/providers/dns/hostingde/hostingde_test.go b/providers/dns/hostingde/hostingde_test.go index 32537bb0..d7681f95 100644 --- a/providers/dns/hostingde/hostingde_test.go +++ b/providers/dns/hostingde/hostingde_test.go @@ -25,7 +25,7 @@ func TestNewDNSProvider(t *testing.T) { desc: "success", envVars: map[string]string{ EnvAPIKey: "123", - EnvZoneName: "456", + EnvZoneName: "example.org", }, }, { @@ -34,7 +34,7 @@ func TestNewDNSProvider(t *testing.T) { EnvAPIKey: "", EnvZoneName: "", }, - expected: "hostingde: some credentials information are missing: HOSTINGDE_API_KEY,HOSTINGDE_ZONE_NAME", + expected: "hostingde: some credentials information are missing: HOSTINGDE_API_KEY", }, { desc: "missing access key", @@ -44,14 +44,6 @@ func TestNewDNSProvider(t *testing.T) { }, expected: "hostingde: some credentials information are missing: HOSTINGDE_API_KEY", }, - { - desc: "missing zone name", - envVars: map[string]string{ - EnvAPIKey: "123", - EnvZoneName: "", - }, - expected: "hostingde: some credentials information are missing: HOSTINGDE_ZONE_NAME", - }, } for _, test := range testCases { @@ -85,7 +77,7 @@ func TestNewDNSProviderConfig(t *testing.T) { { desc: "success", apiKey: "123", - zoneName: "456", + zoneName: "example.org", }, { desc: "missing credentials", @@ -96,11 +88,6 @@ func TestNewDNSProviderConfig(t *testing.T) { zoneName: "456", expected: "hostingde: API key missing", }, - { - desc: "missing zone name", - apiKey: "123", - expected: "hostingde: Zone Name missing", - }, } for _, test := range testCases {