Vendor main dependencies.

This commit is contained in:
Timo Reimann 2017-02-07 22:33:23 +01:00
parent 49a09ab7dd
commit dd5e3fba01
2738 changed files with 1045689 additions and 0 deletions

26
vendor/github.com/ovh/go-ovh/LICENSE generated vendored Normal file
View file

@ -0,0 +1,26 @@
Copyright (c) 2015-2016, OVH SAS.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of OVH SAS nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY OVH SAS AND CONTRIBUTORS ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL OVH SAS AND CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

123
vendor/github.com/ovh/go-ovh/ovh/configuration.go generated vendored Normal file
View file

@ -0,0 +1,123 @@
package ovh
import (
"fmt"
"os"
"os/user"
"path/filepath"
"strings"
"gopkg.in/ini.v1"
)
// Use variables for easier test overload
var (
systemConfigPath = "/etc/ovh.conf"
userConfigPath = "/.ovh.conf" // prefixed with homeDir
localConfigPath = "./ovh.conf"
)
// currentUserHome attempts to get current user's home directory
func currentUserHome() (string, error) {
usr, err := user.Current()
if err != nil {
return "", err
}
return usr.HomeDir, nil
}
// appendConfigurationFile only if it exists. We need to do this because
// ini package will fail to load configuration at all if a configuration
// file is missing. This is racy, but better than always failing.
func appendConfigurationFile(cfg *ini.File, path string) {
if file, err := os.Open(path); err == nil {
file.Close()
cfg.Append(path)
}
}
// loadConfig loads client configuration from params, environments or configuration
// files (by order of decreasing precedence).
//
// loadConfig will check OVH_CONSUMER_KEY, OVH_APPLICATION_KEY, OVH_APPLICATION_SECRET
// and OVH_ENDPOINT environment variables. If any is present, it will take precedence
// over any configuration from file.
//
// Configuration files are ini files. They share the same format as python-ovh,
// node-ovh, php-ovh and all other wrappers. If any wrapper is configured, all
// can re-use the same configuration. loadConfig will check for configuration in:
//
// - ./ovh.conf
// - $HOME/.ovh.conf
// - /etc/ovh.conf
//
func (c *Client) loadConfig(endpointName string) error {
// Load configuration files by order of increasing priority. All configuration
// files are optional. Only load file from user home if home could be resolve
cfg := ini.Empty()
appendConfigurationFile(cfg, systemConfigPath)
if home, err := currentUserHome(); err == nil {
userConfigFullPath := filepath.Join(home, userConfigPath)
appendConfigurationFile(cfg, userConfigFullPath)
}
appendConfigurationFile(cfg, localConfigPath)
// Canonicalize configuration
if endpointName == "" {
endpointName = getConfigValue(cfg, "default", "endpoint", "ovh-eu")
}
if c.AppKey == "" {
c.AppKey = getConfigValue(cfg, endpointName, "application_key", "")
}
if c.AppSecret == "" {
c.AppSecret = getConfigValue(cfg, endpointName, "application_secret", "")
}
if c.ConsumerKey == "" {
c.ConsumerKey = getConfigValue(cfg, endpointName, "consumer_key", "")
}
// Load real endpoint URL by name. If endpoint contains a '/', consider it as a URL
if strings.Contains(endpointName, "/") {
c.endpoint = endpointName
} else {
c.endpoint = Endpoints[endpointName]
}
// If we still have no valid endpoint, AppKey or AppSecret, return an error
if c.endpoint == "" {
return fmt.Errorf("Unknown endpoint '%s'. Consider checking 'Endpoints' list of using an URL.", endpointName)
}
if c.AppKey == "" {
return fmt.Errorf("Missing application key. Please check your configuration or consult the documentation to create one.")
}
if c.AppSecret == "" {
return fmt.Errorf("Missing application secret. Please check your configuration or consult the documentation to create one.")
}
return nil
}
// getConfigValue returns the value of OVH_<NAME> or ``name`` value from ``section``. If
// the value could not be read from either env or any configuration files, return 'def'
func getConfigValue(cfg *ini.File, section, name, def string) string {
// Attempt to load from environment
fromEnv := os.Getenv("OVH_" + strings.ToUpper(name))
if len(fromEnv) > 0 {
return fromEnv
}
// Attempt to load from configuration
fromSection := cfg.Section(section)
if fromSection == nil {
return def
}
fromSectionKey := fromSection.Key(name)
if fromSectionKey == nil {
return def
}
return fromSectionKey.String()
}

