Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Generated client v2 API #477

Merged
merged 11 commits into from
Apr 29, 2020
105 changes: 89 additions & 16 deletions datadog/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import (
"log"
"net/url"
"runtime"
"strings"

"github.com/DataDog/datadog-api-client-go/api/v1/datadog"
datadogV1 "github.com/DataDog/datadog-api-client-go/api/v1/datadog"
datadogV2 "github.com/DataDog/datadog-api-client-go/api/v2/datadog"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/terraform-plugin-sdk/helper/logging"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
Expand Down Expand Up @@ -76,8 +76,10 @@ func Provider() terraform.ResourceProvider {
//ProviderConfiguration contains the initialized API clients to communicate with the Datadog API
type ProviderConfiguration struct {
CommunityClient *datadogCommunity.Client
DatadogClientV1 *datadog.APIClient
Auth context.Context
DatadogClientV1 *datadogV1.APIClient
DatadogClientV2 *datadogV2.APIClient
AuthV1 context.Context
AuthV2 context.Context
}

func providerConfigure(d *schema.ResourceData) (interface{}, error) {
Expand Down Expand Up @@ -105,11 +107,11 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
}
log.Printf("[INFO] Datadog Client successfully validated.")

// Initialize the official Datadog client
auth := context.WithValue(
// Initialize the official Datadog V1 API client
authV1 := context.WithValue(
context.Background(),
datadog.ContextAPIKeys,
map[string]datadog.APIKey{
datadogV1.ContextAPIKeys,
map[string]datadogV1.APIKey{
"apiKeyAuth": {
Key: d.Get("api_key").(string),
},
Expand All @@ -118,19 +120,75 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
},
},
)
config := datadog.NewConfiguration()
configV1 := datadogV1.NewConfiguration()
if apiURL := d.Get("api_url").(string); apiURL != "" {
if strings.Contains(apiURL, "datadoghq.eu") {
auth = context.WithValue(auth, datadog.ContextServerVariables, map[string]string{
parsedApiUrl, parseErr := url.Parse(apiURL)
if parseErr != nil {
return nil, fmt.Errorf(`invalid API Url : %v`, parseErr)
}
if parsedApiUrl.Host == "" || parsedApiUrl.Scheme == "" {
return nil, fmt.Errorf(`missing protocol or host : %v`, apiURL)
}
// Set site to "datadoghq.eu" on ServerIndex{0} if Datadog EU API URL is passed.
// If custom api url (not datadoghq.eu or datadoghq.com) is passed, set the api name and protocol on ServerIndex{-1}
if parsedApiUrl.Host == "datadoghq.eu" {
authV1 = context.WithValue(authV1, datadogV1.ContextServerVariables, map[string]string{
"site": "datadoghq.eu",
})
skarimo marked this conversation as resolved.
Show resolved Hide resolved
} else if parsedApiUrl.Host != "datadoghq.com" {
authV1 = context.WithValue(authV1, datadogV1.ContextServerIndex, len(configV1.Servers)-1)
skarimo marked this conversation as resolved.
Show resolved Hide resolved
authV1 = context.WithValue(authV1, datadogV1.ContextServerVariables, map[string]string{
"name": parsedApiUrl.Host,
"protocol": parsedApiUrl.Scheme,
})
}
}
datadogClientV1 := datadogV1.NewAPIClient(configV1)

// Initialize the official Datadog V2 API client
authV2 := context.WithValue(
context.Background(),
datadogV2.ContextAPIKeys,
map[string]datadogV2.APIKey{
"apiKeyAuth": {
Key: d.Get("api_key").(string),
},
"appKeyAuth": {
Key: d.Get("app_key").(string),
},
},
)
configV2 := datadogV2.NewConfiguration()
if apiURL := d.Get("api_url").(string); apiURL != "" {
parsedApiUrl, parseErr := url.Parse(apiURL)
if parseErr != nil {
return nil, fmt.Errorf(`invalid API Url : %v`, parseErr)
}
if parsedApiUrl.Host == "" || parsedApiUrl.Scheme == "" {
return nil, fmt.Errorf(`missing protocol or host : %v`, apiURL)
}
// Set site to "datadoghq.eu" on ServerIndex{0} if Datadog EU API URL is passed.
// If custom api url (not datadoghq.eu or datadoghq.com) is passed, set the api name and protocol on ServerIndex{-1}
if parsedApiUrl.Host == "api.datadoghq.eu" {
authV2 = context.WithValue(authV2, datadogV2.ContextServerVariables, map[string]string{
"site": "datadoghq.eu",
})
} else if parsedApiUrl.Host != "api.datadoghq.com" {
authV2 = context.WithValue(authV2, datadogV2.ContextServerIndex, len(configV2.Servers)-1)
authV2 = context.WithValue(authV2, datadogV2.ContextServerVariables, map[string]string{
"name": parsedApiUrl.Host,
"protocol": parsedApiUrl.Scheme,
})
}
}
datadogClient := datadog.NewAPIClient(config)
datadogClientV2 := datadogV2.NewAPIClient(configV2)

return &ProviderConfiguration{
CommunityClient: communityClient,
DatadogClientV1: datadogClient,
Auth: auth,
DatadogClientV1: datadogClientV1,
DatadogClientV2: datadogClientV2,
AuthV1: authV1,
AuthV2: authV2,
}, nil
}

Expand All @@ -139,8 +197,23 @@ func translateClientError(err error, msg string) error {
msg = "an error occurred"
}

if _, ok := err.(datadog.GenericOpenAPIError); ok {
return fmt.Errorf(msg+": %s", err.Error())
if apiErr, ok := err.(datadogV1.GenericOpenAPIError); ok {
return fmt.Errorf(msg+": %v: %s", err, apiErr.Body())
}
if errUrl, ok := err.(*url.Error); ok {
return fmt.Errorf(msg+" (url.Error): %s", errUrl)
}

return fmt.Errorf(msg+": %s", err.Error())
}

func translateClientErrorV2(err error, msg string) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not have everything in one method?

if msg == "" {
msg = "an error occurred"
}

if apiErr, ok := err.(datadogV2.GenericOpenAPIError); ok {
fmt.Errorf(msg+": %v: %s", err, apiErr.Body())
}
if errUrl, ok := err.(*url.Error); ok {
return fmt.Errorf(msg+" (url.Error): %s", errUrl)
Expand Down
89 changes: 73 additions & 16 deletions datadog/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import (
"net/url"
"os"
"runtime"
"strings"
"testing"
"time"

"github.com/DataDog/datadog-api-client-go/api/v1/datadog"
datadogV1 "github.com/DataDog/datadog-api-client-go/api/v1/datadog"
datadogV2 "github.com/DataDog/datadog-api-client-go/api/v2/datadog"
"github.com/dnaeon/go-vcr/cassette"
"github.com/dnaeon/go-vcr/recorder"
"github.com/hashicorp/go-cleanhttp"
Expand Down Expand Up @@ -128,36 +128,93 @@ func testProviderConfigure(r *recorder.Recorder) schema.ConfigureFunc {
communityClient.ExtraHeader["User-Agent"] = fmt.Sprintf("Datadog/%s/terraform (%s)", version.ProviderVersion, runtime.Version())

// Initialize the official datadog client
auth := context.WithValue(
authV1 := context.WithValue(
context.Background(),
datadog.ContextAPIKeys,
map[string]datadog.APIKey{
"apiKeyAuth": datadog.APIKey{
datadogV1.ContextAPIKeys,
map[string]datadogV1.APIKey{
"apiKeyAuth": datadogV1.APIKey{
Key: d.Get("api_key").(string),
},
"appKeyAuth": datadog.APIKey{
"appKeyAuth": datadogV1.APIKey{
Key: d.Get("app_key").(string),
},
},
)
//Datadog V1 API config.HTTPClient
configV1 := datadogV1.NewConfiguration()
configV1.Debug = true
configV1.HTTPClient = c
if apiURL := d.Get("api_url").(string); apiURL != "" {
parsedApiUrl, parseErr := url.Parse(apiURL)
if parseErr != nil {
return nil, fmt.Errorf(`invalid API Url : %v`, parseErr)
}
if parsedApiUrl.Host == "" || parsedApiUrl.Scheme == "" {
return nil, fmt.Errorf(`missing protocol or host : %v`, apiURL)
}
// Set site to "datadoghq.eu" on ServerIndex{0} if Datadog EU API URL is passed.
// If custom api url (not datadoghq.eu or datadoghq.com) is passed, set the api name and protocol on ServerIndex{-1}
if parsedApiUrl.Host == "datadoghq.eu" {
authV1 = context.WithValue(authV1, datadogV1.ContextServerVariables, map[string]string{
"site": "datadoghq.eu",
})
} else if parsedApiUrl.Host != "datadoghq.com" {
authV1 = context.WithValue(authV1, datadogV1.ContextServerIndex, len(configV1.Servers)-1)
authV1 = context.WithValue(authV1, datadogV1.ContextServerVariables, map[string]string{
"name": parsedApiUrl.Host,
"protocol": parsedApiUrl.Scheme,
})
}
}
datadogClientV1 := datadogV1.NewAPIClient(configV1)

//config.HTTPClient
config := datadog.NewConfiguration()
config.Debug = true
config.HTTPClient = c
// Initialize the official datadog v2 API client
authV2 := context.WithValue(
context.Background(),
datadogV2.ContextAPIKeys,
map[string]datadogV2.APIKey{
"apiKeyAuth": datadogV2.APIKey{
Key: d.Get("api_key").(string),
},
"appKeyAuth": datadogV2.APIKey{
Key: d.Get("app_key").(string),
},
},
)
//Datadog V2 API config.HTTPClient
configV2 := datadogV2.NewConfiguration()
configV2.Debug = true
configV2.HTTPClient = c
if apiURL := d.Get("api_url").(string); apiURL != "" {
if strings.Contains(apiURL, "datadoghq.eu") {
auth = context.WithValue(auth, datadog.ContextServerVariables, map[string]string{
parsedApiUrl, parseErr := url.Parse(apiURL)
if parseErr != nil {
return nil, fmt.Errorf(`invalid API Url : %v`, parseErr)
}
if parsedApiUrl.Host == "" || parsedApiUrl.Scheme == "" {
return nil, fmt.Errorf(`missing protocol or host : %v`, apiURL)
}
// Set site to "datadoghq.eu" on ServerIndex{0} if Datadog EU API URL is passed.
// If custom api url (not datadoghq.eu or datadoghq.com) is passed, set the api name and protocol on ServerIndex{-1}
if parsedApiUrl.Host == "api.datadoghq.eu" {
authV2 = context.WithValue(authV2, datadogV2.ContextServerVariables, map[string]string{
"site": "datadoghq.eu",
})
} else if parsedApiUrl.Host != "api.datadoghq.com" {
authV2 = context.WithValue(authV2, datadogV2.ContextServerIndex, len(configV2.Servers)-1)
authV2 = context.WithValue(authV2, datadogV2.ContextServerVariables, map[string]string{
"name": parsedApiUrl.Host,
"protocol": parsedApiUrl.Scheme,
})
}
}
datadogClient := datadog.NewAPIClient(config)
datadogClientV2 := datadogV2.NewAPIClient(configV2)

return &ProviderConfiguration{
CommunityClient: communityClient,
DatadogClientV1: datadogClient,
Auth: auth,
DatadogClientV1: datadogClientV1,
DatadogClientV2: datadogClientV2,
AuthV1: authV1,
AuthV2: authV2,
}, nil
}
}
Expand Down