206 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			206 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Go
		
	
	
| package storage
 | |
| 
 | |
| // Copyright (c) Microsoft Corporation. All rights reserved.
 | |
| // Licensed under the MIT License. See License.txt in the project root for license information.
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"net/http"
 | |
| 	"net/url"
 | |
| 	"strconv"
 | |
| )
 | |
| 
 | |
| // Share represents an Azure file share.
 | |
| type Share struct {
 | |
| 	fsc        *FileServiceClient
 | |
| 	Name       string          `xml:"Name"`
 | |
| 	Properties ShareProperties `xml:"Properties"`
 | |
| 	Metadata   map[string]string
 | |
| }
 | |
| 
 | |
| // ShareProperties contains various properties of a share.
 | |
| type ShareProperties struct {
 | |
| 	LastModified string `xml:"Last-Modified"`
 | |
| 	Etag         string `xml:"Etag"`
 | |
| 	Quota        int    `xml:"Quota"`
 | |
| }
 | |
| 
 | |
| // builds the complete path for this share object.
 | |
| func (s *Share) buildPath() string {
 | |
| 	return fmt.Sprintf("/%s", s.Name)
 | |
| }
 | |
| 
 | |
| // Create this share under the associated account.
 | |
| // If a share with the same name already exists, the operation fails.
 | |
| //
 | |
| // See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Create-Share
 | |