113
vendor/github.com/ovh/go-ovh/ovh/consumer_key.go generated vendored Normal file
View file

@ -0,0 +1,113 @@
package ovh
import (
"fmt"
"strings"
)
// Map user friendly access level names to corresponding HTTP verbs
var (
ReadOnly = []string{"GET"}
ReadWrite = []string{"GET", "POST", "PUT", "DELETE"}
ReadWriteSafe = []string{"GET", "POST", "PUT"}
)
// AccessRule represents a method allowed for a path
type AccessRule struct {
// Allowed HTTP Method for the requested AccessRule.
// Can be set to GET/POST/PUT/DELETE.
Method string `json:"method"`
// Allowed path.
// Can be an exact string or a string with '*' char.
// Example :
// /me : only /me is authorized
// /* : all calls are authorized
Path string `json:"path"`
}
// CkValidationState represents the response when asking a new consumerKey.
type CkValidationState struct {
// Consumer key, which need to be validated by customer.
ConsumerKey string `json:"consumerKey"`
// Current status, should be always "pendingValidation".
State string `json:"state"`
// URL to redirect user in order to log in.
ValidationURL string `json:"validationUrl"`
}
// CkRequest represents the parameters to fill in order to ask a new
// consumerKey.
type CkRequest struct {
client *Client
AccessRules []AccessRule `json:"accessRules"`
Redirection string `json:"redirection,omitempty"`
}
func (ck *CkValidationState) String() string {
return fmt.Sprintf("CK: %q\nStatus: %q\nValidation URL: %q\n",
ck.ConsumerKey,
ck.State,
ck.ValidationURL,
)
}
// NewCkRequest helps create a new ck request
func (c *Client) NewCkRequest() *CkRequest {
return &CkRequest{
client: c,
AccessRules: []AccessRule{},
}
}
// NewCkRequestWithRedirection helps create a new ck request with a redirect URL
func (c *Client) NewCkRequestWithRedirection(redirection string) *CkRequest {
return &CkRequest{
client: c,
AccessRules: []AccessRule{},
Redirection: redirection,
}
}
// AddRule adds a new rule to the ckRequest
func (ck *CkRequest) AddRule(method, path string) {
ck.AccessRules = append(ck.AccessRules, AccessRule{
Method: method,
Path: path,
})
}
// AddRules adds grant requests on "path" for all methods. "ReadOnly",
// "ReadWrite" and "ReadWriteSafe" should be used for "methods" unless
// specific access are required.
func (ck *CkRequest) AddRules(methods []string, path string) {
for _, method := range methods {
ck.AddRule(method, path)
}
}
// AddRecursiveRules adds grant requests on "path" and "path/*", for all
// methods "ReadOnly", "ReadWrite" and "ReadWriteSafe" should be used for
// "methods" unless specific access are required.
func (ck *CkRequest) AddRecursiveRules(methods []string, path string) {
path = strings.TrimRight(path, "/")
// Add rules. Skip base rule when requesting access to "/"
if path != "" {
ck.AddRules(methods, path)
}
ck.AddRules(methods, path+"/*")
}
// Do executes the request. On success, set the consumer key in the client
// and return the URL the user needs to visit to validate the key
func (ck *CkRequest) Do() (*CkValidationState, error) {
state := CkValidationState{}
err := ck.client.PostUnAuth("/auth/credential", ck, &state)
if err == nil {
ck.client.ConsumerKey = state.ConsumerKey
}
return &state, err
}

17
vendor/github.com/ovh/go-ovh/ovh/error.go generated vendored Normal file
View file

@ -0,0 +1,17 @@
package ovh
import "fmt"
// APIError represents an error that can occurred while calling the API.
type APIError struct {
// Error message.
Message string
// HTTP code.
Code int
// ID of the request
QueryID string
}
func (err *APIError) Error() string {
return fmt.Sprintf("Error %d: %q", err.Code, err.Message)
}

331
vendor/github.com/ovh/go-ovh/ovh/ovh.go generated vendored Normal file
View file

