Codebase list golang-github-ovh-go-ovh / 7a6adba
Import upstream version 1.3.0+ds Debian Janitor 1 year, 3 months ago
8 changed file(s) with 67 addition(s) and 47 deletion(s). Raw diff Collapse all Expand all
+0
-3
.gitignore less more
0 # Temporary edit files
1 *.swp
2 *~
0 @amstuta
1 @mxpetit
2 @rbeuque74
99 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
1010 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
1111 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
12 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384 h1:TFlARGu6Czu1z7q93HTxcP1P+/ZFC/IKythI5RzrnRg=
1312 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
1413 gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww=
1514 gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
136136 ValidationURL: "fakeURL",
137137 }
138138
139 expected := fmt.Sprintf("CK: \"ck\"\nStatus: \"pending\"\nValidation URL: \"fakeURL\"\n")
140 got := fmt.Sprintf("%s", ckValidationState)
139 expected := "CK: \"ck\"\nStatus: \"pending\"\nValidation URL: \"fakeURL\"\n"
140 got := fmt.Sprint(ckValidationState)
141141
142142 if got != expected {
143143 t.Errorf("expected %q, got %q", expected, got)
33
44 // APIError represents an error that can occurred while calling the API.
55 type APIError struct {
6 // Error class
7 Class string `json:"class,omitempty"`
68 // Error message.
7 Message string
9 Message string `json:"message"`
10 // Error details
11 Details map[string]string `json:"details,omitempty"`
812 // HTTP code.
913 Code int
1014 // ID of the request
1216 }
1317
1418 func (err *APIError) Error() string {
15 return fmt.Sprintf("Error %d: %q", err.Code, err.Message)
19 if err.Class == "" {
20 return fmt.Sprintf("HTTP Error %d: %q", err.Code, err.Message)
21 }
22
23 return fmt.Sprintf("HTTP Error %d: %s: %q (X-OVH-Query-Id: %s)", err.Code, err.Class, err.Message, err.QueryID)
1624 }
1111 Message: "Bad request",
1212 }
1313
14 expected := `Error 400: "Bad request"`
14 expected := `HTTP Error 400: "Bad request"`
1515 got := fmt.Sprintf("%s", err)
1616
1717 if got != expected {
1818 t.Errorf("expected %q, got %q", expected, got)
1919 }
20
21 err.Class = "CartAlreadyExists"
22 err.Code = http.StatusConflict
23 err.Message = `the cart id "foobar" already exists`
24 err.QueryID = "EU.ext-99.foobar"
25
26 expected = `HTTP Error 409: CartAlreadyExists: "the cart id \"foobar\" already exists" (X-OVH-Query-Id: EU.ext-99.foobar)`
27 got = fmt.Sprintf("%s", err)
28
29 if got != expected {
30 t.Errorf("expected %q, got %q", expected, got)
31 }
2032 }
1010 "io/ioutil"
1111 "net/http"
1212 "strconv"
13 "sync"
13 "sync/atomic"
1414 "time"
1515 )
1616
4141
4242 // Errors
4343 var (
44 ErrAPIDown = errors.New("go-vh: the OVH API is down, it does't respond to /time anymore")
44 ErrAPIDown = errors.New("go-ovh: the OVH API is not reachable: failed to get /auth/time response")
4545 )
4646
4747 // Client represents a client to call the OVH API
6969 // Ensures that the timeDelta function is only ran once
7070 // sync.Once would consider init done, even in case of error
7171 // hence a good old flag
72 timeDeltaMutex *sync.Mutex
73 timeDeltaDone bool
74 timeDelta time.Duration
75 Timeout time.Duration
72 timeDelta atomic.Value
73
74 // Timeout configures the maximum duration to wait for an API requests to complete
75 Timeout time.Duration
76
77 // UserAgent configures the user-agent indication that will be sent in the requests to OVHcloud API
78 UserAgent string
7679 }
7780
7881 // NewClient represents a new client to call the API
7982 func NewClient(endpoint, appKey, appSecret, consumerKey string) (*Client, error) {
8083 client := Client{
81 AppKey: appKey,
82 AppSecret: appSecret,
83 ConsumerKey: consumerKey,
84 Client: &http.Client{},
85 timeDeltaMutex: &sync.Mutex{},
86 timeDeltaDone: false,
87 Timeout: time.Duration(DefaultTimeout),
84 AppKey: appKey,
85 AppSecret: appSecret,
86 ConsumerKey: consumerKey,
87 Client: &http.Client{},
88 Timeout: time.Duration(DefaultTimeout),
8889 }
8990
9091 // Get and check the configuration
213214 return c.CallAPIWithContext(ctx, "DELETE", url, nil, resType, false)
214215 }
215216
216 // timeDelta returns the time delta between the host and the remote API
217 // timeDelta returns the time delta between the host and the remote API
217218 func (c *Client) getTimeDelta() (time.Duration, error) {
218
219 if !c.timeDeltaDone {
220 // Ensure only one thread is updating
221 c.timeDeltaMutex.Lock()
222
223 // Ensure that the mutex will be released on return
224 defer c.timeDeltaMutex.Unlock()
225
226 // Did we wait ? Maybe no more needed
227 if !c.timeDeltaDone {
228 ovhTime, err := c.getTime()
229 if err != nil {
230 return 0, err
231 }
232
233 c.timeDelta = time.Since(*ovhTime)
234 c.timeDeltaDone = true
235 }
236 }
237
238 return c.timeDelta, nil
219 d, ok := c.timeDelta.Load().(time.Duration)
220 if ok {
221 return d, nil
222 }
223
224 ovhTime, err := c.getTime()
225 if err != nil {
226 return 0, err
227 }
228
229 d = time.Since(*ovhTime)
230 c.timeDelta.Store(d)
231
232 return d, nil
239233 }
240234
241235 // getTime t returns time from for a given api client endpoint
317311 // Send the request with requested timeout
318312 c.Client.Timeout = c.Timeout
319313
314 if c.UserAgent != "" {
315 req.Header.Set("User-Agent", "github.com/ovh/go-ovh ("+c.UserAgent+")")
316 } else {
317 req.Header.Set("User-Agent", "github.com/ovh/go-ovh")
318 }
319
320320 return req, nil
321321 }
322322
1010 "reflect"
1111 "strconv"
1212 "strings"
13 "sync/atomic"
1314 "testing"
1415 "time"
1516 "unicode"
7071
7172 // Create client
7273 client, _ := NewClient(ts.URL, MockApplicationKey, MockApplicationSecret, MockConsumerKey)
73 client.timeDeltaDone = true
74 client.timeDelta.Store(time.Duration(0))
7475
7576 return ts, client
7677 }
401402 if err != nil {
402403 t.Fatalf("Client.UnmarshalResponse should be able to decode the body")
403404 }
404 if "1234567890" != fmt.Sprint(output["orderId"]) {
405 if fmt.Sprint(output["orderId"]) != "1234567890" {
405406 t.Fatalf("Client.UnmarshalResponse should unmarshal long integer as json.Number instead of float64, stringified incorrectly")
406407 }
407408
521522 defer ts.Close()
522523
523524 // Test
524 client.timeDeltaDone = false
525 client.timeDelta = atomic.Value{}
525526 delta, err := client.getTimeDelta()
526527
527528 if err != nil {