diff --git a/providers/dns/ovh/ovh.go b/providers/dns/ovh/ovh.go index edc3e6e3..287bd8c9 100644 --- a/providers/dns/ovh/ovh.go +++ b/providers/dns/ovh/ovh.go @@ -15,7 +15,7 @@ import ( // OVH API reference: https://eu.api.ovh.com/ // Create a Token: https://eu.api.ovh.com/createToken/ -// Create a OAuth2 client: https://eu.api.ovh.com/console-preview/?section=%2Fme&branch=v1#post-/me/api/oauth2/client +// Create a OAuth2 client: https://eu.api.ovh.com/console/?section=%2Fme&branch=v1#post-/me/api/oauth2/client // Environment variables names. const ( @@ -102,9 +102,23 @@ type DNSProvider struct { // Credentials must be passed in the environment variables: // OVH_ENDPOINT (must be either "ovh-eu" or "ovh-ca"), OVH_APPLICATION_KEY, OVH_APPLICATION_SECRET, OVH_CONSUMER_KEY. func NewDNSProvider() (*DNSProvider, error) { - config, err := createConfigFromEnvVars() - if err != nil { - return nil, fmt.Errorf("ovh: %w", err) + config := NewDefaultConfig() + + // https://github.com/ovh/go-ovh/blob/6817886d12a8c5650794b28da635af9fcdfd1162/ovh/configuration.go#L105 + config.APIEndpoint = env.GetOrDefaultString(EnvEndpoint, "ovh-eu") + + config.ApplicationKey = env.GetOrFile(EnvApplicationKey) + config.ApplicationSecret = env.GetOrFile(EnvApplicationSecret) + config.ConsumerKey = env.GetOrFile(EnvConsumerKey) + + clientID := env.GetOrFile(EnvClientID) + clientSecret := env.GetOrFile(EnvClientSecret) + + if clientID != "" || clientSecret != "" { + config.OAuth2Config = &OAuth2Config{ + ClientID: clientID, + ClientSecret: clientSecret, + } } return NewDNSProviderConfig(config) @@ -125,8 +139,6 @@ func NewDNSProviderConfig(config *Config) (*DNSProvider, error) { return nil, fmt.Errorf("ovh: %w", err) } - client.Client = config.HTTPClient - return &DNSProvider{ config: config, client: client, @@ -222,94 +234,24 @@ func (d *DNSProvider) Timeout() (timeout, interval time.Duration) { return d.config.PropagationTimeout, d.config.PollingInterval } -func createConfigFromEnvVars() (*Config, error) { - firstAppKeyEnvVar := findFirstValuedEnvVar(EnvApplicationKey, EnvApplicationSecret, EnvConsumerKey) - firstOAuth2EnvVar := findFirstValuedEnvVar(EnvClientID, EnvClientSecret) - - if firstAppKeyEnvVar != "" && firstOAuth2EnvVar != "" { - return nil, fmt.Errorf("can't use both %s and %s at the same time", firstAppKeyEnvVar, firstOAuth2EnvVar) - } - - config := NewDefaultConfig() - - if firstOAuth2EnvVar != "" { - values, err := env.Get(EnvEndpoint, EnvClientID, EnvClientSecret) - if err != nil { - return nil, err - } - - config.APIEndpoint = values[EnvEndpoint] - config.OAuth2Config = &OAuth2Config{ - ClientID: values[EnvClientID], - ClientSecret: values[EnvClientSecret], - } - - return config, nil - } - - values, err := env.Get(EnvEndpoint, EnvApplicationKey, EnvApplicationSecret, EnvConsumerKey) - if err != nil { - return nil, err - } - - config.APIEndpoint = values[EnvEndpoint] - - config.ApplicationKey = values[EnvApplicationKey] - config.ApplicationSecret = values[EnvApplicationSecret] - config.ConsumerKey = values[EnvConsumerKey] - - return config, nil -} - -func findFirstValuedEnvVar(envVars ...string) string { - for _, envVar := range envVars { - if env.GetOrFile(envVar) != "" { - return envVar - } - } - - return "" -} - func newClient(config *Config) (*ovh.Client, error) { - if config.OAuth2Config == nil { - return newClientApplicationKey(config) + var client *ovh.Client + var err error + + switch { + case config.hasAppKeyAuth(): + client, err = ovh.NewClient(config.APIEndpoint, config.ApplicationKey, config.ApplicationSecret, config.ConsumerKey) + case config.OAuth2Config != nil: + client, err = ovh.NewOAuth2Client(config.APIEndpoint, config.OAuth2Config.ClientID, config.OAuth2Config.ClientSecret) + default: + client, err = ovh.NewDefaultClient() } - return newClientOAuth2(config) -} - -func newClientApplicationKey(config *Config) (*ovh.Client, error) { - if config.APIEndpoint == "" || config.ApplicationKey == "" || config.ApplicationSecret == "" || config.ConsumerKey == "" { - return nil, errors.New("credentials are missing") - } - - client, err := ovh.NewClient( - config.APIEndpoint, - config.ApplicationKey, - config.ApplicationSecret, - config.ConsumerKey, - ) if err != nil { return nil, fmt.Errorf("new client: %w", err) } - return client, nil -} - -func newClientOAuth2(config *Config) (*ovh.Client, error) { - if config.APIEndpoint == "" || config.OAuth2Config.ClientID == "" || config.OAuth2Config.ClientSecret == "" { - return nil, errors.New("credentials are missing") - } - - client, err := ovh.NewOAuth2Client( - config.APIEndpoint, - config.OAuth2Config.ClientID, - config.OAuth2Config.ClientSecret, - ) - if err != nil { - return nil, fmt.Errorf("new OAuth2 client: %w", err) - } + client.UserAgent = "go-acme/lego" return client, nil } diff --git a/providers/dns/ovh/ovh_test.go b/providers/dns/ovh/ovh_test.go index cac88e90..e735702f 100644 --- a/providers/dns/ovh/ovh_test.go +++ b/providers/dns/ovh/ovh_test.go @@ -34,16 +34,6 @@ func TestNewDNSProvider(t *testing.T) { EnvConsumerKey: "D", }, }, - { - desc: "application key: missing endpoint", - envVars: map[string]string{ - EnvEndpoint: "", - EnvApplicationKey: "B", - EnvApplicationSecret: "C", - EnvConsumerKey: "D", - }, - expected: "ovh: some credentials information are missing: OVH_ENDPOINT", - }, { desc: "application key: missing invalid endpoint", envVars: map[string]string{ @@ -62,7 +52,7 @@ func TestNewDNSProvider(t *testing.T) { EnvApplicationSecret: "C", EnvConsumerKey: "D", }, - expected: "ovh: some credentials information are missing: OVH_APPLICATION_KEY", + expected: "ovh: new client: invalid authentication config, both application_key and application_secret must be given", }, { desc: "application key: missing application secret", @@ -72,17 +62,7 @@ func TestNewDNSProvider(t *testing.T) { EnvApplicationSecret: "", EnvConsumerKey: "D", }, - expected: "ovh: some credentials information are missing: OVH_APPLICATION_SECRET", - }, - { - desc: "application key: missing consumer key", - envVars: map[string]string{ - EnvEndpoint: "ovh-eu", - EnvApplicationKey: "B", - EnvApplicationSecret: "C", - EnvConsumerKey: "", - }, - expected: "ovh: some credentials information are missing: OVH_CONSUMER_KEY", + expected: "ovh: new client: invalid authentication config, both application_key and application_secret must be given", }, { desc: "oauth2: success", @@ -99,7 +79,7 @@ func TestNewDNSProvider(t *testing.T) { EnvClientID: "E", EnvClientSecret: "", }, - expected: "ovh: some credentials information are missing: OVH_CLIENT_SECRET", + expected: "ovh: new client: invalid oauth2 config, both client_id and client_secret must be given", }, { desc: "oauth2: missing client ID", @@ -108,7 +88,7 @@ func TestNewDNSProvider(t *testing.T) { EnvClientID: "", EnvClientSecret: "F", }, - expected: "ovh: some credentials information are missing: OVH_CLIENT_ID", + expected: "ovh: new client: invalid oauth2 config, both client_id and client_secret must be given", }, { desc: "missing credentials", @@ -120,7 +100,7 @@ func TestNewDNSProvider(t *testing.T) { EnvClientID: "", EnvClientSecret: "", }, - expected: "ovh: some credentials information are missing: OVH_ENDPOINT,OVH_APPLICATION_KEY,OVH_APPLICATION_SECRET,OVH_CONSUMER_KEY", + expected: "ovh: new client: missing authentication information, you need to provide at least an application_key/application_secret or a client_id/client_secret", }, { desc: "mixed auth", @@ -132,7 +112,7 @@ func TestNewDNSProvider(t *testing.T) { EnvClientID: "E", EnvClientSecret: "F", }, - expected: "ovh: can't use both OVH_APPLICATION_KEY and OVH_CLIENT_ID at the same time", + expected: "ovh: can't use both authentication systems (ApplicationKey and OAuth2)", }, } @@ -182,7 +162,7 @@ func TestNewDNSProviderConfig(t *testing.T) { applicationKey: "B", applicationSecret: "C", consumerKey: "D", - expected: "ovh: credentials are missing", + expected: "ovh: new client: unknown endpoint '', consider checking 'Endpoints' list or using an URL", }, { desc: "application key: invalid api endpoint", @@ -198,7 +178,7 @@ func TestNewDNSProviderConfig(t *testing.T) { applicationKey: "", applicationSecret: "C", consumerKey: "D", - expected: "ovh: credentials are missing", + expected: "ovh: new client: invalid authentication config, both application_key and application_secret must be given", }, { desc: "application key: missing application secret", @@ -206,15 +186,7 @@ func TestNewDNSProviderConfig(t *testing.T) { applicationKey: "B", applicationSecret: "", consumerKey: "D", - expected: "ovh: credentials are missing", - }, - { - desc: "application key: missing consumer key", - apiEndpoint: "ovh-eu", - applicationKey: "B", - applicationSecret: "C", - consumerKey: "", - expected: "ovh: credentials are missing", + expected: "ovh: new client: invalid authentication config, both application_key and application_secret must be given", }, { desc: "oauth2: success", @@ -227,32 +199,32 @@ func TestNewDNSProviderConfig(t *testing.T) { apiEndpoint: "", clientID: "B", clientSecret: "C", - expected: "ovh: credentials are missing", + expected: "ovh: new client: unknown endpoint '', consider checking 'Endpoints' list or using an URL", }, { desc: "oauth2: invalid api endpoint", apiEndpoint: "foobar", clientID: "B", clientSecret: "C", - expected: "ovh: new OAuth2 client: unknown endpoint 'foobar', consider checking 'Endpoints' list or using an URL", + expected: "ovh: new client: unknown endpoint 'foobar', consider checking 'Endpoints' list or using an URL", }, { desc: "oauth2: missing client id", apiEndpoint: "ovh-eu", clientID: "", clientSecret: "C", - expected: "ovh: credentials are missing", + expected: "ovh: new client: invalid oauth2 config, both client_id and client_secret must be given", }, { desc: "oauth2: missing client secret", apiEndpoint: "ovh-eu", clientID: "B", clientSecret: "", - expected: "ovh: credentials are missing", + expected: "ovh: new client: invalid oauth2 config, both client_id and client_secret must be given", }, { desc: "missing credentials", - expected: "ovh: credentials are missing", + expected: "ovh: new client: missing authentication information, you need to provide at least an application_key/application_secret or a client_id/client_secret", }, { desc: "mixed auth",