@@ -11,25 +11,120 @@ package okms
11
11
12
12
import (
13
13
"context"
14
+ "crypto/tls"
14
15
"errors"
15
16
"fmt"
17
+ "io"
16
18
"net/http"
19
+ "net/http/httputil"
20
+ "os"
17
21
"reflect"
18
22
"strings"
23
+ "time"
19
24
20
25
"github.com/google/uuid"
26
+ "github.com/hashicorp/go-retryablehttp"
21
27
"github.com/ovh/okms-sdk-go/internal"
22
28
"github.com/ovh/okms-sdk-go/types"
23
29
)
24
30
31
+ const DefaultHTTPClientTimeout = 30 * time .Second
32
+
25
33
// RestAPIClient is the main client to the KMS rest api.
26
34
type RestAPIClient struct {
27
35
inner internal.ClientWithResponsesInterface
28
36
customHeaders map [string ]string
29
37
}
30
38
31
- // NewRestAPIClientWithHttp creates and initialize a new HTTP connection to the KMS at url `endpoint`
32
- // using the provided [http.Client].
39
+ // LeveledLogger represents loggers that can be used inside the client.
40
+ type LeveledLogger retryablehttp.LeveledLogger
41
+
42
+ // ClientConfig is used to configure Rest clients created using NewRestAPIClient().
43
+ type ClientConfig struct {
44
+ Timeout * time.Duration
45
+ Retry * RetryConfig
46
+ Logger LeveledLogger
47
+ TlsCfg * tls.Config
48
+ Middleware func (http.RoundTripper ) http.RoundTripper
49
+ }
50
+
51
+ type RetryConfig struct {
52
+ RetryMax int
53
+ RetryWaitMin time.Duration
54
+ RetryWaitMax time.Duration
55
+ }
56
+
57
+ type debugTransport struct {
58
+ next http.RoundTripper
59
+ out io.Writer
60
+ }
61
+
62
+ // RoundTrip implements http.RoundTripper.
63
+ func (t * debugTransport ) RoundTrip (r * http.Request ) (* http.Response , error ) {
64
+ data , _ := httputil .DumpRequestOut (r , true )
65
+ fmt .Fprintf (os .Stderr , "REQUEST:\n %s\n " , data )
66
+ resp , err := t .next .RoundTrip (r )
67
+ if err != nil {
68
+ return resp , err
69
+ }
70
+ data , _ = httputil .DumpResponse (resp , true )
71
+ fmt .Fprintf (os .Stderr , "RESPONSE:\n %s\n " , data )
72
+ return resp , nil
73
+ }
74
+
75
+ // DebugTransport creates an http client middleware that will dump all the HTTP resquests and
76
+ // responses to the giver io.Writer. It can be passed to ClientConfig.Middleware.
77
+ func DebugTransport (out io.Writer ) func (http.RoundTripper ) http.RoundTripper {
78
+ return func (rt http.RoundTripper ) http.RoundTripper {
79
+ if rt == nil {
80
+ rt = http .DefaultTransport
81
+ }
82
+ if out == nil {
83
+ out = os .Stderr
84
+ }
85
+ return & debugTransport {
86
+ next : rt ,
87
+ out : out ,
88
+ }
89
+ }
90
+ }
91
+
92
+ // NewRestAPIClient creates and initializes a new HTTP connection to the KMS at url `endpoint`
93
+ // using the provided client configuration. It allows configuring retries, timeouts and loggers.
94
+ func NewRestAPIClient (endpoint string , clientCfg ClientConfig ) (* RestAPIClient , error ) {
95
+ client := retryablehttp .NewClient ()
96
+ client .HTTPClient .Timeout = DefaultHTTPClientTimeout
97
+ client .Logger = nil
98
+
99
+ client .HTTPClient .Transport .(* http.Transport ).TLSClientConfig = clientCfg .TlsCfg
100
+ if clientCfg .Logger != nil {
101
+ client .Logger = clientCfg .Logger
102
+ }
103
+
104
+ if clientCfg .Timeout != nil {
105
+ client .HTTPClient .Timeout = * clientCfg .Timeout
106
+ }
107
+
108
+ if clientCfg .Retry != nil {
109
+ client .RetryMax = clientCfg .Retry .RetryMax
110
+ if clientCfg .Retry .RetryWaitMin > 0 {
111
+ client .RetryWaitMin = clientCfg .Retry .RetryWaitMin
112
+ }
113
+ if clientCfg .Retry .RetryWaitMax > 0 {
114
+ client .RetryWaitMax = clientCfg .Retry .RetryWaitMax
115
+ }
116
+ }
117
+ if clientCfg .Middleware != nil {
118
+ client .HTTPClient .Transport = clientCfg .Middleware (client .HTTPClient .Transport )
119
+ }
120
+
121
+ client .ErrorHandler = retryablehttp .PassthroughErrorHandler
122
+
123
+ return NewRestAPIClientWithHttp (endpoint , client .StandardClient ())
124
+ }
125
+
126
+ // NewRestAPIClientWithHttp is a lower level constructor to create and initialize a new HTTP
127
+ // connection to the KMS at url `endpoint` using the provided [http.Client].
33
128
//
34
129
// The client must be configured with an appropriate tls.Config using client TLS certificates for authentication.
35
130
func NewRestAPIClientWithHttp (endpoint string , c * http.Client ) (* RestAPIClient , error ) {
0 commit comments