@ -0,0 +1,331 @@
// Package ovh provides a HTTP wrapper for the OVH API.
package ovh
import (
"bytes"
"crypto/sha1"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"strconv"
"sync"
"time"
)
// DefaultTimeout api requests after 180s
const DefaultTimeout = 180 * time.Second
// Endpoints
const (
OvhEU = "https://eu.api.ovh.com/1.0"
OvhCA = "https://ca.api.ovh.com/1.0"
KimsufiEU = "https://eu.api.kimsufi.com/1.0"
KimsufiCA = "https://ca.api.kimsufi.com/1.0"
SoyoustartEU = "https://eu.api.soyoustart.com/1.0"
SoyoustartCA = "https://ca.api.soyoustart.com/1.0"
RunaboveCA = "https://api.runabove.com/1.0"
)
// Endpoints conveniently maps endpoints names to their URI for external configuration
var Endpoints = map[string]string{
"ovh-eu": OvhEU,
"ovh-ca": OvhCA,
"kimsufi-eu": KimsufiEU,
"kimsufi-ca": KimsufiCA,
"soyoustart-eu": SoyoustartEU,
"soyoustart-ca": SoyoustartCA,
"runabove-ca": RunaboveCA,
}
// Errors
var (
ErrAPIDown = errors.New("go-vh: the OVH API is down, it does't respond to /time anymore")
)
// Client represents a client to call the OVH API
type Client struct {
// Self generated tokens. Create one by visiting
// https://eu.api.ovh.com/createApp/
// AppKey holds the Application key
AppKey string
// AppSecret holds the Application secret key
AppSecret string
// ConsumerKey holds the user/app specific token. It must have been validated before use.
ConsumerKey string
// API endpoint
endpoint string
// Client is the underlying HTTP client used to run the requests. It may be overloaded but a default one is instanciated in ``NewClient`` by default.
Client *http.Client
// Ensures that the timeDelta function is only ran once
// sync.Once would consider init done, even in case of error
// hence a good old flag
timeDeltaMutex *sync.Mutex
timeDeltaDone bool
timeDelta time.Duration
Timeout time.Duration
}
// NewClient represents a new client to call the API
func NewClient(endpoint, appKey, appSecret, consumerKey string) (*Client, error) {
client := Client{
AppKey: appKey,
AppSecret: appSecret,
ConsumerKey: consumerKey,
Client: &http.Client{},
timeDeltaMutex: &sync.Mutex{},
timeDeltaDone: false,
Timeout: time.Duration(DefaultTimeout),
}
// Get and check the configuration
if err := client.loadConfig(endpoint); err != nil {
return nil, err
}
return &client, nil
}
// NewEndpointClient will create an API client for specified
// endpoint and load all credentials from environment or
// configuration files
func NewEndpointClient(endpoint string) (*Client, error) {
return NewClient(endpoint, "", "", "")
}
// NewDefaultClient will load all it's parameter from environment
// or configuration files
func NewDefaultClient() (*Client, error) {
return NewClient("", "", "", "")
}
//
// High level helpers
//
// Ping performs a ping to OVH API.
// In fact, ping is just a /auth/time call, in order to check if API is up.
func (c *Client) Ping() error {
_, err := c.getTime()
return err
}
// TimeDelta represents the delay between the machine that runs the code and the
// OVH API. The delay shouldn't change, let's do it only once.
func (c *Client) TimeDelta() (time.Duration, error) {
return c.getTimeDelta()
}
// Time returns time from the OVH API, by asking GET /auth/time.
func (c *Client) Time() (*time.Time, error) {
return c.getTime()
}
//
// Common request wrappers
//
// Get is a wrapper for the GET method
func (c *Client) Get(url string, resType interface{}) error {
return c.CallAPI("GET", url, nil, resType, true)
}
// GetUnAuth is a wrapper for the unauthenticated GET method
func (c *Client) GetUnAuth(url string, resType interface{}) error {
return c.CallAPI("GET", url, nil, resType, false)
}
// Post is a wrapper for the POST method
func (c *Client) Post(url string, reqBody, resType interface{}) error {
return c.CallAPI("POST", url, reqBody, resType, true)
}
// PostUnAuth is a wrapper for the unauthenticated POST method
func (c *Client) PostUnAuth(url string, reqBody, resType interface{}) error {
return c.CallAPI("POST", url, reqBody, resType, false)
}
// Put is a wrapper for the PUT method
func (c *Client) Put(url string, reqBody, resType interface{}) error {
return c.CallAPI("PUT", url, reqBody, resType, true)
}
// PutUnAuth is a wrapper for the unauthenticated PUT method
func (c *Client) PutUnAuth(url string, reqBody, resType interface{}) error {
return c.CallAPI("PUT", url, reqBody, resType, false)
}
// Delete is a wrapper for the DELETE method
func (c *Client) Delete(url string, resType interface{}) error {
return c.CallAPI("DELETE", url, nil, resType, true)
}
// DeleteUnAuth is a wrapper for the unauthenticated DELETE method
func (c *Client) DeleteUnAuth(url string, resType interface{}) error {
return c.CallAPI("DELETE", url, nil, resType, false)
}
//
// Low level API access
//
// getResult check the response and unmarshals it into the response type if needed.
// Helper function, called from CallAPI.
func (c *Client) getResponse(response *http.Response, resType interface{}) error {
// Read all the response body
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
return err
}
// < 200 && >= 300 : API error
if response.StatusCode < http.StatusOK || response.StatusCode >= http.StatusMultipleChoices {
apiError := &APIError{Code: response.StatusCode}
if err = json.Unmarshal(body, apiError); err != nil {
return err
}
apiError.QueryID = response.Header.Get("X-Ovh-QueryID")
return apiError
}
// Nothing to unmarshal
if len(body) == 0 || resType == nil {
return nil
}
return json.Unmarshal(body, &resType)
}
// timeDelta returns the time delta between the host and the remote API
func (c *Client) getTimeDelta() (time.Duration, error) {
if !c.timeDeltaDone {
// Ensure only one thread is updating
c.timeDeltaMutex.Lock()
// Did we wait ? Maybe no more needed
if !c.timeDeltaDone {
ovhTime, err := c.getTime()
if err != nil {
return 0, err
}
c.timeDelta = time.Since(*ovhTime)
c.timeDeltaDone = true
}
c.timeDeltaMutex.Unlock()
}
return c.timeDelta, nil
}
// getTime t returns time from for a given api client endpoint
func (c *Client) getTime() (*time.Time, error) {
var timestamp int64
err := c.GetUnAuth("/auth/time", &timestamp)
if err != nil {
return nil, err
}
serverTime := time.Unix(timestamp, 0)
return &serverTime, nil
}
// getLocalTime is a function to be overwritten during the tests, it return the time
// on the the local machine
var getLocalTime = func() time.Time {
return time.Now()
}
// getEndpointForSignature is a function to be overwritten during the tests, it returns a
// the endpoint
var getEndpointForSignature = func(c *Client) string {
return c.endpoint
}
// CallAPI is the lowest level call helper. If needAuth is true,
// inject authentication headers and sign the request.
//
// Request signature is a sha1 hash on following fields, joined by '+':
// - applicationSecret (from Client instance)
// - consumerKey (from Client instance)
// - capitalized method (from arguments)
// - full request url, including any query string argument
// - full serialized request body
// - server current time (takes time delta into account)
//
// Call will automatically assemble the target url from the endpoint
// configured in the client instance and the path argument. If the reqBody
// argument is not nil, it will also serialize it as json and inject
// the required Content-Type header.
//
// If everyrthing went fine, unmarshall response into resType and return nil
// otherwise, return the error
func (c *Client) CallAPI(method, path string, reqBody, resType interface{}, needAuth bool) error {
var body []byte
var err error
if reqBody != nil {
body, err = json.Marshal(reqBody)
if err != nil {
return err
}
}
target := fmt.Sprintf("%s%s", c.endpoint, path)
req, err := http.NewRequest(method, target, bytes.NewReader(body))
if err != nil {
return err
}
// Inject headers
if body != nil {
req.Header.Add("Content-Type", "application/json;charset=utf-8")
}
req.Header.Add("X-Ovh-Application", c.AppKey)
req.Header.Add("Accept", "application/json")
// Inject signature. Some methods do not need authentication, especially /time,
// /auth and some /order methods are actually broken if authenticated.
if needAuth {
timeDelta, err := c.TimeDelta()
if err != nil {
return err
}
timestamp := getLocalTime().Add(-timeDelta).Unix()
req.Header.Add("X-Ovh-Timestamp", strconv.FormatInt(timestamp, 10))
req.Header.Add("X-Ovh-Consumer", c.ConsumerKey)
h := sha1.New()
h.Write([]byte(fmt.Sprintf("%s+%s+%s+%s%s+%s+%d",
c.AppSecret,
c.ConsumerKey,
method,
getEndpointForSignature(c),
path,
body,
timestamp,
)))
req.Header.Add("X-Ovh-Signature", fmt.Sprintf("$1$%x", h.Sum(nil)))
}
// Send the request with requested timeout
c.Client.Timeout = c.Timeout
response, err := c.Client.Do(req)
if err != nil {
return err
}
// Unmarshal the result into the resType if possible
return c.getResponse(response, resType)
}