ovh: allow to use ovh.conf file (#2216)

This commit is contained in:
Ludovic Fernandez 2024-06-26 14:44:05 +02:00 committed by GitHub
parent 4cbe9a2af5
commit fa0c05f5d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 43 additions and 129 deletions

View file

@ -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
}

View file

@ -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",