From df9f939b0d2075b46bf7db093a382e0ea2d7ac5b Mon Sep 17 00:00:00 2001 From: Brice Figureau Date: Sat, 25 Nov 2023 11:05:17 +0100 Subject: [PATCH] Allow ovh provider to connect to other endpoints than EU (#2625) This introduces the `endpoint` provider configuration parameter. If not provided the provider will connect to the EU region for backward compatibility. The `endpoint` can be set to `eu`, `us` or `ca` depending on the OVH region the use wants to manage domains and zones in. It can also be set to any arbitrary URL for future OVH regions. --- documentation/providers/ovh.md | 21 +++++++++++-- integrationTest/providers.json | 3 +- providers/ovh/ovhProvider.go | 18 ++++++++++- providers/ovh/ovhProvider_test.go | 51 +++++++++++++++++++++++++++++++ 4 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 providers/ovh/ovhProvider_test.go diff --git a/documentation/providers/ovh.md b/documentation/providers/ovh.md index 70d0153ede..dd19ccd7c6 100644 --- a/documentation/providers/ovh.md +++ b/documentation/providers/ovh.md @@ -1,7 +1,7 @@ ## Configuration To use this provider, add an entry to `creds.json` with `TYPE` set to `OVH` -along with a OVH app-key, app-secret-key and consumer-key. +along with a OVH app-key, app-secret-key, consumer-key and optionally endpoint. Example: @@ -12,7 +12,8 @@ Example: "TYPE": "OVH", "app-key": "your app key", "app-secret-key": "your app secret key", - "consumer-key": "your consumer key" + "consumer-key": "your consumer key", + "endpoint": "eu" } } ``` @@ -20,6 +21,13 @@ Example: See [the Activation section](#activation) for details on obtaining these credentials. +`endpoint` can take the following values: + +* `eu` (the default), for connecting to the OVH European endpoint +* `ca` for connecting to OVH Canada API endpoint +* `us` for connecting to the OVH USA API endpoint +* an url for connecting to a different endpoint than the ones above + ## Metadata This provider does not recognize any special metadata fields unique to OVH. @@ -58,7 +66,7 @@ To obtain the OVH keys, one need to register an app at OVH by following the [OVH API Getting Started](https://docs.ovh.com/gb/en/customer/first-steps-with-ovh-api/) It consist in declaring the app at https://eu.api.ovh.com/createApp/ -which gives the `app-key` and `app-secret-key`. +which gives the `app-key` and `app-secret-key`. If your domains and zones are located in another region, see below for the correct url to use. Once done, to obtain the `consumer-key` it is necessary to authorize the just created app to access the data in a specific account: @@ -115,6 +123,13 @@ authorizing it to access your zones and domains. Do not forget to fill the `consumer-key` of your `creds.json`. +For accessing the other international endpoints such as US and CA, change the `https://eu.api.ovh.com` used above to one of the following: + +* Canada endpoint: `https://ca.api.ovh.com` +* US endpoint: `https://api.us.ovhcloud.com` + +Do not forget to fill the `endpoint` of your `creds.json` if you use an endpoint different than the EU one. + ## New domains If a domain does not exist in your OVH account, DNSControl diff --git a/integrationTest/providers.json b/integrationTest/providers.json index 019876b8d5..ac55cbe51c 100644 --- a/integrationTest/providers.json +++ b/integrationTest/providers.json @@ -232,7 +232,8 @@ "app-key": "$OVH_APP_KEY", "app-secret-key": "$OVH_APP_SECRET_KEY", "consumer-key": "$OVH_CONSUMER_KEY", - "domain": "$OVH_DOMAIN" + "domain": "$OVH_DOMAIN", + "endpoint": "$OVH_ENDPOINT" }, "PACKETFRAME": { "TYPE": "PACKETFRAME", diff --git a/providers/ovh/ovhProvider.go b/providers/ovh/ovhProvider.go index d3db32430b..69b0dc8f24 100644 --- a/providers/ovh/ovhProvider.go +++ b/providers/ovh/ovhProvider.go @@ -34,7 +34,7 @@ var features = providers.DocumentationNotes{ func newOVH(m map[string]string, metadata json.RawMessage) (*ovhProvider, error) { appKey, appSecretKey, consumerKey := m["app-key"], m["app-secret-key"], m["consumer-key"] - c, err := ovh.NewClient(ovh.OvhEU, appKey, appSecretKey, consumerKey) + c, err := ovh.NewClient(getOVHEndpoint(m), appKey, appSecretKey, consumerKey) if c == nil { return nil, err } @@ -46,6 +46,22 @@ func newOVH(m map[string]string, metadata json.RawMessage) (*ovhProvider, error) return ovh, nil } +func getOVHEndpoint(params map[string]string) string { + if ep, ok := params["endpoint"]; ok && ep != "" { + switch strings.ToLower(ep) { + case "eu": + return ovh.OvhEU + case "ca": + return ovh.OvhCA + case "us": + return ovh.OvhUS + default: + return ep + } + } + return ovh.OvhEU +} + func newDsp(conf map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) { return newOVH(conf, metadata) } diff --git a/providers/ovh/ovhProvider_test.go b/providers/ovh/ovhProvider_test.go new file mode 100644 index 0000000000..e87a9928dc --- /dev/null +++ b/providers/ovh/ovhProvider_test.go @@ -0,0 +1,51 @@ +package ovh + +import ( + "testing" + + "github.com/ovh/go-ovh/ovh" +) + +func Test_getOVHEndpoint(t *testing.T) { + tests := []struct { + name string + endpoint string + want string + }{ + { + "default to EU", "", ovh.OvhEU, + }, + { + "default to EU if omitted", "omitted", ovh.OvhEU, + }, + { + "set to EU", "eu", ovh.OvhEU, + }, + { + "set to CA", "ca", ovh.OvhCA, + }, + { + "set to US", "eu", ovh.OvhUS, + }, + { + "case insensitive", "Eu", ovh.OvhEU, + }, + { + "case insensitive ca", "CA", ovh.OvhCA, + }, + { + "arbitratry", "https://blah", "https://blah", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + params := make(map[string]string) + if tt.endpoint != "" && tt.endpoint != "omitted" { + params["endpoint"] = tt.endpoint + } + if got := getOVHEndpoint(params); got != tt.want { + t.Errorf("getOVHEndpoint() = %v, want %v", got, tt.want) + } + }) + } +}