Skip to content

Commit

Permalink
ovh: allow to use ovh.conf file
Browse files Browse the repository at this point in the history
  • Loading branch information
ldez committed Jun 21, 2024
1 parent 834a908 commit 9a7a313
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 128 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,5 @@ require (
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace github.com/ovh/go-ovh => github.com/ldez/go-ovh v1.4.2-0.20240621144634-e57d43b43c1c
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,8 @@ github.com/labbsr0x/goh v1.0.1 h1:97aBJkDjpyBZGPbQuOK5/gHcSFbcr5aRsq3RSRJFpPk=
github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c027w=
github.com/labstack/echo/v4 v4.6.3/go.mod h1:Hk5OiHj0kDqmFq7aHe7eDqI7CUhuCrfpupQtLGGLm7A=
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/ldez/go-ovh v1.4.2-0.20240621144634-e57d43b43c1c h1:R+W37CyFOLz4xF2M3TRz/xflvvrJGMihgKNbajqrPYw=
github.com/ldez/go-ovh v1.4.2-0.20240621144634-e57d43b43c1c/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/lestrrat-go/backoff/v2 v2.0.8/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
Expand Down Expand Up @@ -526,8 +528,6 @@ github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:Ff
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU=
github.com/oracle/oci-go-sdk/v65 v65.63.1 h1:dYL7sk9L1+C9LCmoq+zjPMNteuJJfk54YExq/4pV9xQ=
github.com/oracle/oci-go-sdk/v65 v65.63.1/go.mod h1:IBEV9l1qBzUpo7zgGaRUhbB05BVfcDGYRFBCPlTcPp0=
github.com/ovh/go-ovh v1.5.1 h1:P8O+7H+NQuFK9P/j4sFW5C0fvSS2DnHYGPwdVCp45wI=
github.com/ovh/go-ovh v1.5.1/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
Expand Down
117 changes: 33 additions & 84 deletions providers/dns/ovh/ovh.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -222,94 +236,29 @@ 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 ""
}

// Inspired by:
// - NewClient: https://github.com/ovh/go-ovh/blob/6817886d12a8c5650794b28da635af9fcdfd1162/ovh/ovh.go#L103
// - NewOAuth2Client: https://github.com/ovh/go-ovh/blob/6817886d12a8c5650794b28da635af9fcdfd1162/ovh/ovh.go#L132
func newClient(config *Config) (*ovh.Client, error) {
if config.OAuth2Config == nil {
return newClientApplicationKey(config)
client := ovh.Client{
AppKey: config.ApplicationKey,
AppSecret: config.ApplicationSecret,
ConsumerKey: config.ConsumerKey,
Client: &http.Client{},
Timeout: ovh.DefaultTimeout,
UserAgent: "go-acme/lego",
}

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")
if config.OAuth2Config != nil {
client.ClientID = config.OAuth2Config.ClientID
client.ClientSecret = config.OAuth2Config.ClientSecret
}

client, err := ovh.NewClient(
config.APIEndpoint,
config.ApplicationKey,
config.ApplicationSecret,
config.ConsumerKey,
)
// Get and check the configuration
err := client.LoadConfig(config.APIEndpoint)
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)
}

return client, nil
return &client, nil
}
56 changes: 14 additions & 42 deletions providers/dns/ovh/ovh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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 one of the following: application_key/application_secret, client_id/client_secret, or access_token",
},
{
desc: "mixed auth",
Expand All @@ -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)",
},
}

Expand Down Expand Up @@ -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",
Expand All @@ -198,23 +178,15 @@ 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",
apiEndpoint: "ovh-eu",
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",
Expand All @@ -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 one of the following: application_key/application_secret, client_id/client_secret, or access_token",
},
{
desc: "mixed auth",
Expand Down

0 comments on commit 9a7a313

Please sign in to comment.