aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/Azure/azure-storage-go/share.go
blob: e190097ea5cd5c45a51ce25e892e72e2a62bc871 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
package storage

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://msdn.microsoft.com/en-us/library/azure/dn167008.aspx
func (s *Share) Create() error {
    headers, err := s.fsc.createResource(s.buildPath(), resourceShare, nil, mergeMDIntoExtraHeaders(s.Metadata, nil), []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://msdn.microsoft.com/en-us/library/azure/dn167008.aspx
func (s *Share) CreateIfNotExists() (bool, error) {
    resp, err := s.fsc.createResourceNoClose(s.buildPath(), resourceShare, nil, nil)
    if resp != nil {
        defer readAndCloseBody(resp.body)
        if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict {
            if resp.statusCode == http.StatusCreated {
                s.updateEtagAndLastModified(resp.headers)
                return true, nil
            }
            return false, s.FetchAttributes()
        }
    }

    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://msdn.microsoft.com/en-us/library/azure/dn689090.aspx
func (s *Share) Delete() error {
    return s.fsc.deleteResource(s.buildPath(), resourceShare)
}

// DeleteIfExists operation marks this share for deletion if it exists.
//
// See https://msdn.microsoft.com/en-us/library/azure/dn689090.aspx
func (s *Share) DeleteIfExists() (bool, error) {
    resp, err := s.fsc.deleteResourceNoClose(s.buildPath(), resourceShare)
    if resp != nil {
        defer readAndCloseBody(resp.body)
        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.
func (s *Share) FetchAttributes() error {
    headers, err := s.fsc.getResourceHeaders(s.buildPath(), compNone, resourceShare, 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://msdn.microsoft.com/en-us/library/azure/dd179414.aspx
func (s *Share) SetMetadata() error {
    headers, err := s.fsc.setResourceHeaders(s.buildPath(), compMetadata, resourceShare, mergeMDIntoExtraHeaders(s.Metadata, nil))
    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://msdn.microsoft.com/en-us/library/azure/mt427368.aspx
func (s *Share) SetProperties() error {
    if s.Properties.Quota < 1 || s.Properties.Quota > 5120 {
        return fmt.Errorf("invalid value %v for quota, valid values are [1, 5120]", s.Properties.Quota)
    }

    headers, err := s.fsc.setResourceHeaders(s.buildPath(), compProperties, resourceShare, map[string]string{
        "x-ms-share-quota": strconv.Itoa(s.Properties.Quota),
    })
    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{})
}