aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/Azure/azure-sdk-for-go/storage/file.go')
-rw-r--r--vendor/github.com/Azure/azure-sdk-for-go/storage/file.go352
1 files changed, 352 insertions, 0 deletions
diff --git a/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go b/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go
new file mode 100644
index 000000000..2397587c8
--- /dev/null
+++ b/vendor/github.com/Azure/azure-sdk-for-go/storage/file.go
@@ -0,0 +1,352 @@
+package storage
+
+import (
+ "encoding/xml"
+ "fmt"
+ "net/http"
+ "net/url"
+ "strings"
+)
+
+// FileServiceClient contains operations for Microsoft Azure File Service.
+type FileServiceClient struct {
+ client Client
+}
+
+// A Share is an entry in ShareListResponse.
+type Share struct {
+ Name string `xml:"Name"`
+ Properties ShareProperties `xml:"Properties"`
+}
+
+// ShareProperties contains various properties of a share returned from
+// various endpoints like ListShares.
+type ShareProperties struct {
+ LastModified string `xml:"Last-Modified"`
+ Etag string `xml:"Etag"`
+ Quota string `xml:"Quota"`
+}
+
+// ShareListResponse contains the response fields from
+// ListShares call.
+//
+// See https://msdn.microsoft.com/en-us/library/azure/dn167009.aspx
+type ShareListResponse struct {
+ XMLName xml.Name `xml:"EnumerationResults"`
+ Xmlns string `xml:"xmlns,attr"`
+ Prefix string `xml:"Prefix"`
+ Marker string `xml:"Marker"`
+ NextMarker string `xml:"NextMarker"`
+ MaxResults int64 `xml:"MaxResults"`
+ Shares []Share `xml:"Shares>Share"`
+}
+
+// ListSharesParameters defines the set of customizable parameters to make a
+// List Shares call.
+//
+// See https://msdn.microsoft.com/en-us/library/azure/dn167009.aspx
+type ListSharesParameters struct {
+ Prefix string
+ Marker string
+ Include string
+ MaxResults uint
+ Timeout uint
+}
+
+// ShareHeaders contains various properties of a file and is an entry
+// in SetShareProperties
+type ShareHeaders struct {
+ Quota string `header:"x-ms-share-quota"`
+}
+
+func (p ListSharesParameters) getParameters() url.Values {
+ out := url.Values{}
+
+ if p.Prefix != "" {
+ out.Set("prefix", p.Prefix)
+ }
+ if p.Marker != "" {
+ out.Set("marker", p.Marker)
+ }
+ if p.Include != "" {
+ out.Set("include", p.Include)
+ }
+ if p.MaxResults != 0 {
+ out.Set("maxresults", fmt.Sprintf("%v", p.MaxResults))
+ }
+ if p.Timeout != 0 {
+ out.Set("timeout", fmt.Sprintf("%v", p.Timeout))
+ }
+
+ return out
+}
+
+// pathForFileShare returns the URL path segment for a File Share resource
+func pathForFileShare(name string) string {
+ return fmt.Sprintf("/%s", name)
+}
+
+// ListShares returns the list of shares in a storage account along with
+// pagination token and other response details.
+//
+// See https://msdn.microsoft.com/en-us/library/azure/dd179352.aspx
+func (f FileServiceClient) ListShares(params ListSharesParameters) (ShareListResponse, error) {
+ q := mergeParams(params.getParameters(), url.Values{"comp": {"list"}})
+ uri := f.client.getEndpoint(fileServiceName, "", q)
+ headers := f.client.getStandardHeaders()
+
+ var out ShareListResponse
+ resp, err := f.client.exec("GET", uri, headers, nil)
+ if err != nil {
+ return out, err
+ }
+ defer resp.body.Close()
+
+ err = xmlUnmarshal(resp.body, &out)
+ return out, err
+}
+
+// CreateShare operation creates a new share under the specified account. If the
+// share with the same name already exists, the operation fails.
+//
+// See https://msdn.microsoft.com/en-us/library/azure/dn167008.aspx
+func (f FileServiceClient) CreateShare(name string) error {
+ resp, err := f.createShare(name)
+ if err != nil {
+ return err
+ }
+ defer resp.body.Close()
+ return checkRespCode(resp.statusCode, []int{http.StatusCreated})
+}
+
+// ShareExists returns true if a share with given name exists
+// on the storage account, otherwise returns false.
+func (f FileServiceClient) ShareExists(name string) (bool, error) {
+ uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), url.Values{"restype": {"share"}})
+ headers := f.client.getStandardHeaders()
+
+ resp, err := f.client.exec("HEAD", uri, headers, nil)
+ if resp != nil {
+ defer resp.body.Close()
+ if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound {
+ return resp.statusCode == http.StatusOK, nil
+ }
+ }
+ return false, err
+}
+
+// GetShareURL gets the canonical URL to the share with the specified name in the
+// specified container. This method does not create a publicly accessible URL if
+// the file is private and this method does not check if the file
+// exists.
+func (f FileServiceClient) GetShareURL(name string) string {
+ return f.client.getEndpoint(fileServiceName, pathForFileShare(name), url.Values{})
+}
+
+// CreateShareIfNotExists creates a new share under the specified account if
+// it does not exist. Returns true if container is newly created or false if
+// container already exists.
+//
+// See https://msdn.microsoft.com/en-us/library/azure/dn167008.aspx
+func (f FileServiceClient) CreateShareIfNotExists(name string) (bool, error) {
+ resp, err := f.createShare(name)
+ if resp != nil {
+ defer resp.body.Close()
+ if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict {
+ return resp.statusCode == http.StatusCreated, nil
+ }
+ }
+ return false, err
+}
+
+// CreateShare creates a Azure File Share and returns its response
+func (f FileServiceClient) createShare(name string) (*storageResponse, error) {
+ if err := f.checkForStorageEmulator(); err != nil {
+ return nil, err
+ }
+ uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), url.Values{"restype": {"share"}})
+ headers := f.client.getStandardHeaders()
+ return f.client.exec("PUT", uri, headers, nil)
+}
+
+// GetShareProperties provides various information about the specified
+// file. See https://msdn.microsoft.com/en-us/library/azure/dn689099.aspx
+func (f FileServiceClient) GetShareProperties(name string) (*ShareProperties, error) {
+ uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), url.Values{"restype": {"share"}})
+
+ headers := f.client.getStandardHeaders()
+ resp, err := f.client.exec("HEAD", uri, headers, nil)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.body.Close()
+
+ if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
+ return nil, err
+ }
+
+ return &ShareProperties{
+ LastModified: resp.headers.Get("Last-Modified"),
+ Etag: resp.headers.Get("Etag"),
+ Quota: resp.headers.Get("x-ms-share-quota"),
+ }, nil
+}
+
+// SetShareProperties replaces the ShareHeaders for the specified file.
+//
+// Some keys may be converted to Camel-Case before sending. All keys
+// are returned in lower case by SetShareProperties. HTTP header names
+// are case-insensitive so case munging should not matter to other
+// applications either.
+//
+// See https://msdn.microsoft.com/en-us/library/azure/mt427368.aspx
+func (f FileServiceClient) SetShareProperties(name string, shareHeaders ShareHeaders) error {
+ params := url.Values{}
+ params.Set("restype", "share")
+ params.Set("comp", "properties")
+
+ uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), params)
+ headers := f.client.getStandardHeaders()
+
+ extraHeaders := headersFromStruct(shareHeaders)
+
+ for k, v := range extraHeaders {
+ headers[k] = v
+ }
+
+ resp, err := f.client.exec("PUT", uri, headers, nil)
+ if err != nil {
+ return err
+ }
+ defer resp.body.Close()
+
+ return checkRespCode(resp.statusCode, []int{http.StatusOK})
+}
+
+// DeleteShare operation marks the specified share for deletion. The share
+// and any files contained within it are later deleted during garbage
+// collection.
+//
+// See https://msdn.microsoft.com/en-us/library/azure/dn689090.aspx
+func (f FileServiceClient) DeleteShare(name string) error {
+ resp, err := f.deleteShare(name)
+ if err != nil {
+ return err
+ }
+ defer resp.body.Close()
+ return checkRespCode(resp.statusCode, []int{http.StatusAccepted})
+}
+
+// DeleteShareIfExists operation marks the specified share for deletion if it
+// exists. The share and any files contained within it are later deleted during
+// garbage collection. Returns true if share existed and deleted with this call,
+// false otherwise.
+//
+// See https://msdn.microsoft.com/en-us/library/azure/dn689090.aspx
+func (f FileServiceClient) DeleteShareIfExists(name string) (bool, error) {
+ resp, err := f.deleteShare(name)
+ if resp != nil {
+ defer resp.body.Close()
+ if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound {
+ return resp.statusCode == http.StatusAccepted, nil
+ }
+ }
+ return false, err
+}
+
+// deleteShare makes the call to Delete Share operation endpoint and returns
+// the response
+func (f FileServiceClient) deleteShare(name string) (*storageResponse, error) {
+ if err := f.checkForStorageEmulator(); err != nil {
+ return nil, err
+ }
+ uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), url.Values{"restype": {"share"}})
+ return f.client.exec("DELETE", uri, f.client.getStandardHeaders(), nil)
+}
+
+// SetShareMetadata replaces the metadata for the specified Share.
+//
+// Some keys may be converted to Camel-Case before sending. All keys
+// are returned in lower case by GetShareMetadata. HTTP header names
+// are case-insensitive so case munging should not matter to other
+// applications either.
+//
+// See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx
+func (f FileServiceClient) SetShareMetadata(name string, metadata map[string]string, extraHeaders map[string]string) error {
+ params := url.Values{}
+ params.Set("restype", "share")
+ params.Set("comp", "metadata")
+
+ uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), params)
+ headers := f.client.getStandardHeaders()
+ for k, v := range metadata {
+ headers[userDefinedMetadataHeaderPrefix+k] = v
+ }
+
+ for k, v := range extraHeaders {
+ headers[k] = v
+ }
+
+ resp, err := f.client.exec("PUT", uri, headers, nil)
+ if err != nil {
+ return err
+ }
+ defer resp.body.Close()
+
+ return checkRespCode(resp.statusCode, []int{http.StatusOK})
+}
+
+// GetShareMetadata returns all user-defined metadata for the specified share.
+//
+// All metadata keys will be returned in lower case. (HTTP header
+// names are case-insensitive.)
+//
+// See https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx
+func (f FileServiceClient) GetShareMetadata(name string) (map[string]string, error) {
+ params := url.Values{}
+ params.Set("restype", "share")
+ params.Set("comp", "metadata")
+
+ uri := f.client.getEndpoint(fileServiceName, pathForFileShare(name), params)
+ headers := f.client.getStandardHeaders()
+
+ resp, err := f.client.exec("GET", uri, headers, nil)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.body.Close()
+
+ if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
+ return nil, err
+ }
+
+ metadata := make(map[string]string)
+ for k, v := range resp.headers {
+ // Can't trust CanonicalHeaderKey() to munge case
+ // reliably. "_" is allowed in identifiers:
+ // https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx
+ // https://msdn.microsoft.com/library/aa664670(VS.71).aspx
+ // http://tools.ietf.org/html/rfc7230#section-3.2
+ // ...but "_" is considered invalid by
+ // CanonicalMIMEHeaderKey in
+ // https://golang.org/src/net/textproto/reader.go?s=14615:14659#L542
+ // so k can be "X-Ms-Meta-Foo" or "x-ms-meta-foo_bar".
+ k = strings.ToLower(k)
+ if len(v) == 0 || !strings.HasPrefix(k, strings.ToLower(userDefinedMetadataHeaderPrefix)) {
+ continue
+ }
+ // metadata["foo"] = content of the last X-Ms-Meta-Foo header
+ k = k[len(userDefinedMetadataHeaderPrefix):]
+ metadata[k] = v[len(v)-1]
+ }
+ return metadata, nil
+}
+
+//checkForStorageEmulator determines if the client is setup for use with
+//Azure Storage Emulator, and returns a relevant error
+func (f FileServiceClient) checkForStorageEmulator() error {
+ if f.client.accountName == StorageEmulatorAccountName {
+ return fmt.Errorf("Error: File service is not currently supported by Azure Storage Emulator")
+ }
+ return nil
+}