| func (s *Share) Create(options *FileRequestOptions) error {
 | |
| 	extraheaders := map[string]string{}
 | |
| 	if s.Properties.Quota > 0 {
 | |
| 		extraheaders["x-ms-share-quota"] = strconv.Itoa(s.Properties.Quota)
 | |
| 	}
 | |
| 
 | |
| 	params := prepareOptions(options)
 | |
| 	headers, err := s.fsc.createResource(s.buildPath(), resourceShare, params, mergeMDIntoExtraHeaders(s.Metadata, extraheaders), []int{http.StatusCreated})
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	s.updateEtagAndLastModified(headers)
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // CreateIfNotExists creates this share under the associated account if
 | |
| // it does not exist. Returns true if the share is newly created or false if
 | |
| // the share already exists.
 | |
| //
 | |
| // See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Create-Share
 | |
| func (s *Share) CreateIfNotExists(options *FileRequestOptions) (bool, error) {
 | |
| 	extraheaders := map[string]string{}
 | |
| 	if s.Properties.Quota > 0 {
 | |
| 		extraheaders["x-ms-share-quota"] = strconv.Itoa(s.Properties.Quota)
 | |
| 	}
 | |
| 
 | |
| 	params := prepareOptions(options)
 | |
| 	resp, err := s.fsc.createResourceNoClose(s.buildPath(), resourceShare, params, extraheaders)
 | |
| 	if resp != nil {
 | |
| 		defer drainRespBody(resp)
 | |
| 		if resp.StatusCode == http.StatusCreated || resp.StatusCode == http.StatusConflict {
 | |
| 			if resp.StatusCode == http.StatusCreated {
 | |
| 				s.updateEtagAndLastModified(resp.Header)
 | |
| 				return true, nil
 | |
| 			}
 | |
| 			return false, s.FetchAttributes(nil)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return false, err
 | |
| }
 | |
| 
 | |
| // Delete marks this share for deletion. The share along with any files
 | |
| // and directories contained within it are later deleted during garbage
 | |
| // collection.  If the share does not exist the operation fails
 | |
| //
 | |
| // See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Delete-Share
 | |
| func (s *Share) Delete(options *FileRequestOptions) error {
 | |
| 	return s.fsc.deleteResource(s.buildPath(), resourceShare, options)
 | |
| }
 | |
| 
 | |
| // DeleteIfExists operation marks this share for deletion if it exists.
 | |
| //
 | |
| // See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Delete-Share
 | |
| func (s *Share) DeleteIfExists(options *FileRequestOptions) (bool, error) {
 | |
| 	resp, err := s.fsc.deleteResourceNoClose(s.buildPath(), resourceShare, options)
 | |
| 	if resp != nil {
 | |
| 		defer drainRespBody(resp)
 | |
| 		if resp.StatusCode == http.StatusAccepted || resp.StatusCode == http.StatusNotFound {
 | |
| 			return resp.StatusCode == http.StatusAccepted, nil
 | |
| 		}
 | |
| 	}
 | |
| 	return false, err
 | |
| }
 | |
| 
 | |
| // Exists returns true if this share already exists
 | |
| // on the storage account, otherwise returns false.
 | |
| func (s *Share) Exists() (bool, error) {
 | |
| 	exists, headers, err := s.fsc.resourceExists(s.buildPath(), resourceShare)
 | |
| 	if exists {
 | |
| 		s.updateEtagAndLastModified(headers)
 | |
| 		s.updateQuota(headers)
 | |
| 	}
 | |
| 	return exists, err
 | |
| }
 | |
| 
 | |
| // FetchAttributes retrieves metadata and properties for this share.
 | |
| // See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-share-properties
 | |
| func (s *Share) FetchAttributes(options *FileRequestOptions) error {
 | |
| 	params := prepareOptions(options)
 | |
| 	headers, err := s.fsc.getResourceHeaders(s.buildPath(), compNone, resourceShare, params, http.MethodHead)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	s.updateEtagAndLastModified(headers)
 | |
| 	s.updateQuota(headers)
 | |
| 	s.Metadata = getMetadataFromHeaders(headers)
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // GetRootDirectoryReference returns a Directory object at the root of this share.
 | |
| func (s *Share) GetRootDirectoryReference() *Directory {
 | |
| 	return &Directory{
 | |
| 		fsc:   s.fsc,
 | |
| 		share: s,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // ServiceClient returns the FileServiceClient associated with this share.
 | |
| func (s *Share) ServiceClient() *FileServiceClient {
 | |
| 	return s.fsc
 | |
| }
 | |
| 
 | |
| // SetMetadata replaces the metadata for this 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://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/set-share-metadata
 | |
| func (s *Share) SetMetadata(options *FileRequestOptions) error {
 | |
| 	headers, err := s.fsc.setResourceHeaders(s.buildPath(), compMetadata, resourceShare, mergeMDIntoExtraHeaders(s.Metadata, nil), options)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	s.updateEtagAndLastModified(headers)
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // SetProperties sets system properties for this share.
 | |
| //
 | |
| // 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://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Set-Share-Properties
 | |
| func (s *Share) SetProperties(options *FileRequestOptions) error {
 | |
| 	extraheaders := map[string]string{}
 | |
| 	if s.Properties.Quota > 0 {
 | |
| 		if s.Properties.Quota > 5120 {
 | |
| 			return fmt.Errorf("invalid value %v for quota, valid values are [1, 5120]", s.Properties.Quota)
 | |
| 		}
 | |
| 		extraheaders["x-ms-share-quota"] = strconv.Itoa(s.Properties.Quota)
 | |
| 	}
 | |
| 
 | |
| 	headers, err := s.fsc.setResourceHeaders(s.buildPath(), compProperties, resourceShare, extraheaders, options)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	s.updateEtagAndLastModified(headers)
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // updates Etag and last modified date
 | |
| func (s *Share) updateEtagAndLastModified(headers http.Header) {
 | |
| 	s.Properties.Etag = headers.Get("Etag")
 | |
| 	s.Properties.LastModified = headers.Get("Last-Modified")
 | |
| }
 | |
| 
 | |
| // updates quota value
 | |
| func (s *Share) updateQuota(headers http.Header) {
 | |
| 	quota, err := strconv.Atoi(headers.Get("x-ms-share-quota"))
 | |
| 	if err == nil {
 | |
| 		s.Properties.Quota = quota
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // URL gets the canonical URL to this share. This method does not create a publicly accessible
 | |
| // URL if the share is private and this method does not check if the share exists.
 | |
| func (s *Share) URL() string {
 | |
| 	return s.fsc.client.getEndpoint(fileServiceName, s.buildPath(), url.Values{})
 | |
| }
 |