Skip to content

Commit

Permalink
review: first quick review
Browse files Browse the repository at this point in the history
  • Loading branch information
ldez committed Oct 11, 2023
1 parent 8dfc4f4 commit b58cdd0
Show file tree
Hide file tree
Showing 6 changed files with 421 additions and 313 deletions.
106 changes: 50 additions & 56 deletions providers/dns/liquidweb/liquidweb.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,21 @@ import (
"github.com/liquidweb/liquidweb-go/network"
)

const DefaultBaseURL = "https://api.liquidweb.com"
const defaultBaseURL = "https://api.liquidweb.com"

// Environment variables names.
const (
EnvPrefix = "LWAPI_"
envLegacyPrefix = "LIQUID_WEB_"

EnvURL = "URL"
EnvUsername = "USERNAME"
EnvPassword = "PASSWORD"

EnvZone = "ZONE"
EnvTTL = "TTL"
EnvPropagationTimeout = "PROPAGATION_TIMEOUT"
EnvPollingInterval = "POLLING_INTERVAL"
EnvHTTPTimeout = "HTTP_TIMEOUT"
envNamespace = "LIQUID_WEB_"

EnvURL = envNamespace + "URL"
EnvUsername = envNamespace + "USERNAME"
EnvPassword = envNamespace + "PASSWORD"

EnvZone = envNamespace + "ZONE"
EnvTTL = envNamespace + "TTL"
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
EnvHTTPTimeout = envNamespace + "HTTP_TIMEOUT"
)

// Config is used to configure the creation of the DNSProvider.
Expand All @@ -46,6 +45,17 @@ type Config struct {
HTTPTimeout time.Duration
}

// NewDefaultConfig returns a default configuration for the DNSProvider.
func NewDefaultConfig() *Config {
return &Config{
BaseURL: defaultBaseURL,
TTL: env.GetOrDefaultInt(EnvTTL, 300),
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute),
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, 2*time.Second),
HTTPTimeout: env.GetOrDefaultSecond(EnvHTTPTimeout, 1*time.Minute),
}
}

