mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 05:40:42 +00:00 
			
		
		
		
	Update storageos api dependency to 0.3.4
This commit is contained in:
		
							
								
								
									
										53
									
								
								vendor/github.com/storageos/go-api/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										53
									
								
								vendor/github.com/storageos/go-api/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -6,61 +6,28 @@ go_library( | ||||
|         "client.go", | ||||
|         "controller.go", | ||||
|         "event.go", | ||||
|         "health.go", | ||||
|         "logger.go", | ||||
|         "login.go", | ||||
|         "namespace.go", | ||||
|         "policy.go", | ||||
|         "pool.go", | ||||
|         "rule.go", | ||||
|         "server_version.go", | ||||
|         "template.go", | ||||
|         "user.go", | ||||
|         "util.go", | ||||
|         "validation.go", | ||||
|         "volume.go", | ||||
|     ] + select({ | ||||
|         "@io_bazel_rules_go//go/platform:android": [ | ||||
|             "client_unix.go", | ||||
|         ], | ||||
|         "@io_bazel_rules_go//go/platform:darwin": [ | ||||
|             "client_unix.go", | ||||
|         ], | ||||
|         "@io_bazel_rules_go//go/platform:dragonfly": [ | ||||
|             "client_unix.go", | ||||
|         ], | ||||
|         "@io_bazel_rules_go//go/platform:freebsd": [ | ||||
|             "client_unix.go", | ||||
|         ], | ||||
|         "@io_bazel_rules_go//go/platform:linux": [ | ||||
|             "client_unix.go", | ||||
|         ], | ||||
|         "@io_bazel_rules_go//go/platform:nacl": [ | ||||
|             "client_unix.go", | ||||
|         ], | ||||
|         "@io_bazel_rules_go//go/platform:netbsd": [ | ||||
|             "client_unix.go", | ||||
|         ], | ||||
|         "@io_bazel_rules_go//go/platform:openbsd": [ | ||||
|             "client_unix.go", | ||||
|         ], | ||||
|         "@io_bazel_rules_go//go/platform:plan9": [ | ||||
|             "client_unix.go", | ||||
|         ], | ||||
|         "@io_bazel_rules_go//go/platform:solaris": [ | ||||
|             "client_unix.go", | ||||
|         ], | ||||
|         "@io_bazel_rules_go//go/platform:windows": [ | ||||
|             "client_windows.go", | ||||
|         ], | ||||
|         "//conditions:default": [], | ||||
|     }), | ||||
|     ], | ||||
|     importpath = "github.com/storageos/go-api", | ||||
|     visibility = ["//visibility:public"], | ||||
|     deps = [ | ||||
|         "//vendor/github.com/gorilla/websocket:go_default_library", | ||||
|         "//vendor/github.com/storageos/go-api/netutil:go_default_library", | ||||
|         "//vendor/github.com/storageos/go-api/serror:go_default_library", | ||||
|         "//vendor/github.com/storageos/go-api/types:go_default_library", | ||||
|     ] + select({ | ||||
|         "@io_bazel_rules_go//go/platform:windows": [ | ||||
|             "//vendor/github.com/Microsoft/go-winio:go_default_library", | ||||
|         ], | ||||
|         "//conditions:default": [], | ||||
|     }), | ||||
|     ], | ||||
| ) | ||||
|  | ||||
| filegroup( | ||||
| @@ -74,6 +41,8 @@ filegroup( | ||||
|     name = "all-srcs", | ||||
|     srcs = [ | ||||
|         ":package-srcs", | ||||
|         "//vendor/github.com/storageos/go-api/netutil:all-srcs", | ||||
|         "//vendor/github.com/storageos/go-api/serror:all-srcs", | ||||
|         "//vendor/github.com/storageos/go-api/types:all-srcs", | ||||
|     ], | ||||
|     tags = ["automanaged"], | ||||
|   | ||||
							
								
								
									
										3
									
								
								vendor/github.com/storageos/go-api/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/storageos/go-api/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,2 +1,5 @@ | ||||
| # StorageOS API client library | ||||
|  | ||||
| ## Swagger Spec | ||||
| Swagger specification for this repo is available in the [StorageOS public documentation](https://github.com/storageos/storageos.github.io/blob/master/swagger.yaml). | ||||
|  | ||||
|   | ||||
							
								
								
									
										305
									
								
								vendor/github.com/storageos/go-api/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										305
									
								
								vendor/github.com/storageos/go-api/client.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -4,16 +4,16 @@ import ( | ||||
| 	"bytes" | ||||
| 	"context" | ||||
| 	"crypto/tls" | ||||
| 	"crypto/x509" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"github.com/storageos/go-api/netutil" | ||||
| 	"github.com/storageos/go-api/serror" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"net" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 	"os" | ||||
| 	"reflect" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| @@ -22,17 +22,11 @@ import ( | ||||
|  | ||||
| const ( | ||||
| 	userAgent         = "go-storageosclient" | ||||
| 	unixProtocol      = "unix" | ||||
| 	namedPipeProtocol = "npipe" | ||||
| 	DefaultVersionStr = "1" | ||||
| 	DefaultVersion    = 1 | ||||
| 	defaultNamespace  = "default" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// ErrInvalidEndpoint is returned when the endpoint is not a valid HTTP URL. | ||||
| 	ErrInvalidEndpoint = errors.New("invalid endpoint") | ||||
|  | ||||
| 	// ErrConnectionRefused is returned when the client cannot connect to the given endpoint. | ||||
| 	ErrConnectionRefused = errors.New("cannot connect to StorageOS API endpoint") | ||||
|  | ||||
| @@ -42,8 +36,14 @@ var ( | ||||
| 	// ErrInvalidVersion is returned when a versioned client was requested but no version specified. | ||||
| 	ErrInvalidVersion = errors.New("invalid version") | ||||
|  | ||||
| 	// DefaultPort is the default API port | ||||
| 	DefaultPort = "5705" | ||||
|  | ||||
| 	// DataplaneHealthPort is the the port used by the dataplane health-check service | ||||
| 	DataplaneHealthPort = "5704" | ||||
|  | ||||
| 	// DefaultHost is the default API host | ||||
| 	DefaultHost = "tcp://localhost:5705" | ||||
| 	DefaultHost = "tcp://localhost:" + DefaultPort | ||||
| ) | ||||
|  | ||||
| // APIVersion is an internal representation of a version of the Remote API. | ||||
| @@ -73,15 +73,13 @@ type Client struct { | ||||
| 	SkipServerVersionCheck bool | ||||
| 	HTTPClient             *http.Client | ||||
| 	TLSConfig              *tls.Config | ||||
| 	Dialer                 Dialer | ||||
| 	endpoint               string | ||||
| 	endpointURL            *url.URL | ||||
| 	username               string | ||||
| 	secret                 string | ||||
| 	requestedAPIVersion    APIVersion | ||||
| 	serverAPIVersion       APIVersion | ||||
| 	expectedAPIVersion     APIVersion | ||||
| 	nativeHTTPClient       *http.Client | ||||
| 	useTLS                 bool | ||||
| } | ||||
|  | ||||
| // ClientVersion returns the API version of the client | ||||
| @@ -99,20 +97,8 @@ type Dialer interface { | ||||
| // NewClient returns a Client instance ready for communication with the given | ||||
| // server endpoint. It will use the latest remote API version available in the | ||||
| // server. | ||||
| func NewClient(endpoint string) (*Client, error) { | ||||
| 	client, err := NewVersionedClient(endpoint, "") | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	client.SkipServerVersionCheck = true | ||||
| 	return client, nil | ||||
| } | ||||
|  | ||||
| // NewTLSClient returns a Client instance ready for TLS communications with the given | ||||
| // server endpoint, key and certificates . It will use the latest remote API version | ||||
| // available in the server. | ||||
| func NewTLSClient(endpoint string, cert, key, ca string) (*Client, error) { | ||||
| 	client, err := NewVersionedTLSClient(endpoint, cert, key, ca, "") | ||||
| func NewClient(nodes string) (*Client, error) { | ||||
| 	client, err := NewVersionedClient(nodes, "") | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @@ -122,17 +108,24 @@ func NewTLSClient(endpoint string, cert, key, ca string) (*Client, error) { | ||||
|  | ||||
| // NewVersionedClient returns a Client instance ready for communication with | ||||
| // the given server endpoint, using a specific remote API version. | ||||
| func NewVersionedClient(endpoint string, apiVersionString string) (*Client, error) { | ||||
| 	u, err := parseEndpoint(endpoint, false) | ||||
| func NewVersionedClient(nodestring string, apiVersionString string) (*Client, error) { | ||||
| 	nodes := strings.Split(nodestring, ",") | ||||
|  | ||||
| 	d, err := netutil.NewMultiDialer(nodes, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var useTLS bool | ||||
| 	if len(nodes) > 0 { | ||||
| 		if u, err := url.Parse(nodes[0]); err != nil && u.Scheme == "https" { | ||||
| 			useTLS = true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	c := &Client{ | ||||
| 		HTTPClient:  defaultClient(), | ||||
| 		Dialer:      &net.Dialer{}, | ||||
| 		endpoint:    endpoint, | ||||
| 		endpointURL: u, | ||||
| 		HTTPClient: defaultClient(d), | ||||
| 		useTLS:     useTLS, | ||||
| 	} | ||||
|  | ||||
| 	if apiVersionString != "" { | ||||
| @@ -143,85 +136,6 @@ func NewVersionedClient(endpoint string, apiVersionString string) (*Client, erro | ||||
| 		c.requestedAPIVersion = APIVersion(version) | ||||
| 	} | ||||
|  | ||||
| 	c.initializeNativeClient() | ||||
| 	return c, nil | ||||
| } | ||||
|  | ||||
| // NewVersionedTLSClient returns a Client instance ready for TLS communications with the givens | ||||
| // server endpoint, key and certificates, using a specific remote API version. | ||||
| func NewVersionedTLSClient(endpoint string, cert, key, ca, apiVersionString string) (*Client, error) { | ||||
| 	var certPEMBlock []byte | ||||
| 	var keyPEMBlock []byte | ||||
| 	var caPEMCert []byte | ||||
| 	if _, err := os.Stat(cert); !os.IsNotExist(err) { | ||||
| 		certPEMBlock, err = ioutil.ReadFile(cert) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
| 	if _, err := os.Stat(key); !os.IsNotExist(err) { | ||||
| 		keyPEMBlock, err = ioutil.ReadFile(key) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
| 	if _, err := os.Stat(ca); !os.IsNotExist(err) { | ||||
| 		caPEMCert, err = ioutil.ReadFile(ca) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
| 	return NewVersionedTLSClientFromBytes(endpoint, certPEMBlock, keyPEMBlock, caPEMCert, apiVersionString) | ||||
| } | ||||
|  | ||||
| // NewVersionedTLSClientFromBytes returns a Client instance ready for TLS communications with the givens | ||||
| // server endpoint, key and certificates (passed inline to the function as opposed to being | ||||
| // read from a local file), using a specific remote API version. | ||||
| func NewVersionedTLSClientFromBytes(endpoint string, certPEMBlock, keyPEMBlock, caPEMCert []byte, apiVersionString string) (*Client, error) { | ||||
| 	u, err := parseEndpoint(endpoint, true) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	tlsConfig := &tls.Config{} | ||||
| 	if certPEMBlock != nil && keyPEMBlock != nil { | ||||
| 		tlsCert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		tlsConfig.Certificates = []tls.Certificate{tlsCert} | ||||
| 	} | ||||
| 	if caPEMCert == nil { | ||||
| 		tlsConfig.InsecureSkipVerify = true | ||||
| 	} else { | ||||
| 		caPool := x509.NewCertPool() | ||||
| 		if !caPool.AppendCertsFromPEM(caPEMCert) { | ||||
| 			return nil, errors.New("Could not add RootCA pem") | ||||
| 		} | ||||
| 		tlsConfig.RootCAs = caPool | ||||
| 	} | ||||
| 	tr := defaultTransport() | ||||
| 	tr.TLSClientConfig = tlsConfig | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	c := &Client{ | ||||
| 		HTTPClient:  &http.Client{Transport: tr}, | ||||
| 		TLSConfig:   tlsConfig, | ||||
| 		Dialer:      &net.Dialer{}, | ||||
| 		endpoint:    endpoint, | ||||
| 		endpointURL: u, | ||||
| 	} | ||||
|  | ||||
| 	if apiVersionString != "" { | ||||
| 		version, err := strconv.Atoi(apiVersionString) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		c.requestedAPIVersion = APIVersion(version) | ||||
| 	} | ||||
|  | ||||
| 	c.initializeNativeClient() | ||||
| 	return c, nil | ||||
| } | ||||
|  | ||||
| @@ -265,13 +179,6 @@ func (c *Client) checkAPIVersion() error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Endpoint returns the current endpoint. It's useful for getting the endpoint | ||||
| // when using functions that get this data from the environment (like | ||||
| // NewClientFromEnv. | ||||
| func (c *Client) Endpoint() string { | ||||
| 	return c.endpoint | ||||
| } | ||||
|  | ||||
| // Ping pings the API server | ||||
| // | ||||
| // See https://goo.gl/wYfgY1 for more details. | ||||
| @@ -341,15 +248,7 @@ func (c *Client) do(method, urlpath string, doOptions doOptions) (*http.Response | ||||
| 	} | ||||
|  | ||||
| 	httpClient := c.HTTPClient | ||||
| 	protocol := c.endpointURL.Scheme | ||||
| 	var u string | ||||
| 	switch protocol { | ||||
| 	case unixProtocol, namedPipeProtocol: | ||||
| 		httpClient = c.nativeHTTPClient | ||||
| 		u = c.getFakeNativeURL(urlpath, doOptions.unversioned) | ||||
| 	default: | ||||
| 		u = c.getAPIPath(urlpath, query, doOptions.unversioned) | ||||
| 	} | ||||
| 	u := c.getAPIPath(urlpath, query, doOptions.unversioned) | ||||
|  | ||||
| 	req, err := http.NewRequest(method, u, params) | ||||
| 	if err != nil { | ||||
| @@ -376,6 +275,11 @@ func (c *Client) do(method, urlpath string, doOptions doOptions) (*http.Response | ||||
|  | ||||
| 	resp, err := httpClient.Do(req.WithContext(ctx)) | ||||
| 	if err != nil { | ||||
| 		// If it is a custom error, return it. It probably knows more than us | ||||
| 		if serror.IsStorageOSError(err) { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		if strings.Contains(err.Error(), "connection refused") { | ||||
| 			return nil, ErrConnectionRefused | ||||
| 		} | ||||
| @@ -397,27 +301,18 @@ func chooseError(ctx context.Context, err error) error { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (c *Client) getURL(path string, unversioned bool) string { | ||||
|  | ||||
| 	urlStr := strings.TrimRight(c.endpointURL.String(), "/") | ||||
| 	path = strings.TrimLeft(path, "/") | ||||
| 	if c.endpointURL.Scheme == unixProtocol || c.endpointURL.Scheme == namedPipeProtocol { | ||||
| 		urlStr = "" | ||||
| 	} | ||||
| 	if unversioned { | ||||
| 		return fmt.Sprintf("%s/%s", urlStr, path) | ||||
| 	} | ||||
| 	return fmt.Sprintf("%s/%s/%s", urlStr, c.requestedAPIVersion, path) | ||||
|  | ||||
| } | ||||
|  | ||||
| func (c *Client) getAPIPath(path string, query url.Values, unversioned bool) string { | ||||
| 	var apiPath string | ||||
| 	urlStr := strings.TrimRight(c.endpointURL.String(), "/") | ||||
| 	path = strings.TrimLeft(path, "/") | ||||
| 	if c.endpointURL.Scheme == unixProtocol || c.endpointURL.Scheme == namedPipeProtocol { | ||||
| 		urlStr = "" | ||||
| 	// The custom dialer contacts the hosts for us, making this hosname irrelevant | ||||
| 	var urlStr string | ||||
| 	if c.useTLS { | ||||
| 		urlStr = "https://storageos-cluster" | ||||
| 	} else { | ||||
| 		urlStr = "http://storageos-cluster" | ||||
| 	} | ||||
|  | ||||
| 	var apiPath string | ||||
|  | ||||
| 	path = strings.TrimLeft(path, "/") | ||||
| 	if unversioned { | ||||
| 		apiPath = fmt.Sprintf("%s/%s", urlStr, path) | ||||
| 	} else { | ||||
| @@ -431,30 +326,6 @@ func (c *Client) getAPIPath(path string, query url.Values, unversioned bool) str | ||||
| 	return apiPath | ||||
| } | ||||
|  | ||||
| // getFakeNativeURL returns the URL needed to make an HTTP request over a UNIX | ||||
| // domain socket to the given path. | ||||
| func (c *Client) getFakeNativeURL(path string, unversioned bool) string { | ||||
| 	u := *c.endpointURL // Copy. | ||||
|  | ||||
| 	// Override URL so that net/http will not complain. | ||||
| 	u.Scheme = "http" | ||||
| 	u.Host = "unix.sock" // Doesn't matter what this is - it's not used. | ||||
| 	u.Path = "" | ||||
| 	urlStr := strings.TrimRight(u.String(), "/") | ||||
| 	path = strings.TrimLeft(path, "/") | ||||
| 	if unversioned { | ||||
| 		return fmt.Sprintf("%s/%s", urlStr, path) | ||||
| 	} | ||||
| 	return fmt.Sprintf("%s/%s/%s", urlStr, c.requestedAPIVersion, path) | ||||
| } | ||||
|  | ||||
| type jsonMessage struct { | ||||
| 	Status   string `json:"status,omitempty"` | ||||
| 	Progress string `json:"progress,omitempty"` | ||||
| 	Error    string `json:"error,omitempty"` | ||||
| 	Stream   string `json:"stream,omitempty"` | ||||
| } | ||||
|  | ||||
| func queryString(opts interface{}) string { | ||||
| 	if opts == nil { | ||||
| 		return "" | ||||
| @@ -530,63 +401,50 @@ type Error struct { | ||||
| } | ||||
|  | ||||
| func newError(resp *http.Response) *Error { | ||||
| 	type jsonError struct { | ||||
| 		Message string `json:"message"` | ||||
| 	} | ||||
|  | ||||
| 	defer resp.Body.Close() | ||||
| 	data, err := ioutil.ReadAll(resp.Body) | ||||
| 	if err != nil { | ||||
| 		return &Error{Status: resp.StatusCode, Message: fmt.Sprintf("cannot read body, err: %v", err)} | ||||
| 	} | ||||
| 	return &Error{Status: resp.StatusCode, Message: string(data)} | ||||
|  | ||||
| 	// attempt to unmarshal the error if in json format | ||||
| 	jerr := &jsonError{} | ||||
| 	err = json.Unmarshal(data, jerr) | ||||
| 	if err != nil { | ||||
| 		return &Error{Status: resp.StatusCode, Message: string(data)} // Failed, just return string | ||||
| 	} | ||||
|  | ||||
| 	return &Error{Status: resp.StatusCode, Message: jerr.Message} | ||||
| } | ||||
|  | ||||
| func (e *Error) Error() string { | ||||
| 	return fmt.Sprintf("API error (%d): %s", e.Status, e.Message) | ||||
| } | ||||
| 	var niceStatus string | ||||
|  | ||||
| func parseEndpoint(endpoint string, tls bool) (*url.URL, error) { | ||||
| 	if endpoint != "" && !strings.Contains(endpoint, "://") { | ||||
| 		endpoint = "tcp://" + endpoint | ||||
| 	switch e.Status { | ||||
| 	case 400, 500: | ||||
| 		niceStatus = "Server failed to process your request. Was the data correct?" | ||||
| 	case 401: | ||||
| 		niceStatus = "Unauthenticated access of secure endpoint, please retry after authentication" | ||||
| 	case 403: | ||||
| 		niceStatus = "Forbidden request. Your user cannot perform this action" | ||||
| 	case 404: | ||||
| 		niceStatus = "Requested object not found. Does this item exist?" | ||||
| 	} | ||||
| 	u, err := url.Parse(endpoint) | ||||
| 	if err != nil { | ||||
| 		return nil, ErrInvalidEndpoint | ||||
| 	} | ||||
| 	if tls && u.Scheme != "unix" { | ||||
| 		u.Scheme = "https" | ||||
| 	} | ||||
| 	switch u.Scheme { | ||||
| 	case unixProtocol, namedPipeProtocol: | ||||
| 		return u, nil | ||||
| 	case "http", "https", "tcp": | ||||
| 		_, port, err := net.SplitHostPort(u.Host) | ||||
| 		if err != nil { | ||||
| 			if e, ok := err.(*net.AddrError); ok { | ||||
| 				if e.Err == "missing port in address" { | ||||
| 					return u, nil | ||||
| 				} | ||||
| 			} | ||||
| 			return nil, ErrInvalidEndpoint | ||||
| 		} | ||||
| 		number, err := strconv.ParseInt(port, 10, 64) | ||||
| 		if err == nil && number > 0 && number < 65536 { | ||||
| 			if u.Scheme == "tcp" { | ||||
| 				if tls { | ||||
| 					u.Scheme = "https" | ||||
| 				} else { | ||||
| 					u.Scheme = "http" | ||||
| 				} | ||||
| 			} | ||||
| 			return u, nil | ||||
| 		} | ||||
| 		return nil, ErrInvalidEndpoint | ||||
| 	default: | ||||
| 		return nil, ErrInvalidEndpoint | ||||
|  | ||||
| 	if niceStatus != "" { | ||||
| 		return fmt.Sprintf("API error (%s): %s", niceStatus, e.Message) | ||||
| 	} | ||||
| 	return fmt.Sprintf("API error (%s): %s", http.StatusText(e.Status), e.Message) | ||||
| } | ||||
|  | ||||
| // defaultTransport returns a new http.Transport with the same default values | ||||
| // as http.DefaultTransport, but with idle connections and keepalives disabled. | ||||
| func defaultTransport() *http.Transport { | ||||
| 	transport := defaultPooledTransport() | ||||
| func defaultTransport(d Dialer) *http.Transport { | ||||
| 	transport := defaultPooledTransport(d) | ||||
| 	transport.DisableKeepAlives = true | ||||
| 	transport.MaxIdleConnsPerHost = -1 | ||||
| 	return transport | ||||
| @@ -596,14 +454,11 @@ func defaultTransport() *http.Transport { | ||||
| // values to http.DefaultTransport. Do not use this for transient transports as | ||||
| // it can leak file descriptors over time. Only use this for transports that | ||||
| // will be re-used for the same host(s). | ||||
| func defaultPooledTransport() *http.Transport { | ||||
| func defaultPooledTransport(d Dialer) *http.Transport { | ||||
| 	transport := &http.Transport{ | ||||
| 		Proxy: http.ProxyFromEnvironment, | ||||
| 		Dial: (&net.Dialer{ | ||||
| 			Timeout:   30 * time.Second, | ||||
| 			KeepAlive: 30 * time.Second, | ||||
| 		}).Dial, | ||||
| 		TLSHandshakeTimeout: 10 * time.Second, | ||||
| 		Proxy:               http.ProxyFromEnvironment, | ||||
| 		Dial:                d.Dial, | ||||
| 		TLSHandshakeTimeout: 5 * time.Second, | ||||
| 		DisableKeepAlives:   false, | ||||
| 		MaxIdleConnsPerHost: 1, | ||||
| 	} | ||||
| @@ -613,8 +468,16 @@ func defaultPooledTransport() *http.Transport { | ||||
| // defaultClient returns a new http.Client with similar default values to | ||||
| // http.Client, but with a non-shared Transport, idle connections disabled, and | ||||
| // keepalives disabled. | ||||
| func defaultClient() *http.Client { | ||||
| // If a custom dialer is not provided, one with sane defaults will be created. | ||||
| func defaultClient(d Dialer) *http.Client { | ||||
| 	if d == nil { | ||||
| 		d = &net.Dialer{ | ||||
| 			Timeout:   5 * time.Second, | ||||
| 			KeepAlive: 5 * time.Second, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return &http.Client{ | ||||
| 		Transport: defaultTransport(), | ||||
| 		Transport: defaultTransport(d), | ||||
| 	} | ||||
| } | ||||
|   | ||||
							
								
								
									
										25
									
								
								vendor/github.com/storageos/go-api/client_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								vendor/github.com/storageos/go-api/client_unix.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,25 +0,0 @@ | ||||
| // +build !windows | ||||
| // Copyright 2016 go-dockerclient authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package storageos | ||||
|  | ||||
| import ( | ||||
| 	"net" | ||||
| 	"net/http" | ||||
| ) | ||||
|  | ||||
| // initializeNativeClient initializes the native Unix domain socket client on | ||||
| // Unix-style operating systems | ||||
| func (c *Client) initializeNativeClient() { | ||||
| 	if c.endpointURL.Scheme != unixProtocol { | ||||
| 		return | ||||
| 	} | ||||
| 	socketPath := c.endpointURL.Path | ||||
| 	tr := defaultTransport() | ||||
| 	tr.Dial = func(network, addr string) (net.Conn, error) { | ||||
| 		return c.Dialer.Dial(unixProtocol, socketPath) | ||||
| 	} | ||||
| 	c.nativeHTTPClient = &http.Client{Transport: tr} | ||||
| } | ||||
							
								
								
									
										40
									
								
								vendor/github.com/storageos/go-api/client_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								vendor/github.com/storageos/go-api/client_windows.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,40 +0,0 @@ | ||||
| // +build windows | ||||
| // Copyright 2016 go-dockerclient authors. All rights reserved. | ||||
| // Use of this source code is governed by a BSD-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package storageos | ||||
|  | ||||
| import ( | ||||
| 	"net" | ||||
| 	"net/http" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/Microsoft/go-winio" | ||||
| ) | ||||
|  | ||||
| const namedPipeConnectTimeout = 2 * time.Second | ||||
|  | ||||
| type pipeDialer struct { | ||||
| 	dialFunc func(network, addr string) (net.Conn, error) | ||||
| } | ||||
|  | ||||
| func (p pipeDialer) Dial(network, address string) (net.Conn, error) { | ||||
| 	return p.dialFunc(network, address) | ||||
| } | ||||
|  | ||||
| // initializeNativeClient initializes the native Named Pipe client for Windows | ||||
| func (c *Client) initializeNativeClient() { | ||||
| 	if c.endpointURL.Scheme != namedPipeProtocol { | ||||
| 		return | ||||
| 	} | ||||
| 	namedPipePath := c.endpointURL.Path | ||||
| 	dialFunc := func(network, addr string) (net.Conn, error) { | ||||
| 		timeout := namedPipeConnectTimeout | ||||
| 		return winio.DialPipe(namedPipePath, &timeout) | ||||
| 	} | ||||
| 	tr := defaultTransport() | ||||
| 	tr.Dial = dialFunc | ||||
| 	c.Dialer = &pipeDialer{dialFunc} | ||||
| 	c.nativeHTTPClient = &http.Client{Transport: tr} | ||||
| } | ||||
							
								
								
									
										1
									
								
								vendor/github.com/storageos/go-api/controller.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/storageos/go-api/controller.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -26,7 +26,6 @@ func (c *Client) ControllerList(opts types.ListOptions) ([]*types.Controller, er | ||||
| 	listOpts := doOptions{ | ||||
| 		fieldSelector: opts.FieldSelector, | ||||
| 		labelSelector: opts.LabelSelector, | ||||
| 		namespace:     opts.Namespace, | ||||
| 		context:       opts.Context, | ||||
| 	} | ||||
|  | ||||
|   | ||||
							
								
								
									
										71
									
								
								vendor/github.com/storageos/go-api/health.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								vendor/github.com/storageos/go-api/health.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| package storageos | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
|  | ||||
| 	"github.com/storageos/go-api/types" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// HealthAPIPrefix is a partial path to the HTTP endpoint. | ||||
| 	HealthAPIPrefix = "health" | ||||
| ) | ||||
|  | ||||
| // CPHealth returns the health of the control plane server at a given url. | ||||
| func (c *Client) CPHealth(ctx context.Context, hostname string) (*types.CPHealthStatus, error) { | ||||
|  | ||||
| 	url := fmt.Sprintf("http://%s:%s/v1/%s", hostname, DefaultPort, HealthAPIPrefix) | ||||
| 	req, err := http.NewRequest("GET", url, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	req.Header.Set("User-Agent", userAgent) | ||||
| 	if c.username != "" && c.secret != "" { | ||||
| 		req.SetBasicAuth(c.username, c.secret) | ||||
| 	} | ||||
|  | ||||
| 	resp, err := c.HTTPClient.Do(req.WithContext(ctx)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	var status *types.CPHealthStatus | ||||
| 	if err := json.NewDecoder(resp.Body).Decode(&status); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return status, nil | ||||
| } | ||||
|  | ||||
| // DPHealth returns the health of the data plane server at a given url. | ||||
| func (c *Client) DPHealth(ctx context.Context, hostname string) (*types.DPHealthStatus, error) { | ||||
|  | ||||
| 	url := fmt.Sprintf("http://%s:%s/v1/%s", hostname, DataplaneHealthPort, HealthAPIPrefix) | ||||
| 	req, err := http.NewRequest("GET", url, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	req.Header.Set("User-Agent", userAgent) | ||||
| 	if c.username != "" && c.secret != "" { | ||||
| 		req.SetBasicAuth(c.username, c.secret) | ||||
| 	} | ||||
|  | ||||
| 	resp, err := c.HTTPClient.Do(req.WithContext(ctx)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	var status *types.DPHealthStatus | ||||
| 	if err := json.NewDecoder(resp.Body).Decode(&status); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return status, nil | ||||
| } | ||||
							
								
								
									
										62
									
								
								vendor/github.com/storageos/go-api/logger.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								vendor/github.com/storageos/go-api/logger.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| package storageos | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	"net/url" | ||||
|  | ||||
| 	"github.com/storageos/go-api/types" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// LoggerAPIPrefix is a partial path to the HTTP endpoint. | ||||
| 	LoggerAPIPrefix = "logs" | ||||
| ) | ||||
|  | ||||
| // LoggerConfig returns every cluster node's logging configuration. | ||||
| func (c *Client) LoggerConfig(opts types.ListOptions) ([]*types.Logger, error) { | ||||
|  | ||||
| 	listOpts := doOptions{ | ||||
| 		fieldSelector: opts.FieldSelector, | ||||
| 		labelSelector: opts.LabelSelector, | ||||
| 		context:       opts.Context, | ||||
| 	} | ||||
|  | ||||
| 	if opts.LabelSelector != "" { | ||||
| 		query := url.Values{} | ||||
| 		query.Add("labelSelector", opts.LabelSelector) | ||||
| 		listOpts.values = query | ||||
| 	} | ||||
|  | ||||
| 	resp, err := c.do("GET", LoggerAPIPrefix+"/cluster/config", listOpts) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
| 	var loggers []*types.Logger | ||||
| 	if err := json.NewDecoder(resp.Body).Decode(&loggers); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return loggers, nil | ||||
|  | ||||
| } | ||||
|  | ||||
| // LoggerUpdate patches updates to logging configuration.  Fields to update must | ||||
| // be listed in the Fields value, and if a list of Nodes is given it will only | ||||
| // apply to the nodes listed.  Returns the updated configuration. | ||||
| func (c *Client) LoggerUpdate(opts types.LoggerUpdateOptions) ([]*types.Logger, error) { | ||||
|  | ||||
| 	resp, err := c.do("PATCH", LoggerAPIPrefix+"/cluster/config", doOptions{ | ||||
| 		data:    opts, | ||||
| 		context: context.Background(), | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
| 	var loggers []*types.Logger | ||||
| 	if err := json.NewDecoder(resp.Body).Decode(&loggers); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return loggers, nil | ||||
| } | ||||
							
								
								
									
										46
									
								
								vendor/github.com/storageos/go-api/login.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								vendor/github.com/storageos/go-api/login.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| package storageos | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	// LoginAPIPrefix is a partial path to the HTTP endpoint. | ||||
| 	LoginAPIPrefix = "auth/login" | ||||
| 	ErrLoginFailed = errors.New("Failed to get token from API endpoint") | ||||
| ) | ||||
|  | ||||
| // Login attemps to get a token from the API | ||||
| func (c *Client) Login() (token string, err error) { | ||||
| 	resp, err := c.do("POST", LoginAPIPrefix, doOptions{data: struct { | ||||
| 		User string `json:"username"` | ||||
| 		Pass string `json:"password"` | ||||
| 	}{c.username, c.secret}}) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		if _, ok := err.(*Error); ok { | ||||
| 			return "", ErrLoginFailed | ||||
| 		} | ||||
|  | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	if resp.StatusCode != 200 { | ||||
| 		return "", ErrLoginFailed | ||||
| 	} | ||||
|  | ||||
| 	unmarsh := struct { | ||||
| 		Token string `json:"token"` | ||||
| 	}{} | ||||
|  | ||||
| 	if err := json.NewDecoder(resp.Body).Decode(&unmarsh); err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|  | ||||
| 	if unmarsh.Token == "" { | ||||
| 		return "", ErrLoginFailed | ||||
| 	} | ||||
|  | ||||
| 	return unmarsh.Token, nil | ||||
| } | ||||
							
								
								
									
										27
									
								
								vendor/github.com/storageos/go-api/netutil/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/storageos/go-api/netutil/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| load("@io_bazel_rules_go//go:def.bzl", "go_library") | ||||
|  | ||||
| go_library( | ||||
|     name = "go_default_library", | ||||
|     srcs = [ | ||||
|         "errors.go", | ||||
|         "multidialer.go", | ||||
|         "parsers.go", | ||||
|     ], | ||||
|     importpath = "github.com/storageos/go-api/netutil", | ||||
|     visibility = ["//visibility:public"], | ||||
|     deps = ["//vendor/github.com/storageos/go-api/serror:go_default_library"], | ||||
| ) | ||||
|  | ||||
| filegroup( | ||||
|     name = "package-srcs", | ||||
|     srcs = glob(["**"]), | ||||
|     tags = ["automanaged"], | ||||
|     visibility = ["//visibility:private"], | ||||
| ) | ||||
|  | ||||
| filegroup( | ||||
|     name = "all-srcs", | ||||
|     srcs = [":package-srcs"], | ||||
|     tags = ["automanaged"], | ||||
|     visibility = ["//visibility:public"], | ||||
| ) | ||||
							
								
								
									
										26
									
								
								vendor/github.com/storageos/go-api/netutil/errors.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/storageos/go-api/netutil/errors.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| package netutil | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"github.com/storageos/go-api/serror" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| func errAllFailed(addrs []string) error { | ||||
| 	msg := fmt.Sprintf("failed to dial all known cluster members, (%s)", strings.Join(addrs, ",")) | ||||
| 	help := "ensure that the value of $STORAGEOS_HOST (or the -H flag) is correct, and that there are healthy StorageOS nodes in this cluster" | ||||
|  | ||||
| 	return serror.NewTypedStorageOSError(serror.APIUncontactable, nil, msg, help) | ||||
| } | ||||
|  | ||||
| func newInvalidNodeError(err error) error { | ||||
| 	msg := fmt.Sprintf("invalid node format: %s", err) | ||||
| 	help := "please check the format of $STORAGEOS_HOST (or the -H flag) complies with the StorageOS JOIN format" | ||||
|  | ||||
| 	return serror.NewTypedStorageOSError(serror.InvalidHostConfig, err, msg, help) | ||||
| } | ||||
|  | ||||
| var errNoAddresses = errors.New("the MultiDialer instance has not been initialised with client addresses") | ||||
| var errUnsupportedScheme = errors.New("unsupported URL scheme") | ||||
| var errInvalidPortNumber = errors.New("invalid port number") | ||||
							
								
								
									
										109
									
								
								vendor/github.com/storageos/go-api/netutil/multidialer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								vendor/github.com/storageos/go-api/netutil/multidialer.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | ||||
| package netutil | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"math/rand" | ||||
| 	"net" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| var DefaultDialPort = "5705" | ||||
|  | ||||
| func init() { | ||||
| 	rand.Seed(time.Now().UnixNano()) | ||||
| } | ||||
|  | ||||
| // Dialer is an interface that matches *net.Dialer. The intention is to allow either the stdlib | ||||
| // dialer or a custom implementation to be passed to the MultiDialer constructor. This also makes | ||||
| // the component easier to test. | ||||
| type Dialer interface { | ||||
| 	DialContext(context.Context, string, string) (net.Conn, error) | ||||
| } | ||||
|  | ||||
| // MultiDialer is a custom net Dialer (to be used in a net.Transport field) that attemps to dial | ||||
| // out to any (potentialy many) of a set of pre-defined addresses. The intended use of this | ||||
| // function is to extend the functionality of the stdlib http.Client to transparently support | ||||
| // requests to any member of a given storageos cluster. | ||||
| type MultiDialer struct { | ||||
| 	Addresses []string | ||||
| 	Dialer    *net.Dialer | ||||
| } | ||||
|  | ||||
| // NewMultiDialer returns a new MultiDialer instance, configured to dial out to the given set of | ||||
| // nodes. Nodes can be provided using a URL format (e.g. http://google.com:80), or a host-port pair | ||||
| // (e.g. localhost:4567). | ||||
| // | ||||
| // If a port number is omitted, the value of DefaultDialPort is used. | ||||
| // Given hostnames are resolved to IP addresses, and IP addresses are used verbatim. | ||||
| // | ||||
| // If called with a non-nil dialer, the MultiDialer instance will use this for internall dial | ||||
| // requests. If this value is nil, the function will initialise one with sane defaults. | ||||
| func NewMultiDialer(nodes []string, dialer *net.Dialer) (*MultiDialer, error) { | ||||
| 	// If a dialer is not provided, initialise one with sane defaults | ||||
| 	if dialer == nil { | ||||
| 		dialer = &net.Dialer{ | ||||
| 			Timeout:   5 * time.Second, | ||||
| 			KeepAlive: 5 * time.Second, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	addrs, err := addrsFromNodes(nodes) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &MultiDialer{ | ||||
| 		Addresses: addrs, | ||||
| 		Dialer:    dialer, | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
| // DialContext will dial each of the MultiDialer's internal addresses in a random order until one | ||||
| // successfully returns a connection, it has run out of addresses (returning ErrAllFailed), or the | ||||
| // given context has been closed. | ||||
| // | ||||
| // Due to the intrinsic behaviour of this function, any address passed to this function will be | ||||
| // ignored. | ||||
| func (m *MultiDialer) DialContext(ctx context.Context, network, ignoredAddress string) (net.Conn, error) { | ||||
| 	if len(m.Addresses) == 0 { | ||||
| 		return nil, newInvalidNodeError(errNoAddresses) | ||||
| 	} | ||||
|  | ||||
| 	// Shuffle a copy of the addresses (for even load balancing) | ||||
| 	addrs := make([]string, len(m.Addresses)) | ||||
| 	copy(addrs, m.Addresses) | ||||
|  | ||||
| 	// Fisher–Yates shuffle algorithm | ||||
| 	for i := len(addrs) - 1; i > 0; i-- { | ||||
| 		j := rand.Intn(i + 1) | ||||
| 		addrs[i], addrs[j] = addrs[j], addrs[i] | ||||
| 	} | ||||
|  | ||||
| 	// Try to dial each of these addresses in turn, or return on closed context | ||||
| 	for _, addr := range addrs { | ||||
| 		select { | ||||
| 		case <-ctx.Done(): | ||||
| 			return nil, ctx.Err() | ||||
|  | ||||
| 		default: | ||||
| 			// Create new child context for a single dial | ||||
| 			dctx, cancel := context.WithTimeout(ctx, time.Second) | ||||
| 			defer cancel() | ||||
|  | ||||
| 			conn, err := m.Dialer.DialContext(dctx, network, addr) | ||||
| 			if err != nil { | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			return conn, nil | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// We failed to dail all of the addresses we have | ||||
| 	return nil, errAllFailed(m.Addresses) | ||||
| } | ||||
|  | ||||
| // Dial returns the result of a call to m.DialContext passing in the background context | ||||
| func (m *MultiDialer) Dial(network, addr string) (net.Conn, error) { | ||||
| 	return m.DialContext(context.Background(), network, addr) | ||||
| } | ||||
							
								
								
									
										142
									
								
								vendor/github.com/storageos/go-api/netutil/parsers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								vendor/github.com/storageos/go-api/netutil/parsers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,142 @@ | ||||
| package netutil | ||||
|  | ||||
| import ( | ||||
| 	"net" | ||||
| 	"net/url" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| // addrsFromNodes takes a list of node hosts and attempts to return a list of hosts in ip:port | ||||
| // format along with any error encountered. | ||||
| // | ||||
| // The function accepts node hosts in URL, ip, ip:port, resolvable-name and resolvable-name:port | ||||
| // formats and will append the default port value if needed. | ||||
| func addrsFromNodes(nodes []string) ([]string, error) { | ||||
| 	var addrs []string | ||||
|  | ||||
| 	for _, n := range nodes { | ||||
| 		switch { | ||||
| 		// Assume that the node is provided as a URL | ||||
| 		case strings.Contains(n, "://"): | ||||
| 			newAddrs, err := parseURL(n) | ||||
| 			if err != nil { | ||||
| 				return nil, newInvalidNodeError(err) | ||||
| 			} | ||||
|  | ||||
| 			addrs = append(addrs, newAddrs...) | ||||
|  | ||||
| 		// Assume the node is in hostname:port or ip:port format | ||||
| 		case strings.Contains(n, ":"): | ||||
| 			newAddrs, err := parseHostPort(n) | ||||
| 			if err != nil { | ||||
| 				return nil, newInvalidNodeError(err) | ||||
| 			} | ||||
|  | ||||
| 			addrs = append(addrs, newAddrs...) | ||||
|  | ||||
| 		// Assume hostname or ip | ||||
| 		default: | ||||
| 			newAddrs, err := parseHost(n) | ||||
| 			if err != nil { | ||||
| 				return nil, newInvalidNodeError(err) | ||||
| 			} | ||||
|  | ||||
| 			addrs = append(addrs, newAddrs...) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return addrs, nil | ||||
| } | ||||
|  | ||||
| func validPort(port string) bool { | ||||
| 	intPort, err := strconv.Atoi(port) | ||||
|  | ||||
| 	return (err == nil) && | ||||
| 		(intPort > 0) && | ||||
| 		(intPort <= 65535) | ||||
| } | ||||
|  | ||||
| // parseURL takes a valid URL and verifies that it is using a correct scheme, has a resolvable | ||||
| // address (or is an IP) and has a valid port (or adds the default if the port is omitted). The | ||||
| // function then returns a list of addresses in ip:port format along with any error encountered. | ||||
| // | ||||
| // The function may return multiple addresses depending on the dns answer received when resolving | ||||
| // the host. | ||||
| func parseURL(node string) ([]string, error) { | ||||
| 	url, err := url.Parse(node) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// Verify a valid scheme | ||||
| 	switch url.Scheme { | ||||
| 	case "tcp", "http", "https": | ||||
| 		host, port, err := net.SplitHostPort(url.Host) | ||||
| 		if err != nil { | ||||
| 			// We could be here as there is no port, lets try one last time with default port added | ||||
| 			host, port, err = net.SplitHostPort(url.Host + ":" + DefaultDialPort) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if !validPort(port) { | ||||
| 			return nil, errInvalidPortNumber | ||||
| 		} | ||||
|  | ||||
| 		// LookupHost works for IP addr too | ||||
| 		addrs, err := net.LookupHost(host) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		for i, a := range addrs { | ||||
| 			addrs[i] = a + ":" + port | ||||
| 		} | ||||
|  | ||||
| 		return addrs, nil | ||||
|  | ||||
| 	default: | ||||
| 		return nil, errUnsupportedScheme | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // parseHostPort takes a string in host:port format and checks it has a resolvable address (or is | ||||
| // an IP) and a valid port (or adds the default if the port is omitted). The function then returns | ||||
| // a list of addresses in ip:port format along with any error encountered. | ||||
| // | ||||
| // The function may return multiple addresses depending on the dns answer received when resolving | ||||
| // the host. | ||||
| func parseHostPort(node string) ([]string, error) { | ||||
| 	host, port, err := net.SplitHostPort(node) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if !validPort(port) { | ||||
| 		return nil, errInvalidPortNumber | ||||
| 	} | ||||
|  | ||||
| 	// LookupHost works for IP addr too | ||||
| 	addrs, err := net.LookupHost(host) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	for i, a := range addrs { | ||||
| 		addrs[i] = a + ":" + port | ||||
| 	} | ||||
|  | ||||
| 	return addrs, nil | ||||
| } | ||||
|  | ||||
| // parseHostPort takes a hostname string and checks it is resolvable to an address (or is already | ||||
| // an IP) The function then returns a list of addresses in ip:port format (where port is the | ||||
| // default port) along with any error encountered. | ||||
| // | ||||
| // The function may return multiple addresses depending on the dns answer received when resolving | ||||
| // the host. | ||||
| func parseHost(node string) ([]string, error) { | ||||
| 	return parseHostPort(node + ":" + DefaultDialPort) | ||||
| } | ||||
							
								
								
									
										103
									
								
								vendor/github.com/storageos/go-api/policy.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								vendor/github.com/storageos/go-api/policy.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| package storageos | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"github.com/storageos/go-api/types" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
|  | ||||
| 	// PolicyAPIPrefix is a partial path to the HTTP endpoint. | ||||
| 	PolicyAPIPrefix = "policies" | ||||
|  | ||||
| 	// ErrNoSuchPolicy is the error returned when the policy does not exist. | ||||
| 	ErrNoSuchPolicy = errors.New("no such policy") | ||||
| ) | ||||
|  | ||||
| // nopMarshaler is an alias to a []byte that implements json.Marshaler | ||||
| // it bypasses the base64 encoded string representation that json will give byte slices. | ||||
| // It should only be used to wrap []byte types containing pre-rendered valid json that will later | ||||
| // (out of the caller's control) be run through json.Marshal | ||||
| type nopMarshaler []byte | ||||
|  | ||||
| func (n *nopMarshaler) MarshalJSON() ([]byte, error) { | ||||
| 	return *n, nil | ||||
| } | ||||
|  | ||||
| // PolicyCreate creates a policy on the server. | ||||
| func (c *Client) PolicyCreate(jsonl []byte, ctx context.Context) error { | ||||
| 	nopm := nopMarshaler(jsonl) | ||||
| 	_, err := c.do("POST", PolicyAPIPrefix, doOptions{ | ||||
| 		data:    &nopm, | ||||
| 		context: ctx, | ||||
| 		headers: map[string]string{"Content-Type": "application/x-jsonlines"}, | ||||
| 	}) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // Policy returns a policy on the server by ID. | ||||
| func (c *Client) Policy(id string) (*types.Policy, error) { | ||||
| 	path := fmt.Sprintf("%s/%s", PolicyAPIPrefix, id) | ||||
| 	resp, err := c.do("GET", path, doOptions{}) | ||||
| 	if err != nil { | ||||
| 		if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { | ||||
| 			return nil, ErrNoSuchPolicy | ||||
| 		} | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	var policy *types.Policy | ||||
| 	if err := json.NewDecoder(resp.Body).Decode(&policy); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return policy, nil | ||||
| } | ||||
|  | ||||
| // PolicyList returns the list of policies on the server. | ||||
| func (c *Client) PolicyList(opts types.ListOptions) (types.PolicySet, error) { | ||||
| 	listOpts := doOptions{ | ||||
| 		fieldSelector: opts.FieldSelector, | ||||
| 		labelSelector: opts.LabelSelector, | ||||
| 		namespace:     opts.Namespace, | ||||
| 		context:       opts.Context, | ||||
| 	} | ||||
|  | ||||
| 	if opts.LabelSelector != "" { | ||||
| 		query := url.Values{} | ||||
| 		query.Add("labelSelector", opts.LabelSelector) | ||||
| 		listOpts.values = query | ||||
| 	} | ||||
|  | ||||
| 	resp, err := c.do("GET", PolicyAPIPrefix, listOpts) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	var policies types.PolicySet | ||||
| 	if err := json.NewDecoder(resp.Body).Decode(&policies); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return policies, nil | ||||
| } | ||||
|  | ||||
| // PolicyDelete deletes a policy on the server by ID. | ||||
| func (c *Client) PolicyDelete(opts types.DeleteOptions) error { | ||||
| 	resp, err := c.do("DELETE", PolicyAPIPrefix+"/"+opts.Name, doOptions{}) | ||||
| 	if err != nil { | ||||
| 		if e, ok := err.(*Error); ok { | ||||
| 			if e.Status == http.StatusNotFound { | ||||
| 				return ErrNoSuchPolicy | ||||
| 			} | ||||
| 		} | ||||
| 		return err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										13
									
								
								vendor/github.com/storageos/go-api/rule.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								vendor/github.com/storageos/go-api/rule.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -72,10 +72,15 @@ func (c *Client) Rule(namespace string, ref string) (*types.Rule, error) { | ||||
|  | ||||
| // RuleCreate creates a rule on the server and returns the new object. | ||||
| func (c *Client) RuleCreate(opts types.RuleCreateOptions) (*types.Rule, error) { | ||||
| 	resp, err := c.do("POST", RuleAPIPrefix, doOptions{ | ||||
| 		data:      opts, | ||||
| 		namespace: opts.Namespace, | ||||
| 		context:   opts.Context, | ||||
| 	path, err := namespacedPath(opts.Namespace, RuleAPIPrefix) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	resp, err := c.do("POST", path, doOptions{ | ||||
| 		data: opts, | ||||
| 		// namespace: opts.Namespace, | ||||
| 		context: opts.Context, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
|   | ||||
							
								
								
									
										28
									
								
								vendor/github.com/storageos/go-api/serror/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/storageos/go-api/serror/BUILD
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| load("@io_bazel_rules_go//go:def.bzl", "go_library") | ||||
|  | ||||
| go_library( | ||||
|     name = "go_default_library", | ||||
|     srcs = [ | ||||
|         "error_kind.go", | ||||
|         "kind_lookup_map.go", | ||||
|         "storageos_error.go", | ||||
|         "storageoserrorkind_string.go", | ||||
|         "typed_error.go", | ||||
|     ], | ||||
|     importpath = "github.com/storageos/go-api/serror", | ||||
|     visibility = ["//visibility:public"], | ||||
| ) | ||||
|  | ||||
| filegroup( | ||||
|     name = "package-srcs", | ||||
|     srcs = glob(["**"]), | ||||
|     tags = ["automanaged"], | ||||
|     visibility = ["//visibility:private"], | ||||
| ) | ||||
|  | ||||
| filegroup( | ||||
|     name = "all-srcs", | ||||
|     srcs = [":package-srcs"], | ||||
|     tags = ["automanaged"], | ||||
|     visibility = ["//visibility:public"], | ||||
| ) | ||||
							
								
								
									
										11
									
								
								vendor/github.com/storageos/go-api/serror/error_kind.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/storageos/go-api/serror/error_kind.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| package serror | ||||
|  | ||||
| //go:generate stringer -type=StorageOSErrorKind error_kind.go | ||||
| type StorageOSErrorKind int | ||||
|  | ||||
| // Known error kinds | ||||
| const ( | ||||
| 	UnknownError StorageOSErrorKind = iota | ||||
| 	APIUncontactable | ||||
| 	InvalidHostConfig | ||||
| ) | ||||
							
								
								
									
										37
									
								
								vendor/github.com/storageos/go-api/serror/kind_lookup_map.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								vendor/github.com/storageos/go-api/serror/kind_lookup_map.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| package serror | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| var kindLookupMap map[string]StorageOSErrorKind | ||||
|  | ||||
| func init() { | ||||
| 	kindLookupMap = make(map[string]StorageOSErrorKind) | ||||
|  | ||||
| 	// Populate the lookup map with all the known constants | ||||
| 	for i := StorageOSErrorKind(0); !strings.HasPrefix(i.String(), "StorageOSErrorKind("); i++ { | ||||
| 		kindLookupMap[i.String()] = i | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (s *StorageOSErrorKind) UnmarshalJSON(b []byte) error { | ||||
| 	str := "" | ||||
| 	if err := json.Unmarshal(b, &str); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	v, ok := kindLookupMap[str] | ||||
| 	if !ok { | ||||
| 		return fmt.Errorf("Failed to unmarshal ErrorKind %s", s) | ||||
| 	} | ||||
|  | ||||
| 	*s = v | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (s *StorageOSErrorKind) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(s.String()) | ||||
| } | ||||
							
								
								
									
										34
									
								
								vendor/github.com/storageos/go-api/serror/storageos_error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								vendor/github.com/storageos/go-api/serror/storageos_error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| package serror | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| ) | ||||
|  | ||||
| type StorageOSError interface { | ||||
| 	// embedding error provides compatibility with standard error handling code | ||||
| 	error | ||||
|  | ||||
| 	// Encoding/decoding methods to help errors traverse API boundaries | ||||
| 	json.Marshaler | ||||
| 	json.Unmarshaler | ||||
|  | ||||
| 	Err() error               // Returns the underlying error that caused this event | ||||
| 	String() string           // A short string representing the error (for logging etc) | ||||
| 	Help() string             // A larger string that should provide informative debug instruction to users | ||||
| 	Kind() StorageOSErrorKind // A type representing a set of known error conditions, helpful to switch on | ||||
| 	Extra() map[string]string // A container for error specific information | ||||
|  | ||||
| 	// TODO: should we include callstack traces here? We could have a debug mode for it. | ||||
| } | ||||
|  | ||||
| func ErrorKind(err error) StorageOSErrorKind { | ||||
| 	if serr, ok := err.(StorageOSError); ok { | ||||
| 		return serr.Kind() | ||||
| 	} | ||||
| 	return UnknownError | ||||
| } | ||||
|  | ||||
| func IsStorageOSError(err error) bool { | ||||
| 	_, ok := err.(StorageOSError) | ||||
| 	return ok | ||||
| } | ||||
							
								
								
									
										16
									
								
								vendor/github.com/storageos/go-api/serror/storageoserrorkind_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/storageos/go-api/serror/storageoserrorkind_string.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| // Code generated by "stringer -type=StorageOSErrorKind error_kind.go"; DO NOT EDIT. | ||||
|  | ||||
| package serror | ||||
|  | ||||
| import "strconv" | ||||
|  | ||||
| const _StorageOSErrorKind_name = "UnknownErrorAPIUncontactableInvalidHostConfig" | ||||
|  | ||||
| var _StorageOSErrorKind_index = [...]uint8{0, 12, 28, 45} | ||||
|  | ||||
| func (i StorageOSErrorKind) String() string { | ||||
| 	if i < 0 || i >= StorageOSErrorKind(len(_StorageOSErrorKind_index)-1) { | ||||
| 		return "StorageOSErrorKind(" + strconv.FormatInt(int64(i), 10) + ")" | ||||
| 	} | ||||
| 	return _StorageOSErrorKind_name[_StorageOSErrorKind_index[i]:_StorageOSErrorKind_index[i+1]] | ||||
| } | ||||
							
								
								
									
										64
									
								
								vendor/github.com/storageos/go-api/serror/typed_error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								vendor/github.com/storageos/go-api/serror/typed_error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| package serror | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| ) | ||||
|  | ||||
| func NewTypedStorageOSError(kind StorageOSErrorKind, err error, msg string, help string) StorageOSError { | ||||
| 	return &typedStorageOSError{ | ||||
| 		internal: &internal_TypedStorageOSError{ | ||||
| 			ErrorKind:   &kind, | ||||
| 			Cause:       err, | ||||
| 			ErrMessage:  msg, | ||||
| 			HelpMessage: help, | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func NewUntypedStorageOSError(err error, msg string, help string) StorageOSError { | ||||
| 	var kind StorageOSErrorKind = UnknownError | ||||
|  | ||||
| 	return &typedStorageOSError{ | ||||
| 		internal: &internal_TypedStorageOSError{ | ||||
| 			ErrorKind:   &kind, | ||||
| 			Cause:       err, | ||||
| 			ErrMessage:  msg, | ||||
| 			HelpMessage: help, | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| type internal_TypedStorageOSError struct { | ||||
| 	ErrorKind   *StorageOSErrorKind `json:"error_kind"` | ||||
| 	Cause       error               `json:"caused_by"` | ||||
| 	ErrMessage  string              `json:"error_message"` | ||||
| 	HelpMessage string              `json:"help_message"` | ||||
| 	ExtraMap    map[string]string   `json:"extra"` | ||||
| } | ||||
|  | ||||
| type typedStorageOSError struct { | ||||
| 	internal *internal_TypedStorageOSError | ||||
| } | ||||
|  | ||||
| func (t *typedStorageOSError) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(t.internal) | ||||
| } | ||||
|  | ||||
| func (t *typedStorageOSError) UnmarshalJSON(d []byte) error { | ||||
| 	internal := &internal_TypedStorageOSError{} | ||||
|  | ||||
| 	err := json.Unmarshal(d, internal) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	t.internal = internal | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (t *typedStorageOSError) Error() string            { return t.String() } | ||||
| func (t *typedStorageOSError) Err() error               { return t.internal.Cause } | ||||
| func (t *typedStorageOSError) String() string           { return t.internal.ErrMessage } | ||||
| func (t *typedStorageOSError) Help() string             { return t.internal.HelpMessage } | ||||
| func (t *typedStorageOSError) Kind() StorageOSErrorKind { return *t.internal.ErrorKind } | ||||
| func (t *typedStorageOSError) Extra() map[string]string { return t.internal.ExtraMap } | ||||
							
								
								
									
										12
									
								
								vendor/github.com/storageos/go-api/swagger-gen.yaml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/storageos/go-api/swagger-gen.yaml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,12 +0,0 @@ | ||||
|  | ||||
| layout: | ||||
|   models: | ||||
|     - name: definition | ||||
|       source: asset:model | ||||
|       target: "{{ joinFilePath .Target .ModelPackage }}" | ||||
|       file_name: "{{ (snakize (pascalize .Name)) }}.go" | ||||
|   operations: | ||||
|     - name: handler | ||||
|       source: asset:serverOperation | ||||
|       target: "{{ joinFilePath .Target .APIPackage .Package }}" | ||||
|       file_name: "{{ (snakize (pascalize .Name)) }}.go" | ||||
							
								
								
									
										854
									
								
								vendor/github.com/storageos/go-api/swagger.yaml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										854
									
								
								vendor/github.com/storageos/go-api/swagger.yaml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,854 +0,0 @@ | ||||
|  | ||||
| # A Swagger 2.0 (a.k.a. OpenAPI) definition of the StorageOS API. | ||||
| # | ||||
| # This is used for generating API documentation and the types used by the | ||||
| # client/server. See api/README.md for more information. | ||||
| # | ||||
| # Some style notes: | ||||
| # - This file is used by ReDoc, which allows GitHub Flavored Markdown in | ||||
| #   descriptions. | ||||
| # - There is no maximum line length, for ease of editing and pretty diffs. | ||||
| # - operationIds are in the format "NounVerb", with a singular noun. | ||||
|  | ||||
| swagger: "2.0" | ||||
| schemes: | ||||
|   - "http" | ||||
|   - "https" | ||||
| produces: | ||||
|   - "application/json" | ||||
|   - "text/plain" | ||||
| consumes: | ||||
|   - "application/json" | ||||
|   - "text/plain" | ||||
| basePath: "/v1" | ||||
| info: | ||||
|   title: "StorageOS API" | ||||
|   version: "0.7" | ||||
|   x-logo: | ||||
|     url: "http://storageos.wpengine.com/wp-content/uploads/2017/03/cropped-logo-1.png" | ||||
|   description: | | ||||
|     The StorageOS API is an HTTP API used for managing volumes and StorageOS services. It is the API that the StorageOS UI, CLI and platform integrations use to communicate with the StorageOS backend. | ||||
|  | ||||
|     # Errors | ||||
|  | ||||
|     The API uses standard HTTP status codes to indicate the success or failure of the API call. The body of the response will be JSON in the following format: | ||||
|     ``` | ||||
|     { | ||||
|       "message": "page not found" | ||||
|     } | ||||
|     ``` | ||||
| # The tags on paths define the menu sections in the ReDoc documentation, so | ||||
| # the usage of tags must make sense for that: | ||||
| # - They should be singular, not plural. | ||||
| # - There should not be too many tags, or the menu becomes unwieldy. For | ||||
| #   example, it is preferable to add a path to the "System" tag instead of | ||||
| #   creating a tag with a single path in it. | ||||
| # - The order of tags in this list defines the order in the menu. | ||||
| tags: | ||||
|   # Primary objects | ||||
|   - name: "Volume" | ||||
|     x-displayName: "Volumes" | ||||
|     description: | | ||||
|       Create and manage volumes. | ||||
|   - name: "Pool" | ||||
|     x-displayName: "Pools" | ||||
|     description: | | ||||
|       Create and manage distributed capacity pools. | ||||
|  | ||||
| definitions: | ||||
|  | ||||
|   ErrorResponse: | ||||
|     description: "Represents an error." | ||||
|     type: "object" | ||||
|     required: ["message"] | ||||
|     properties: | ||||
|       message: | ||||
|         description: "The error message." | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|     example: | ||||
|       message: "Something went wrong." | ||||
|  | ||||
|   Deployment: | ||||
|     type: "object" | ||||
|     description: "Volume master or replica deployment details." | ||||
|     properties: | ||||
|       ID: | ||||
|         type: "string" | ||||
|         readOnly: true | ||||
|       Controller: | ||||
|         type: "string" | ||||
|         readOnly: true | ||||
|       Inode: | ||||
|         type: "integer" | ||||
|         format: "uint32" | ||||
|         readOnly: true | ||||
|       Status: | ||||
|         type: "string" | ||||
|         readOnly: true | ||||
|       Health: | ||||
|         type: "string" | ||||
|         readOnly: true | ||||
|       CreatedAt: | ||||
|         type: "string" | ||||
|         format: "datetime" | ||||
|         readOnly: true | ||||
|  | ||||
|   VolumeCreateOptions: | ||||
|     type: "object" | ||||
|     description: "Parameters available for creating new volumes." | ||||
|     required: [Name] | ||||
|     properties: | ||||
|       Name: | ||||
|         description: "Volume name." | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|       Description: | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         description: "Volume description." | ||||
|       Size: | ||||
|         type: "integer" | ||||
|         description: "Size in GB (if 0 or not specified, then defaults to 10 GB)." | ||||
|         x-nullable: false | ||||
|       Pool: | ||||
|         type: "string" | ||||
|         description: "Name of capacity pool to provision the volume in, or the name of the current pool." | ||||
|       Labels: | ||||
|         type: "object" | ||||
|         description: "User-defined key/value metadata." | ||||
|         x-nullable: false | ||||
|         additionalProperties: | ||||
|           type: "string" | ||||
|  | ||||
|   VolumeUpdateOptions: | ||||
|     type: "object" | ||||
|     description: "Parameters available for updating existing volumes." | ||||
|     properties: | ||||
|       Description: | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         description: "Volume description." | ||||
|       Size: | ||||
|         type: "integer" | ||||
|         description: "Size in GB." | ||||
|         x-nullable: false | ||||
|       Labels: | ||||
|         type: "object" | ||||
|         description: "User-defined key/value metadata." | ||||
|         x-nullable: false | ||||
|         additionalProperties: | ||||
|           type: "string" | ||||
|  | ||||
|   # VolumeMountOptions: | ||||
|   #   type: "object" | ||||
|   #   description: "Parameters available for mounting volumes." | ||||
|   #   properties: | ||||
|   #     ID: | ||||
|   #       type: "string" | ||||
|   #       x-nullable: false | ||||
|   #       description: "Volume unique ID." | ||||
|   #     Name: | ||||
|   #       description: "Volume name." | ||||
|   #       type: "string" | ||||
|   #       x-nullable: false | ||||
|   #     Namespace: | ||||
|   #       description: "The object scope, such as for teams and projects." | ||||
|   #       type: "string" | ||||
|   #       x-nullable: false | ||||
|   #     Client: | ||||
|   #       type: "string" | ||||
|   #       x-nullable: false | ||||
|   #       description: "Hostname of the client performing the mount." | ||||
|   # | ||||
|   # VolumeUnmountOptions: | ||||
|   #   type: "object" | ||||
|   #   description: "Parameters available for unmounting volumes." | ||||
|   #   properties: | ||||
|   #     ID: | ||||
|   #       type: "string" | ||||
|   #       x-nullable: false | ||||
|   #       description: "Volume unique ID." | ||||
|   #     Name: | ||||
|   #       description: "Volume name." | ||||
|   #       type: "string" | ||||
|   #       x-nullable: false | ||||
|   #     Namespace: | ||||
|   #       description: "The object scope, such as for teams and projects." | ||||
|   #       type: "string" | ||||
|   #       x-nullable: false | ||||
|   #     Client: | ||||
|   #       type: "string" | ||||
|   #       x-nullable: false | ||||
|   #       description: "Hostname of the client performing the unmount." | ||||
|  | ||||
|   # ListOptions: | ||||
|   #   type: "object" | ||||
|   #   description: "Parameters for finding volumes." | ||||
|   #   properties: | ||||
|   #     LabelSelector: | ||||
|   #       description: "A selector to restrict the list of returned objects by their labels. Defaults to everything." | ||||
|   #       type: "string" | ||||
|   #     FieldSelector: | ||||
|   #       type: "string" | ||||
|   #       description: "A selector to restrict the list of returned objects by their fields. Defaults to everything." | ||||
|   #     TimeoutSeconds: | ||||
|   #       type: "integer" | ||||
|   #       description: "Timeout for the list call." | ||||
|   #     Namespace: | ||||
|   #       type: "string" | ||||
|   #       description: "Object name and auth scope, such as for teams and projects" | ||||
|  | ||||
|   Volume: | ||||
|     type: "object" | ||||
|     description: "A storage volume." | ||||
|     required: [Name, Size] | ||||
|     properties: | ||||
|       ID: | ||||
|         description: "Volume unique ID." | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         readOnly: true | ||||
|       Name: | ||||
|         description: "Volume name." | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|       Description: | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         description: "Volume description." | ||||
|       Size: | ||||
|         type: integer | ||||
|         description: "Size in GB." | ||||
|         x-nullable: false | ||||
|       Pool: | ||||
|         type: "string" | ||||
|         description: "Name of capacity pool to provision the volume in, or the name of the current pool." | ||||
|       Labels: | ||||
|         type: "object" | ||||
|         description: "User-defined key/value metadata." | ||||
|         x-nullable: false | ||||
|         additionalProperties: | ||||
|           type: "string" | ||||
|       Master: | ||||
|         $ref: "#/definitions/Deployment" | ||||
|       Replicas: | ||||
|         type: "array" | ||||
|         description: "Volume deployment information for the replica volumes." | ||||
|         items: | ||||
|           $ref: "#/definitions/Deployment" | ||||
|         readOnly: true | ||||
|       Status: | ||||
|         type: "string" | ||||
|         description: "Short status, one of: pending, evaluating, deploying, active, unavailable, failed, updating, deleting." | ||||
|         readOnly: true | ||||
|       StatusMessage: | ||||
|         type: "string" | ||||
|         description: "Status message explaining current status." | ||||
|         readOnly: true | ||||
|       Health: | ||||
|         type: "string" | ||||
|         description: "Volume health, one of: healthy, degraded or dead." | ||||
|         readOnly: true | ||||
|       Inode: | ||||
|         type: "integer" | ||||
|         format: "uint32" | ||||
|         description: "Block device inode." | ||||
|         readOnly: true | ||||
|       Deleted: | ||||
|         type: "boolean" | ||||
|         description: "Flag indicating if the volume has been deleted and is waiting for scrubbing." | ||||
|         readOnly: true | ||||
|       Mounted: | ||||
|         type: "boolean" | ||||
|         description: "Flag indicating if the volume is mounted and in use." | ||||
|         readOnly: true | ||||
|       MountedBy: | ||||
|         type: "string" | ||||
|         description: "Reference to the node that has the volume mounted." | ||||
|         readOnly: true | ||||
|       Mountpoint: | ||||
|         type: "string" | ||||
|         description: "Mountpoint where the volume was mounted." | ||||
|         readOnly: true   | ||||
|       MountedAt: | ||||
|         type: "string" | ||||
|         format: "dateTime" | ||||
|         description: "When the volume was mounted." | ||||
|         readOnly: true | ||||
|       CreatedBy: | ||||
|         type: "string" | ||||
|         description: "User that created the volume." | ||||
|         readOnly: true | ||||
|       CreatedAt: | ||||
|         type: "string" | ||||
|         format: "dateTime" | ||||
|         description: "When the volume was created." | ||||
|         readOnly: true | ||||
|     example: | ||||
|       Name: vol01 | ||||
|       Size: 5 | ||||
|       Labels: | ||||
|         com.example.some-label: "some-value" | ||||
|         com.example.some-other-label: "some-other-value" | ||||
|  | ||||
|   PoolCreateOptions: | ||||
|     type: "object" | ||||
|     description: "Parameters available for creating new pools." | ||||
|     required: [Name] | ||||
|     properties: | ||||
|       Name: | ||||
|         description: "Pool name." | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|       Description: | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         description: "Pool description." | ||||
|       Default: | ||||
|         type: "boolean" | ||||
|         description: "Default determines whether this pool is the default if a volume is provisioned without a pool specified.  There can only be one default pool." | ||||
|         x-nullable: false | ||||
|       DefaultDriver: | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         description: "DefaultDriver specifies the storage driver to use by default if there are multiple drivers in the pool and no driver was specified in the provisioning request or assigned by rules.  If no driver was specified and no default set, driver weight is used to determine the default." | ||||
|       ControllerNames: | ||||
|         type: "array" | ||||
|         description: "ControllerNames is a list of controller names that are participating in the storage pool." | ||||
|         items: | ||||
|           type: "string" | ||||
|       DriverNames: | ||||
|         type: "array" | ||||
|         description: "DriverNames is a list of backend storage drivers that are available in the storage pool." | ||||
|         items: | ||||
|           type: "string" | ||||
|       Active: | ||||
|         type: "boolean" | ||||
|         x-nullable: false | ||||
|         description: "Flag describing whether rule is active." | ||||
|         default: false | ||||
|       Labels: | ||||
|         type: "object" | ||||
|         description: "Labels define a list of labels that describe the pool." | ||||
|         additionalProperties: | ||||
|           type: "string" | ||||
|  | ||||
|   Pool: | ||||
|     type: "object" | ||||
|     description: | | ||||
|       Pools are used to define distributed capacity that can be used to provision | ||||
|       volumes from.  Typically, each server that makes storage available will be | ||||
|       added to one or more pools. | ||||
|  | ||||
|       Capacity drivers are also added to the pool to determine which backend | ||||
|       storage driver to use.  Currently this is limited to a single type of | ||||
|       driver per pool, but in the future we will allow multiple, allowing for | ||||
|       dynamic tiering and snapshots from one driver type to another. | ||||
|     required: [Name] | ||||
|     properties: | ||||
|       ID: | ||||
|         description: "Pool unique ID." | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         readOnly: true | ||||
|       Name: | ||||
|         description: "Pool name." | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|       Description: | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         description: "Pool description." | ||||
|       Default: | ||||
|         type: "boolean" | ||||
|         x-nullable: false | ||||
|         description: | | ||||
|           Default determines whether this pool is the default if a volume is | ||||
|           provisioned without a pool specified.  There can only be one default | ||||
|           pool. | ||||
|       DefaultDriver: | ||||
|         type: "string" | ||||
|         description: | | ||||
|           DefaultDriver specifies the storage driver to use by default if there | ||||
|           are multiple drivers in the pool and no driver was specified in the | ||||
|           provisioning request or assigned by rules.  If no driver was specified | ||||
|           and no default set, driver weight is used to determine the default. | ||||
|       ControllerNames: | ||||
|         type: "array" | ||||
|         description: "ControllerNames is a list of controller names that are participating in the storage pool." | ||||
|         items: | ||||
|           type: "string" | ||||
|       DriverNames: | ||||
|         type: "array" | ||||
|         description: "DriverNames is a list of backend storage drivers that are available in the storage pool." | ||||
|         items: | ||||
|           type: "string" | ||||
|       DriverInstances: | ||||
|         $ref: "#/definitions/DriverInstances" | ||||
|       Active: | ||||
|         type: "boolean" | ||||
|         x-nullable: false | ||||
|         description: "Flag describing whether rule is active." | ||||
|         default: false | ||||
|       CapacityStats: | ||||
|         $ref: "#/definitions/CapacityStats" | ||||
|       Labels: | ||||
|         type: "object" | ||||
|         description: "Labels define a list of labels that describe the pool." | ||||
|         additionalProperties: | ||||
|           type: "string" | ||||
|  | ||||
|   Rule: | ||||
|     type: "object" | ||||
|     description: "A policy rule." | ||||
|     required: [Name] | ||||
|     properties: | ||||
|       ID: | ||||
|         description: "Rule unique ID." | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         readOnly: true | ||||
|       Name: | ||||
|         description: "Rule name." | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|       Description: | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         description: "Rule description." | ||||
|       Active: | ||||
|         type: "boolean" | ||||
|         x-nullable: false | ||||
|         description: "Flag describing whether rule is active." | ||||
|         default: false | ||||
|       Weight: | ||||
|         type: "integer" | ||||
|         x-nullable: false | ||||
|         description: | | ||||
|           "Weight is used to determine order during rule processing.  Rules with heavier weights are processed later." | ||||
|         default: 0 | ||||
|       Operator: | ||||
|         type: "string" | ||||
|         description: "Operator is used to compare objects or labels." | ||||
|         enum: | ||||
|           - "!" | ||||
|           - "=" | ||||
|           - "==" | ||||
|           - "in" | ||||
|           - "!=" | ||||
|           - "notin" | ||||
|           - "exists" | ||||
|           - "gt" | ||||
|           - "lt" | ||||
|       RuleAction: | ||||
|         type: "string" | ||||
|         description: "RuleAction controls whether the action is to add or remove a label from the matching object(s)." | ||||
|         enum: | ||||
|           - "add" | ||||
|           - "remove" | ||||
|         default: "add" | ||||
|       Selectors: | ||||
|         type: "object" | ||||
|         description: "Selectors defines the list of labels that should trigger a rule." | ||||
|         additionalProperties: | ||||
|           type: "string" | ||||
|       Labels: | ||||
|         type: "object" | ||||
|         description: "Labels define the list of labels that will be added or removed from the matching object(s).." | ||||
|         additionalProperties: | ||||
|           type: "string" | ||||
|  | ||||
|   CapacityStats: | ||||
|     type: "object" | ||||
|     description: "CapacityStats is used to report capacity statistics on pools and controllers." | ||||
|     properties: | ||||
|       TotalCapacityBytes: | ||||
|         description: "TotalCapacityBytes is the object's total capacity in bytes." | ||||
|         type: "integer" | ||||
|         readOnly: true | ||||
|       AvailableCapacityBytes: | ||||
|         description: "AvailableCapacityBytes is the object's available capacity in bytes." | ||||
|         type: "integer" | ||||
|         readOnly: true | ||||
|       ProvisionedCapacityBytes: | ||||
|         description: "ProvisionedCapacityBytes is the object's provisioned capacity in bytes." | ||||
|         type: "integer" | ||||
|         readOnly: true | ||||
|  | ||||
|   DriverInstances: | ||||
|     type: "object" | ||||
|     description: "DriverInstances shows the internal configuration and state of each driver on all the nodes in the pool. Data within DriverInstances can not be modified directly." | ||||
|     properties: | ||||
|       ID: | ||||
|         description: "Instance unique ID." | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         readOnly: true | ||||
|       Name: | ||||
|         description: "Instance name." | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         readOnly: true | ||||
|       Description: | ||||
|         description: "Instance description." | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         readOnly: true | ||||
|       Active: | ||||
|         description: "Flag describing whether the template is active." | ||||
|         type: "boolean" | ||||
|         x-nullable: false | ||||
|         readOnly: true | ||||
|       Config: | ||||
|         description: "Config is JSON struct that is passed directly to the driver.  There is no specific format, and the driver is responsible for validation." | ||||
|         type: "object" | ||||
|         readOnly: true | ||||
|         additionalProperties: | ||||
|           type: "string" | ||||
|       Labels: | ||||
|         description: "Labels define a list of labels that describe the driver instance.  These are inherited from the pool when the driver instance is created." | ||||
|         type: "object" | ||||
|         readOnly: true | ||||
|         additionalProperties: | ||||
|           type: "string" | ||||
|       ControllerName: | ||||
|         description: "ControllerName specifies the controller that this instance is running on." | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         readOnly: true | ||||
|       PoolID: | ||||
|         description: "PoolID refers to the pool that this driver instance relates to." | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         readOnly: true | ||||
|       DriverName: | ||||
|         description: "DriverName specifies which capacity driver this is an instance of." | ||||
|         type: "string" | ||||
|         x-nullable: false | ||||
|         readOnly: true | ||||
|       CapacityStats: | ||||
|         $ref: "#/definitions/CapacityStats" | ||||
|  | ||||
| parameters: | ||||
|   Name: | ||||
|     name: "name" | ||||
|     in: "path" | ||||
|     type: "string" | ||||
|     description: "Volume name or ID." | ||||
|     required: true | ||||
|   Namespace: | ||||
|     name: "namespace" | ||||
|     in: "path" | ||||
|     type: "string" | ||||
|     description: "Object name and auth scope, such as for teams and projects." | ||||
|     required: true | ||||
|   NamespaceQuery: | ||||
|     name: "namespace" | ||||
|     in: "query" | ||||
|     type: "string" | ||||
|     description: "Object name and auth scope, such as for teams and projects." | ||||
|     default: "default" | ||||
|   LabelSelector: | ||||
|     name: "labelSelector" | ||||
|     in: "query" | ||||
|     description: "A selector to restrict the list of returned objects by their labels. Defaults to everything." | ||||
|     type: "string" | ||||
|   FieldSelector: | ||||
|     name: "fieldSelector" | ||||
|     in: "query" | ||||
|     type: "string" | ||||
|     description: "A selector to restrict the list of returned objects by their fields. Defaults to everything." | ||||
|   TimeoutSeconds: | ||||
|     name: "timeoutSeconds" | ||||
|     in: "query" | ||||
|     type: "integer" | ||||
|     description: "Timeout for the list call." | ||||
|  | ||||
| paths: | ||||
|   /namespaces/{namespace}/volumes: | ||||
|     get: | ||||
|       summary: "List volumes" | ||||
|       description: "List of volumes that match the query." | ||||
|       produces: | ||||
|         - "application/json" | ||||
|       tags: ["Volume"] | ||||
|       parameters: | ||||
|         - name: "namespace" | ||||
|           in: "path" | ||||
|           required: true | ||||
|           description: "The object scope, such as for teams and projects." | ||||
|           type: "string" | ||||
|         - $ref: "#/parameters/LabelSelector" | ||||
|         - $ref: "#/parameters/FieldSelector" | ||||
|         - $ref: "#/parameters/TimeoutSeconds" | ||||
|         - $ref: "#/parameters/NamespaceQuery" | ||||
|       responses: | ||||
|         200: | ||||
|           description: "Success" | ||||
|           schema: | ||||
|             type: "array" | ||||
|             items: | ||||
|               $ref: "#/definitions/Volume" | ||||
|         500: | ||||
|           description: "Server error" | ||||
|           schema: | ||||
|             $ref: "#/definitions/ErrorResponse" | ||||
|     post: | ||||
|       summary: "Create volume" | ||||
|       description: "Provisions a new volume." | ||||
|       produces: | ||||
|         - "application/json" | ||||
|       tags: ["Volume"] | ||||
|       parameters: | ||||
|         - $ref: "#/parameters/Namespace" | ||||
|         - name: "VolumeCreateOptions" | ||||
|           in: "body" | ||||
|           schema: | ||||
|             $ref: "#/definitions/VolumeCreateOptions" | ||||
|       responses: | ||||
|         201: | ||||
|           description: "Volume created successfully" | ||||
|           schema: | ||||
|             $ref: "#/definitions/Volume" | ||||
|         401: | ||||
|           description: "Unauthorized" | ||||
|         409: | ||||
|           description: "Volume with name already exists" | ||||
|         500: | ||||
|           description: "Server error" | ||||
|           schema: | ||||
|             $ref: "#/definitions/ErrorResponse" | ||||
|   /namespaces/{namespace}/volumes/{name}: | ||||
|     get: | ||||
|       summary: "Get a volume" | ||||
|       description: "Gets a volume by name or ID.  Returns to whole volume object." | ||||
|       produces: | ||||
|         - "application/json" | ||||
|       tags: ["Volume"] | ||||
|       parameters: | ||||
|         - $ref: "#/parameters/Name" | ||||
|         - $ref: "#/parameters/Namespace" | ||||
|       responses: | ||||
|         200: | ||||
|           description: "Success" | ||||
|           schema: | ||||
|             $ref: "#/definitions/Volume" | ||||
|         401: | ||||
|           description: "Unauthorized" | ||||
|         404: | ||||
|           description: "Not found" | ||||
|           schema: | ||||
|             $ref: "#/definitions/ErrorResponse" | ||||
|         407: | ||||
|           description: "Volume already exists" | ||||
|         500: | ||||
|           description: "Server error" | ||||
|           schema: | ||||
|             $ref: "#/definitions/ErrorResponse" | ||||
|     put: | ||||
|       summary: "Update volume" | ||||
|       description: "Updates an existing volume." | ||||
|       produces: | ||||
|         - "application/json" | ||||
|       tags: ["Volume"] | ||||
|       parameters: | ||||
|         - $ref: "#/parameters/Name" | ||||
|         - $ref: "#/parameters/Namespace" | ||||
|         - name: "VolumeUpdateOptions" | ||||
|           in: "body" | ||||
|           schema: | ||||
|             $ref: "#/definitions/VolumeUpdateOptions" | ||||
|       responses: | ||||
|         200: | ||||
|           description: "Success" | ||||
|           schema: | ||||
|             $ref: "#/definitions/Volume" | ||||
|         401: | ||||
|           description: "Unauthorized" | ||||
|         500: | ||||
|           description: "Server error" | ||||
|           schema: | ||||
|             $ref: "#/definitions/ErrorResponse" | ||||
|     delete: | ||||
|       summary: "Delete volume" | ||||
|       description: "Deletes a volume." | ||||
|       produces: | ||||
|         - "application/json" | ||||
|       tags: ["Volume"] | ||||
|       parameters: | ||||
|         - name: "namespace" | ||||
|           in: "path" | ||||
|           required: true | ||||
|           description: "The object scope, such as for teams and projects." | ||||
|           type: "string" | ||||
|         - name: "name" | ||||
|           in: "path" | ||||
|           required: true | ||||
|           description: "Volume name or ID." | ||||
|           type: "string" | ||||
|       responses: | ||||
|         200: | ||||
|           description: "Success" | ||||
|         401: | ||||
|           description: "Unauthorized" | ||||
|         407: | ||||
|           description: "Volume in use" | ||||
|         500: | ||||
|           description: "Server error" | ||||
|           schema: | ||||
|             $ref: "#/definitions/ErrorResponse" | ||||
|   /namespaces/{namespace}/volumes/{name}/mount: | ||||
|     post: | ||||
|       summary: "Mount volume" | ||||
|       description: "Updates the mount reference for the volume." | ||||
|       produces: | ||||
|         - "application/json" | ||||
|       tags: ["Volume"] | ||||
|       parameters: | ||||
|         - $ref: "#/parameters/Name" | ||||
|         - $ref: "#/parameters/Namespace" | ||||
|         - name: "client" | ||||
|           in: "body" | ||||
|           description: "Hostname of the client mounting the volume" | ||||
|           required: true | ||||
|           schema: | ||||
|             type: "string" | ||||
|       responses: | ||||
|         200: | ||||
|           description: "Success" | ||||
|           schema: | ||||
|             $ref: "#/definitions/Volume" | ||||
|         401: | ||||
|           description: "Unauthorized" | ||||
|         407: | ||||
|           description: "Volume already mounted" | ||||
|         500: | ||||
|           description: "Server error" | ||||
|           schema: | ||||
|             $ref: "#/definitions/ErrorResponse" | ||||
|   /namespaces/{namespace}/volumes/{name}/unmount: | ||||
|     post: | ||||
|       summary: "Mount volume" | ||||
|       description: "Updates the mount reference for the volume." | ||||
|       produces: | ||||
|         - "application/json" | ||||
|       tags: ["Volume"] | ||||
|       parameters: | ||||
|         - $ref: "#/parameters/Name" | ||||
|         - $ref: "#/parameters/Namespace" | ||||
|         - name: "client" | ||||
|           in: "body" | ||||
|           description: "Hostname of the client mounting the volume" | ||||
|           required: true | ||||
|           schema: | ||||
|             type: "string" | ||||
|       responses: | ||||
|         200: | ||||
|           description: "Success" | ||||
|           schema: | ||||
|             $ref: "#/definitions/Volume" | ||||
|         401: | ||||
|           description: "Unauthorized" | ||||
|         407: | ||||
|           description: "Volume not mounted" | ||||
|         500: | ||||
|           description: "Server error" | ||||
|           schema: | ||||
|             $ref: "#/definitions/ErrorResponse" | ||||
|   /pools: | ||||
|     get: | ||||
|       summary: "List pools" | ||||
|       description: "List of pools that match the query." | ||||
|       produces: | ||||
|         - "application/json" | ||||
|       tags: ["Pool"] | ||||
|       #parameters: | ||||
|       #  - $ref: "#/parameters/LabelSelector" | ||||
|       #  - $ref: "#/parameters/FieldSelector" | ||||
|       #  - $ref: "#/parameters/TimeoutSeconds" | ||||
|       #  - $ref: "#/parameters/NamespaceQuery" | ||||
|       responses: | ||||
|         200: | ||||
|           description: "Success" | ||||
|           schema: | ||||
|             type: "array" | ||||
|             items: | ||||
|               $ref: "#/definitions/Pool" | ||||
|         500: | ||||
|           description: "Server error" | ||||
|           schema: | ||||
|             $ref: "#/definitions/ErrorResponse" | ||||
|     post: | ||||
|       summary: "Create pool" | ||||
|       description: "Provisions a new pool." | ||||
|       produces: | ||||
|         - "application/json" | ||||
|       tags: ["Pool"] | ||||
|       parameters: | ||||
|         - name: "PoolCreateOptions" | ||||
|           in: "body" | ||||
|           schema: | ||||
|             $ref: "#/definitions/PoolCreateOptions" | ||||
|       responses: | ||||
|         201: | ||||
|           description: "Pool created successfully" | ||||
|           schema: | ||||
|             $ref: "#/definitions/Pool" | ||||
|         401: | ||||
|           description: "Unauthorized" | ||||
|         409: | ||||
|           description: "Pool with name already exists" | ||||
|         500: | ||||
|           description: "Server error" | ||||
|           schema: | ||||
|             $ref: "#/definitions/ErrorResponse" | ||||
|   /pools/{name}: | ||||
|     get: | ||||
|       summary: "Get a pool" | ||||
|       description: "Gets a pool by name or ID.  Returns to whole pool object." | ||||
|       produces: | ||||
|         - "application/json" | ||||
|       tags: ["Pool"] | ||||
|       parameters: | ||||
|         - $ref: "#/parameters/Name" | ||||
|       responses: | ||||
|         200: | ||||
|           description: "Success" | ||||
|           schema: | ||||
|             $ref: "#/definitions/Pool" | ||||
|         401: | ||||
|           description: "Unauthorized" | ||||
|         404: | ||||
|           description: "Not found" | ||||
|           schema: | ||||
|             $ref: "#/definitions/ErrorResponse" | ||||
|         407: | ||||
|           description: "Pool already exists" | ||||
|         500: | ||||
|           description: "Server error" | ||||
|           schema: | ||||
|             $ref: "#/definitions/ErrorResponse" | ||||
|     delete: | ||||
|       summary: "Delete pool" | ||||
|       description: "Deletes a pool." | ||||
|       produces: | ||||
|         - "application/json" | ||||
|       tags: ["Pool"] | ||||
|       parameters: | ||||
|         - name: "name" | ||||
|           in: "path" | ||||
|           required: true | ||||
|           description: "Pool name or ID." | ||||
|           type: "string" | ||||
|       responses: | ||||
|         200: | ||||
|           description: "Success" | ||||
|         401: | ||||
|           description: "Unauthorized" | ||||
|         407: | ||||
|           description: "Pool in use" | ||||
|         500: | ||||
|           description: "Server error" | ||||
|           schema: | ||||
|             $ref: "#/definitions/ErrorResponse" | ||||
							
								
								
									
										4
									
								
								vendor/github.com/storageos/go-api/types/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/storageos/go-api/types/BUILD
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -13,13 +13,17 @@ go_library( | ||||
|         "error_response.go", | ||||
|         "events.go", | ||||
|         "list_options.go", | ||||
|         "logger.go", | ||||
|         "namespace.go", | ||||
|         "node.go", | ||||
|         "operator.go", | ||||
|         "policy.go", | ||||
|         "pool.go", | ||||
|         "pool_create_options.go", | ||||
|         "rule.go", | ||||
|         "template.go", | ||||
|         "template_create_options.go", | ||||
|         "user.go", | ||||
|         "version.go", | ||||
|         "volume.go", | ||||
|         "volume_create_options.go", | ||||
|   | ||||
							
								
								
									
										4
									
								
								vendor/github.com/storageos/go-api/types/controller.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/storageos/go-api/types/controller.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -41,6 +41,7 @@ type Controller struct { | ||||
| 	Scheduler        bool                   `json:"scheduler"` | ||||
| 	Name             string                 `json:"name"` | ||||
| 	Address          string                 `json:"address"` | ||||
| 	DeviceDir        string                 `json:"deviceDir"` | ||||
| 	APIPort          int                    `json:"apiPort"` | ||||
| 	NatsPort         int                    `json:"natsPort"` | ||||
| 	NatsClusterPort  int                    `json:"natsClusterPort"` | ||||
| @@ -59,6 +60,9 @@ type Controller struct { | ||||
| 	VersionInfo     map[string]VersionInfo `json:"versionInfo"` | ||||
| 	Version         string                 `json:"version"` | ||||
|  | ||||
| 	// Cordon true if in an unschedulable state | ||||
| 	Cordon bool `json:"unschedulable"` | ||||
|  | ||||
| 	// high level stats that combine info from all driver instances | ||||
| 	CapacityStats CapacityStats `json:"capacityStats"` | ||||
| } | ||||
|   | ||||
							
								
								
									
										3
									
								
								vendor/github.com/storageos/go-api/types/controller_update_options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/storageos/go-api/types/controller_update_options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -19,6 +19,9 @@ type ControllerUpdateOptions struct { | ||||
| 	// Labels are user-defined key/value metadata. | ||||
| 	Labels map[string]string `json:"labels"` | ||||
|  | ||||
| 	// Cordon sets the controler into an unschedulable state if true | ||||
| 	Cordon bool `json:"unschedulable"` | ||||
|  | ||||
| 	// Context can be set with a timeout or can be used to cancel a request. | ||||
| 	Context context.Context `json:"-"` | ||||
| } | ||||
|   | ||||
							
								
								
									
										4
									
								
								vendor/github.com/storageos/go-api/types/deployment.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/storageos/go-api/types/deployment.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -18,6 +18,10 @@ type Deployment struct { | ||||
| 	// Read Only: true | ||||
| 	Controller string `json:"controller"` | ||||
|  | ||||
| 	// Controller name | ||||
| 	// Read Only: true | ||||
| 	ControllerName string `json:"controllerName"` | ||||
|  | ||||
| 	// Health | ||||
| 	// Read Only: true | ||||
| 	Health string `json:"health"` | ||||
|   | ||||
							
								
								
									
										40
									
								
								vendor/github.com/storageos/go-api/types/logger.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								vendor/github.com/storageos/go-api/types/logger.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| package types | ||||
|  | ||||
| import "context" | ||||
|  | ||||
| // Logger is the runtime configuration of the node's logging services. | ||||
| // swagger:model Logger | ||||
| type Logger struct { | ||||
|  | ||||
| 	// Node name | ||||
| 	Node string `json:"node"` | ||||
|  | ||||
| 	// Log level | ||||
| 	Level string `json:"level"` | ||||
|  | ||||
| 	// Log filter | ||||
| 	Filter string `json:"filter"` | ||||
|  | ||||
| 	// Log filters by category | ||||
| 	// Read Only: true | ||||
| 	Categories map[string]string `json:"categories"` | ||||
| } | ||||
|  | ||||
| // LoggerUpdateOptions are the available parameters for updating loggers. | ||||
| type LoggerUpdateOptions struct { | ||||
|  | ||||
| 	// Log level | ||||
| 	Level string `json:"level"` | ||||
|  | ||||
| 	// Log filter | ||||
| 	Filter string `json:"filter"` | ||||
|  | ||||
| 	// List of nodes to update.  All if not set. | ||||
| 	Nodes []string `json:"nodes"` | ||||
|  | ||||
| 	// List of fields to update.  Must be set. | ||||
| 	Fields []string `json:"fields"` | ||||
|  | ||||
| 	// Context can be set with a timeout or can be used to cancel a request. | ||||
| 	Context context.Context `json:"-"` | ||||
| } | ||||
							
								
								
									
										97
									
								
								vendor/github.com/storageos/go-api/types/node.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								vendor/github.com/storageos/go-api/types/node.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| package types | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| ) | ||||
|  | ||||
| type SubModuleStatus struct { | ||||
| 	Status    string `json:"status"` | ||||
| 	UpdatedAt string `json:"updatedAt"` | ||||
| 	ChangedAt string `json:"changedAt"` | ||||
| 	Message   string `json:"message"` | ||||
| } | ||||
|  | ||||
| type NamedSubModuleStatus struct { | ||||
| 	Name string | ||||
| 	SubModuleStatus | ||||
| } | ||||
|  | ||||
| type CPHealthStatus struct { | ||||
| 	KV        SubModuleStatus | ||||
| 	KVWrite   SubModuleStatus | ||||
| 	NATS      SubModuleStatus | ||||
| 	Scheduler SubModuleStatus | ||||
| } | ||||
|  | ||||
| func (c *CPHealthStatus) ToNamedSubmodules() []NamedSubModuleStatus { | ||||
| 	return []NamedSubModuleStatus{ | ||||
| 		{Name: "nats", SubModuleStatus: c.NATS}, | ||||
| 		{Name: "kv", SubModuleStatus: c.KV}, | ||||
| 		{Name: "kv_write", SubModuleStatus: c.KVWrite}, | ||||
| 		{Name: "scheduler", SubModuleStatus: c.Scheduler}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (c *CPHealthStatus) UnmarshalJSON(data []byte) error { | ||||
| 	unmarsh := struct { | ||||
| 		Submodules struct { | ||||
| 			KV        SubModuleStatus `json:"kv"` | ||||
| 			KVWrite   SubModuleStatus `json:"kv_write"` | ||||
| 			NATS      SubModuleStatus `json:"nats"` | ||||
| 			Scheduler SubModuleStatus `json:"scheduler"` | ||||
| 		} `json:"submodules"` | ||||
| 	}{} | ||||
|  | ||||
| 	if err := json.Unmarshal(data, &unmarsh); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	c.KV = unmarsh.Submodules.KV | ||||
| 	c.KVWrite = unmarsh.Submodules.KVWrite | ||||
| 	c.NATS = unmarsh.Submodules.NATS | ||||
| 	c.Scheduler = unmarsh.Submodules.Scheduler | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type DPHealthStatus struct { | ||||
| 	DirectFSClient SubModuleStatus | ||||
| 	DirectFSServer SubModuleStatus | ||||
| 	Director       SubModuleStatus | ||||
| 	FSDriver       SubModuleStatus | ||||
| 	FS             SubModuleStatus | ||||
| } | ||||
|  | ||||
| func (d *DPHealthStatus) ToNamedSubmodules() []NamedSubModuleStatus { | ||||
| 	return []NamedSubModuleStatus{ | ||||
| 		{Name: "dfs_client", SubModuleStatus: d.DirectFSClient}, | ||||
| 		{Name: "dfs_server", SubModuleStatus: d.DirectFSServer}, | ||||
| 		{Name: "director", SubModuleStatus: d.Director}, | ||||
| 		{Name: "fs_driver", SubModuleStatus: d.FSDriver}, | ||||
| 		{Name: "fs", SubModuleStatus: d.FS}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (d *DPHealthStatus) UnmarshalJSON(data []byte) error { | ||||
| 	unmarsh := struct { | ||||
| 		Submodules struct { | ||||
| 			DirectFSClient SubModuleStatus `json:"directfs-client"` | ||||
| 			DirectFSServer SubModuleStatus `json:"directfs-server"` | ||||
| 			Director       SubModuleStatus `json:"director"` | ||||
| 			FSDriver       SubModuleStatus `json:"filesystem-driver"` | ||||
| 			FS             SubModuleStatus `json:"fs"` | ||||
| 		} `json:"submodules"` | ||||
| 	}{} | ||||
|  | ||||
| 	if err := json.Unmarshal(data, &unmarsh); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	d.DirectFSClient = unmarsh.Submodules.DirectFSClient | ||||
| 	d.DirectFSServer = unmarsh.Submodules.DirectFSServer | ||||
| 	d.Director = unmarsh.Submodules.Director | ||||
| 	d.FSDriver = unmarsh.Submodules.FSDriver | ||||
| 	d.FS = unmarsh.Submodules.FS | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										45
									
								
								vendor/github.com/storageos/go-api/types/policy.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								vendor/github.com/storageos/go-api/types/policy.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| package types | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| ) | ||||
|  | ||||
| type Policy struct { | ||||
| 	Spec struct { | ||||
| 		User            string `json:"user,omitempty"` | ||||
| 		Group           string `json:"group,omitempty"` | ||||
| 		Readonly        bool   `json:"readonly,omitempty"` | ||||
| 		APIGroup        string `json:"apiGroup,omitempty"` | ||||
| 		Resource        string `json:"resource,omitempty"` | ||||
| 		Namespace       string `json:"namespace,omitempty"` | ||||
| 		NonResourcePath string `json:"nonResourcePath,omitempty"` | ||||
| 	} `json:"spec"` | ||||
| } | ||||
|  | ||||
| // PolicyWithId is used as an internal type to render table formated versions of the json response | ||||
| type PolicyWithID struct { | ||||
| 	Policy | ||||
| 	ID string | ||||
| } | ||||
|  | ||||
| // MarshalJSON returns a marshaled copy of the internal policy object, so it is still valid to use | ||||
| // with the REST API | ||||
| func (p *PolicyWithID) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(p.Policy) | ||||
| } | ||||
|  | ||||
| // PolicySet is a representation of the data structure returned from the REST API | ||||
| type PolicySet map[string]Policy | ||||
|  | ||||
| func (p PolicySet) GetPoliciesWithID() []*PolicyWithID { | ||||
| 	rtn := make([]*PolicyWithID, 0, len(p)) | ||||
|  | ||||
| 	for k, v := range p { | ||||
| 		rtn = append(rtn, &PolicyWithID{ | ||||
| 			Policy: v, | ||||
| 			ID:     k, | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| 	return rtn | ||||
| } | ||||
							
								
								
									
										79
									
								
								vendor/github.com/storageos/go-api/types/user.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								vendor/github.com/storageos/go-api/types/user.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| package types | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	"strings" | ||||
| ) | ||||
|  | ||||
| type User struct { | ||||
| 	UUID     string   `json:"id"` | ||||
| 	Username string   `json:"username"` | ||||
| 	Groups   []string `json:"groups"` | ||||
| 	Password string   `json:"password,omitempty"` | ||||
| 	Role     string   `json:"role"` | ||||
| } | ||||
|  | ||||
| func (u *User) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(&struct { | ||||
| 		UUID     string `json:"id"` | ||||
| 		Username string `json:"username"` | ||||
| 		Groups   string `json:"groups"` | ||||
| 		Password string `json:"password,omitempty"` | ||||
| 		Role     string `json:"role"` | ||||
| 	}{ | ||||
| 		UUID:     u.UUID, | ||||
| 		Username: u.Username, | ||||
| 		Groups:   strings.Join(u.Groups, ","), | ||||
| 		Password: u.Password, | ||||
| 		Role:     u.Role, | ||||
| 	}) | ||||
|  | ||||
| } | ||||
|  | ||||
| func (u *User) UnmarshalJSON(data []byte) error { | ||||
| 	temp := &struct { | ||||
| 		UUID     string `json:"id"` | ||||
| 		Username string `json:"username"` | ||||
| 		Groups   string `json:"groups"` | ||||
| 		Password string `json:"password"` | ||||
| 		Role     string `json:"role"` | ||||
| 	}{} | ||||
|  | ||||
| 	if err := json.Unmarshal(data, temp); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	u.UUID = temp.UUID | ||||
| 	u.Username = temp.Username | ||||
| 	u.Password = temp.Password | ||||
| 	u.Role = temp.Role | ||||
| 	u.Groups = strings.Split(temp.Groups, ",") | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| type UserCreateOptions struct { | ||||
| 	Username string   `json:"username"` | ||||
| 	Groups   []string `json:"groups"` | ||||
| 	Password string   `json:"password"` | ||||
| 	Role     string   `json:"role"` | ||||
|  | ||||
| 	// Context can be set with a timeout or can be used to cancel a request. | ||||
| 	Context context.Context `json:"-"` | ||||
| } | ||||
|  | ||||
| func (u UserCreateOptions) MarshalJSON() ([]byte, error) { | ||||
| 	return json.Marshal(&struct { | ||||
| 		Username string `json:"username"` | ||||
| 		Groups   string `json:"groups"` | ||||
| 		Password string `json:"password"` | ||||
| 		Role     string `json:"role"` | ||||
| 	}{ | ||||
| 		Username: u.Username, | ||||
| 		Groups:   strings.Join(u.Groups, ","), | ||||
| 		Password: u.Password, | ||||
| 		Role:     u.Role, | ||||
| 	}) | ||||
|  | ||||
| } | ||||
							
								
								
									
										10
									
								
								vendor/github.com/storageos/go-api/types/volume.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/storageos/go-api/types/volume.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -43,6 +43,9 @@ type Volume struct { | ||||
| 	// Namespace is the object name and authentication scope, such as for teams and projects. | ||||
| 	Namespace string `json:"namespace"` | ||||
|  | ||||
| 	// node selector (where volumes should land) | ||||
| 	NodeSelector string `json:"nodeSelector"` | ||||
|  | ||||
| 	// Volume deployment information for the master volume. | ||||
| 	// Read Only: true | ||||
| 	Master *Deployment `json:"master,omitempty"` | ||||
| @@ -51,6 +54,9 @@ type Volume struct { | ||||
| 	// Read Only: true | ||||
| 	Mounted bool `json:"mounted"` | ||||
|  | ||||
| 	// MountDevice, where the device is located | ||||
| 	MountDevice string `json:"mountDevice"` | ||||
|  | ||||
| 	// Mountpoint, where the volume is mounted | ||||
| 	Mountpoint string `json:"mountpoint"` | ||||
|  | ||||
| @@ -78,6 +84,10 @@ type Volume struct { | ||||
| 	// Read Only: true | ||||
| 	StatusMessage string `json:"statusMessage"` | ||||
|  | ||||
| 	// mkfs performed on new volumes | ||||
| 	MkfsDone   bool      `json:"mkfsDone"` | ||||
| 	MkfsDoneAt time.Time `json:"mkfsDoneAt"` | ||||
|  | ||||
| 	// When the volume was created. | ||||
| 	// Read Only: true | ||||
| 	CreatedAt time.Time `json:"createdAt"` | ||||
|   | ||||
							
								
								
									
										3
									
								
								vendor/github.com/storageos/go-api/types/volume_create_options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/storageos/go-api/types/volume_create_options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -25,6 +25,9 @@ type VolumeCreateOptions struct { | ||||
| 	// Namespace is the object scope, such as for teams and projects. | ||||
| 	Namespace string `json:"namespace"` | ||||
|  | ||||
| 	// node selector (where volumes should land) | ||||
| 	NodeSelector string `json:"nodeSelector"` | ||||
|  | ||||
| 	// Labels are user-defined key/value metadata. | ||||
| 	Labels map[string]string `json:"labels"` | ||||
|  | ||||
|   | ||||
							
								
								
									
										3
									
								
								vendor/github.com/storageos/go-api/types/volume_update_options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/storageos/go-api/types/volume_update_options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -23,6 +23,9 @@ type VolumeUpdateOptions struct { | ||||
| 	// Namespace is the object scope, such as for teams and projects. | ||||
| 	Namespace string `json:"namespace"` | ||||
|  | ||||
| 	// node selector (where volumes should land) | ||||
| 	NodeSelector string `json:"nodeSelector"` | ||||
|  | ||||
| 	// Labels are user-defined key/value metadata. | ||||
| 	Labels map[string]string `json:"labels"` | ||||
|  | ||||
|   | ||||
							
								
								
									
										119
									
								
								vendor/github.com/storageos/go-api/user.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								vendor/github.com/storageos/go-api/user.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| package storageos | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
|  | ||||
| 	"github.com/storageos/go-api/types" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
|  | ||||
| 	// UserAPIPrefix is a partial path to the HTTP endpoint. | ||||
| 	UserAPIPrefix = "users" | ||||
|  | ||||
| 	// ErrNoSuchUser is the error returned when the user does not exist. | ||||
| 	ErrNoSuchUser = errors.New("no such user") | ||||
| ) | ||||
|  | ||||
| // UserList returns the list of available users. | ||||
| func (c *Client) UserList(opts types.ListOptions) ([]*types.User, error) { | ||||
| 	listOpts := doOptions{ | ||||
| 		fieldSelector: opts.FieldSelector, | ||||
| 		labelSelector: opts.LabelSelector, | ||||
| 		namespace:     opts.Namespace, | ||||
| 		context:       opts.Context, | ||||
| 	} | ||||
|  | ||||
| 	if opts.LabelSelector != "" { | ||||
| 		query := url.Values{} | ||||
| 		query.Add("labelSelector", opts.LabelSelector) | ||||
| 		listOpts.values = query | ||||
| 	} | ||||
|  | ||||
| 	resp, err := c.do("GET", UserAPIPrefix, listOpts) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	users := make([]*types.User, 0) | ||||
| 	if err := json.NewDecoder(resp.Body).Decode(&users); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return users, nil | ||||
| } | ||||
|  | ||||
| // User returns a user by its username/id. | ||||
| func (c *Client) User(username string) (*types.User, error) { | ||||
| 	path := fmt.Sprintf("%s/%s", UserAPIPrefix, username) | ||||
| 	resp, err := c.do("GET", path, doOptions{}) | ||||
| 	if err != nil { | ||||
| 		if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { | ||||
| 			return nil, ErrNoSuchUser | ||||
| 		} | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	var user *types.User | ||||
| 	if err := json.NewDecoder(resp.Body).Decode(&user); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return user, nil | ||||
| } | ||||
|  | ||||
| // UserCreate creates a user on the server. | ||||
| func (c *Client) UserCreate(opts types.UserCreateOptions) error { | ||||
| 	_, err := c.do("POST", UserAPIPrefix, doOptions{ | ||||
| 		data:    opts, | ||||
| 		context: opts.Context, | ||||
| 	}) | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // UserUpdate updates a user on the server. | ||||
| func (c *Client) UserUpdate(user *types.User, ctx context.Context) error { | ||||
| 	var ref string | ||||
| 	switch { | ||||
| 	case user.UUID != "": | ||||
| 		ref = user.UUID | ||||
| 	case user.Username != "": | ||||
| 		ref = user.Username | ||||
| 	default: | ||||
| 		return ErrNoSuchUser | ||||
| 	} | ||||
|  | ||||
| 	path := fmt.Sprintf("%s/%s", UserAPIPrefix, ref) | ||||
| 	resp, err := c.do("POST", path, doOptions{ | ||||
| 		data:    user, | ||||
| 		context: ctx, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		if e, ok := err.(*Error); ok && e.Status == http.StatusNotFound { | ||||
| 			return ErrNoSuchUser | ||||
| 		} | ||||
| 		return err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // UserDelete removes a user by its reference. | ||||
| func (c *Client) UserDelete(opts types.DeleteOptions) error { | ||||
| 	resp, err := c.do("DELETE", UserAPIPrefix+"/"+opts.Name, doOptions{}) | ||||
| 	if err != nil { | ||||
| 		if e, ok := err.(*Error); ok { | ||||
| 			if e.Status == http.StatusNotFound { | ||||
| 				return ErrNoSuchUser | ||||
| 			} | ||||
| 		} | ||||
| 		return err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
| 	return nil | ||||
| } | ||||
		Reference in New Issue
	
	Block a user