-
Notifications
You must be signed in to change notification settings - Fork 25
/
client.go
127 lines (108 loc) · 3.38 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package exoscale
import (
"fmt"
"log"
"net/http"
"runtime/debug"
exov2 "github.com/exoscale/egoscale/v2"
"github.com/exoscale/terraform-provider-exoscale/version"
cleanhttp "github.com/hashicorp/go-cleanhttp"
retryablehttp "github.com/hashicorp/go-retryablehttp"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging"
providerConfig "github.com/exoscale/terraform-provider-exoscale/pkg/provider/config"
)
const (
DefaultEnvironment = "api"
)
var UserAgent = fmt.Sprintf("Exoscale-Terraform-Provider/%s (%s) Terraform-SDK/%s Terraform-framework/%s %s",
version.Version,
version.Commit,
getModVersion("github.com/hashicorp/terraform-plugin-sdk/v2"),
getModVersion("github.com/hashicorp/terraform-plugin-framework"),
exov2.UserAgent)
func getModVersion(module string) string {
// Read Build info
bi, ok := debug.ReadBuildInfo()
if ok {
for _, mod := range bi.Deps {
if mod.Path == module {
return mod.Version
}
}
}
return "err"
}
func getConfig(meta interface{}) providerConfig.BaseConfig {
t := meta.(map[string]interface{})
return t["config"].(providerConfig.BaseConfig)
}
func getClient(meta interface{}) *exov2.Client {
config := getConfig(meta)
httpClient := cleanhttp.DefaultPooledClient()
httpClient.Transport = &defaultTransport{next: httpClient.Transport}
if logging.IsDebugOrHigher() {
httpClient.Transport = logging.NewSubsystemLoggingHTTPTransport(
"exoscale",
httpClient.Transport,
)
}
// During the Exoscale API V1 -> V2 transition, we need to initialize the
// V2 client independently from the V1 client because of HTTP middleware
// (http.Transport) clashes.
// This can be removed once the only API used is V2.
clientExoV2, err := exov2.NewClient(
config.Key,
config.Secret,
exov2.ClientOptWithTimeout(config.Timeout),
exov2.ClientOptWithHTTPClient(func() *http.Client {
rc := retryablehttp.NewClient()
rc.Logger = LeveledTFLogger{Verbose: logging.IsDebugOrHigher()}
hc := rc.StandardClient()
if logging.IsDebugOrHigher() {
hc.Transport = logging.NewSubsystemLoggingHTTPTransport("exoscale", hc.Transport)
}
return hc
}()),
)
if err != nil {
panic(fmt.Sprintf("unable to initialize Exoscale API V2 client: %v", err))
}
return clientExoV2
}
func getEnvironment(meta interface{}) string {
config := getConfig(meta)
if config.Environment == "" {
return DefaultEnvironment
}
return config.Environment
}
type defaultTransport struct {
next http.RoundTripper
}
// RoundTrip executes a single HTTP transaction while augmenting requests with custom headers.
func (t *defaultTransport) RoundTrip(req *http.Request) (*http.Response, error) {
req.Header.Add("User-Agent", UserAgent)
resp, err := t.next.RoundTrip(req)
if err != nil {
return nil, err
}
return resp, nil
}
// LeveledTFLogger is a thin wrapper around stdlib.log that satisfies retryablehttp.LeveledLogger interface.
type LeveledTFLogger struct {
Verbose bool
}
func (l LeveledTFLogger) Error(msg string, keysAndValues ...interface{}) {
log.Println("[ERROR]", msg, keysAndValues)
}
func (l LeveledTFLogger) Info(msg string, keysAndValues ...interface{}) {
log.Println("[INFO]", msg, keysAndValues)
}
func (l LeveledTFLogger) Debug(msg string, keysAndValues ...interface{}) {
if l.Verbose {
log.Println("[DEBUG]", msg, keysAndValues)
}
}
func (l LeveledTFLogger) Warn(msg string, keysAndValues ...interface{}) {
log.Println("[WARN]", msg, keysAndValues)
}