// DNSProvider implements the challenge.Provider interface.
type DNSProvider struct {
config *Config
Expand All @@ -54,47 +64,32 @@ type DNSProvider struct {
recordIDsMu sync.Mutex
}

func getStringEnv(varName, defVal string) string {
defVal = env.GetOrDefaultString(envLegacyPrefix+varName, defVal)
defVal = env.GetOrDefaultString(EnvPrefix+varName, defVal)
return defVal
}
// NewDNSProvider returns a DNSProvider instance configured for Liquid Web.
func NewDNSProvider() (*DNSProvider, error) {
values, err := env.Get(EnvUsername, EnvPassword)
if err != nil {
return nil, fmt.Errorf("liquidweb: %w", err)
}

func getIntEnv(varName string, defVal int) int {
defVal = env.GetOrDefaultInt(envLegacyPrefix+varName, defVal)
defVal = env.GetOrDefaultInt(EnvPrefix+varName, defVal)
return defVal
}
config := NewDefaultConfig()
config.BaseURL = env.GetOrFile(EnvURL)
config.Username = values[EnvUsername]
config.Password = values[EnvPassword]
config.Zone = env.GetOrDefaultString(EnvZone, "")

func getSecondEnv(varName string, defVal time.Duration) time.Duration {
defVal = env.GetOrDefaultSecond(envLegacyPrefix+varName, defVal)
defVal = env.GetOrDefaultSecond(EnvPrefix+varName, defVal)
return defVal
return NewDNSProviderConfig(config)
}

// NewDNSProvider returns a DNSProvider instance configured for Liquid Web.
func NewDNSProvider() (*DNSProvider, error) {
config := &Config{
Username: getStringEnv(EnvUsername, ""),
Password: getStringEnv(EnvPassword, ""),
BaseURL: getStringEnv(EnvURL, DefaultBaseURL),
Zone: getStringEnv(EnvZone, ""),
TTL: getIntEnv(EnvTTL, 300),
PropagationTimeout: getSecondEnv(EnvPropagationTimeout, 2*time.Minute),
PollingInterval: getSecondEnv(EnvPollingInterval, 2*time.Second),
HTTPTimeout: getSecondEnv(EnvHTTPTimeout, 1*time.Minute),
// NewDNSProviderConfig return a DNSProvider instance configured for Liquid Web.
func NewDNSProviderConfig(config *Config) (*DNSProvider, error) {
if config == nil {
return nil, errors.New("liquidweb: the configuration of the DNS provider is nil")
}

switch {
case config.Username == "" && config.Password == "":
return nil, errors.New("liquidweb: username and password are missing, set LWAPI_USERNAME and LWAPI_PASSWORD")
case config.Username == "":
return nil, errors.New("liquidweb: username is missing, set LWAPI_USERNAME")
case config.Password == "":
return nil, errors.New("liquidweb: password is missing, set LWAPI_PASSWORD")
if config.BaseURL == "" {
config.BaseURL = defaultBaseURL
}

// Initialize LW client.
client, err := lw.NewAPI(config.Username, config.Password, config.BaseURL, int(config.HTTPTimeout.Seconds()))
if err != nil {
return nil, fmt.Errorf("liquidweb: could not create Liquid Web API client: %w", err)
Expand Down Expand Up @@ -127,11 +122,11 @@ func (d *DNSProvider) Present(domain, token, keyAuth string) error {

if params.Zone == "" {
bestZone, err := d.findZone(params.Name)
if err == nil {
params.Zone = bestZone
} else {
if err != nil {
return err
}

params.Zone = bestZone
}

dnsEntry, err := d.client.NetworkDNS.Create(params)
Expand Down Expand Up @@ -169,33 +164,32 @@ func (d *DNSProvider) CleanUp(domain, token, keyAuth string) error {
return nil
}

func (d *DNSProvider) findZone(fqdn string) (string, error) {
fqdn = dns01.UnFqdn(fqdn)
func (d *DNSProvider) findZone(domain string) (string, error) {
zones, err := d.client.NetworkDNSZone.ListAll()
if err != nil {
return "", fmt.Errorf("failed to retrieve zones for account: %w", err)
}

// filter the zones on the account to only ones that match
for id := 0; id < len(zones.Items); {
if !strings.HasSuffix(fqdn, zones.Items[id].Name) {
if !strings.HasSuffix(domain, zones.Items[id].Name) {
zones.Items = append(zones.Items[:id], zones.Items[id+1:]...)
} else {
id++
}
}

if len(zones.Items) < 1 {
return "", fmt.Errorf("no valid zone in account for certificate %s", fqdn)
return "", fmt.Errorf("no valid zone in account for certificate %s", domain)
}

// filter the zones on the account to only ones that
sort.Slice(zones.Items, func(i, j int) bool {
return len(zones.Items[i].Name) > len(zones.Items[j].Name)
})

// powerdns _only_ looks for records on the longest matching subdomain zone
// aka, for test.sub.example.com if sub.example.com exists, it will look there
// it will not look atexample.com even if it also exists
// powerdns _only_ looks for records on the longest matching subdomain zone aka,
// for test.sub.example.com if sub.example.com exists,
// it will look there it will not look atexample.com even if it also exists
return zones.Items[0].Name, nil
}
20 changes: 10 additions & 10 deletions providers/dns/liquidweb/liquidweb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ Code = "liquidweb"
Since = "v3.1.0"

Example = '''
LWAPI_USERNAME=someuser \
LWAPI_PASSWORD=somepass \
LIQUID_WEB_USERNAME=someuser \
LIQUID_WEB_PASSWORD=somepass \
lego --email you@example.com --dns liquidweb --domains my.example.org run
'''

[Configuration]
[Configuration.Credentials]
LWAPI_USERNAME = "Liquid Web API Username"
LWAPI_PASSWORD = "Liquid Web API Password"
LIQUID_WEB_USERNAME = "Liquid Web API Username"
LIQUID_WEB_PASSWORD = "Liquid Web API Password"
[Configuration.Additional]
LWAPI_ZONE = "DNS Zone"
LWAPI_URL = "Liquid Web API endpoint"
LWAPI_TTL = "The TTL of the TXT record used for the DNS challenge"
LWAPI_POLLING_INTERVAL = "Time between DNS propagation check"
LWAPI_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation"
LWAPI_HTTP_TIMEOUT = "Maximum waiting time for the DNS records to be created (not verified)"
LIQUID_WEB_ZONE = "DNS Zone"
LIQUID_WEB_URL = "Liquid Web API endpoint"
LIQUID_WEB_TTL = "The TTL of the TXT record used for the DNS challenge"
LIQUID_WEB_POLLING_INTERVAL = "Time between DNS propagation check"
LIQUID_WEB_PROPAGATION_TIMEOUT = "Maximum waiting time for DNS propagation"
LIQUID_WEB_HTTP_TIMEOUT = "Maximum waiting time for the DNS records to be created (not verified)"

[Links]
API = "https://api.liquidweb.com/docs/"
Expand Down
Loading

0 comments on commit b58cdd0

Please sign in to comment.