aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go')
-rw-r--r--vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go491
1 files changed, 491 insertions, 0 deletions
diff --git a/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go b/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go
new file mode 100644
index 0000000..c52f78c
--- /dev/null
+++ b/vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go
@@ -0,0 +1,491 @@
1/*
2 * MinIO Go Library for Amazon S3 Compatible Cloud Storage
3 * Copyright 2020 MinIO, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18// Package lifecycle contains all the lifecycle related data types and marshallers.
19package lifecycle
20
21import (
22 "encoding/json"
23 "encoding/xml"
24 "errors"
25 "time"
26)
27
28var errMissingStorageClass = errors.New("storage-class cannot be empty")
29
30// AbortIncompleteMultipartUpload structure, not supported yet on MinIO
31type AbortIncompleteMultipartUpload struct {
32 XMLName xml.Name `xml:"AbortIncompleteMultipartUpload,omitempty" json:"-"`
33 DaysAfterInitiation ExpirationDays `xml:"DaysAfterInitiation,omitempty" json:"DaysAfterInitiation,omitempty"`
34}
35
36// IsDaysNull returns true if days field is null
37func (n AbortIncompleteMultipartUpload) IsDaysNull() bool {
38 return n.DaysAfterInitiation == ExpirationDays(0)
39}
40
41// MarshalXML if days after initiation is set to non-zero value
42func (n AbortIncompleteMultipartUpload) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
43 if n.IsDaysNull() {
44 return nil
45 }
46 type abortIncompleteMultipartUploadWrapper AbortIncompleteMultipartUpload
47 return e.EncodeElement(abortIncompleteMultipartUploadWrapper(n), start)
48}
49
50// NoncurrentVersionExpiration - Specifies when noncurrent object versions expire.
51// Upon expiration, server permanently deletes the noncurrent object versions.
52// Set this lifecycle configuration action on a bucket that has versioning enabled
53// (or suspended) to request server delete noncurrent object versions at a
54// specific period in the object's lifetime.
55type NoncurrentVersionExpiration struct {
56 XMLName xml.Name `xml:"NoncurrentVersionExpiration" json:"-"`
57 NoncurrentDays ExpirationDays `xml:"NoncurrentDays,omitempty" json:"NoncurrentDays,omitempty"`
58 NewerNoncurrentVersions int `xml:"NewerNoncurrentVersions,omitempty" json:"NewerNoncurrentVersions,omitempty"`
59}
60
61// MarshalXML if n is non-empty, i.e has a non-zero NoncurrentDays or NewerNoncurrentVersions.
62func (n NoncurrentVersionExpiration) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
63 if n.isNull() {
64 return nil
65 }
66 type noncurrentVersionExpirationWrapper NoncurrentVersionExpiration
67 return e.EncodeElement(noncurrentVersionExpirationWrapper(n), start)
68}
69
70// IsDaysNull returns true if days field is null
71func (n NoncurrentVersionExpiration) IsDaysNull() bool {
72 return n.NoncurrentDays == ExpirationDays(0)
73}
74
75func (n NoncurrentVersionExpiration) isNull() bool {
76 return n.IsDaysNull() && n.NewerNoncurrentVersions == 0
77}
78
79// NoncurrentVersionTransition structure, set this action to request server to
80// transition noncurrent object versions to different set storage classes
81// at a specific period in the object's lifetime.
82type NoncurrentVersionTransition struct {
83 XMLName xml.Name `xml:"NoncurrentVersionTransition,omitempty" json:"-"`
84 StorageClass string `xml:"StorageClass,omitempty" json:"StorageClass,omitempty"`
85 NoncurrentDays ExpirationDays `xml:"NoncurrentDays" json:"NoncurrentDays"`
86 NewerNoncurrentVersions int `xml:"NewerNoncurrentVersions,omitempty" json:"NewerNoncurrentVersions,omitempty"`
87}
88
89// IsDaysNull returns true if days field is null
90func (n NoncurrentVersionTransition) IsDaysNull() bool {
91 return n.NoncurrentDays == ExpirationDays(0)
92}
93
94// IsStorageClassEmpty returns true if storage class field is empty
95func (n NoncurrentVersionTransition) IsStorageClassEmpty() bool {
96 return n.StorageClass == ""
97}
98
99func (n NoncurrentVersionTransition) isNull() bool {
100 return n.StorageClass == ""
101}
102
103// UnmarshalJSON implements NoncurrentVersionTransition JSONify
104func (n *NoncurrentVersionTransition) UnmarshalJSON(b []byte) error {
105 type noncurrentVersionTransition NoncurrentVersionTransition
106 var nt noncurrentVersionTransition
107 err := json.Unmarshal(b, &nt)
108 if err != nil {
109 return err
110 }
111
112 if nt.StorageClass == "" {
113 return errMissingStorageClass
114 }
115 *n = NoncurrentVersionTransition(nt)
116 return nil
117}
118
119// MarshalXML is extended to leave out
120// <NoncurrentVersionTransition></NoncurrentVersionTransition> tags
121func (n NoncurrentVersionTransition) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
122 if n.isNull() {
123 return nil
124 }
125 type noncurrentVersionTransitionWrapper NoncurrentVersionTransition
126 return e.EncodeElement(noncurrentVersionTransitionWrapper(n), start)
127}
128
129// Tag structure key/value pair representing an object tag to apply lifecycle configuration
130type Tag struct {
131 XMLName xml.Name `xml:"Tag,omitempty" json:"-"`
132 Key string `xml:"Key,omitempty" json:"Key,omitempty"`
133 Value string `xml:"Value,omitempty" json:"Value,omitempty"`
134}
135
136// IsEmpty returns whether this tag is empty or not.
137func (tag Tag) IsEmpty() bool {
138 return tag.Key == ""
139}
140
141// Transition structure - transition details of lifecycle configuration
142type Transition struct {
143 XMLName xml.Name `xml:"Transition" json:"-"`
144 Date ExpirationDate `xml:"Date,omitempty" json:"Date,omitempty"`
145 StorageClass string `xml:"StorageClass,omitempty" json:"StorageClass,omitempty"`
146 Days ExpirationDays `xml:"Days" json:"Days"`
147}
148
149// UnmarshalJSON returns an error if storage-class is empty.
150func (t *Transition) UnmarshalJSON(b []byte) error {
151 type transition Transition
152 var tr transition
153 err := json.Unmarshal(b, &tr)
154 if err != nil {
155 return err
156 }
157
158 if tr.StorageClass == "" {
159 return errMissingStorageClass
160 }
161 *t = Transition(tr)
162 return nil
163}
164
165// MarshalJSON customizes json encoding by omitting empty values
166func (t Transition) MarshalJSON() ([]byte, error) {
167 if t.IsNull() {
168 return nil, nil
169 }
170 type transition struct {
171 Date *ExpirationDate `json:"Date,omitempty"`
172 StorageClass string `json:"StorageClass,omitempty"`
173 Days *ExpirationDays `json:"Days"`
174 }
175
176 newt := transition{
177 StorageClass: t.StorageClass,
178 }
179
180 if !t.IsDateNull() {
181 newt.Date = &t.Date
182 } else {
183 newt.Days = &t.Days
184 }
185 return json.Marshal(newt)
186}
187
188// IsDaysNull returns true if days field is null
189func (t Transition) IsDaysNull() bool {
190 return t.Days == ExpirationDays(0)
191}
192
193// IsDateNull returns true if date field is null
194func (t Transition) IsDateNull() bool {
195 return t.Date.Time.IsZero()
196}
197
198// IsNull returns true if no storage-class is set.
199func (t Transition) IsNull() bool {
200 return t.StorageClass == ""
201}
202
203// MarshalXML is transition is non null
204func (t Transition) MarshalXML(en *xml.Encoder, startElement xml.StartElement) error {
205 if t.IsNull() {
206 return nil
207 }
208 type transitionWrapper Transition
209 return en.EncodeElement(transitionWrapper(t), startElement)
210}
211
212// And And Rule for LifecycleTag, to be used in LifecycleRuleFilter
213type And struct {
214 XMLName xml.Name `xml:"And" json:"-"`
215 Prefix string `xml:"Prefix" json:"Prefix,omitempty"`
216 Tags []Tag `xml:"Tag" json:"Tags,omitempty"`
217 ObjectSizeLessThan int64 `xml:"ObjectSizeLessThan,omitempty" json:"ObjectSizeLessThan,omitempty"`
218 ObjectSizeGreaterThan int64 `xml:"ObjectSizeGreaterThan,omitempty" json:"ObjectSizeGreaterThan,omitempty"`
219}
220
221// IsEmpty returns true if Tags field is null
222func (a And) IsEmpty() bool {
223 return len(a.Tags) == 0 && a.Prefix == "" &&
224 a.ObjectSizeLessThan == 0 && a.ObjectSizeGreaterThan == 0
225}
226
227// Filter will be used in selecting rule(s) for lifecycle configuration
228type Filter struct {
229 XMLName xml.Name `xml:"Filter" json:"-"`
230 And And `xml:"And,omitempty" json:"And,omitempty"`
231 Prefix string `xml:"Prefix,omitempty" json:"Prefix,omitempty"`
232 Tag Tag `xml:"Tag,omitempty" json:"Tag,omitempty"`
233 ObjectSizeLessThan int64 `xml:"ObjectSizeLessThan,omitempty" json:"ObjectSizeLessThan,omitempty"`
234 ObjectSizeGreaterThan int64 `xml:"ObjectSizeGreaterThan,omitempty" json:"ObjectSizeGreaterThan,omitempty"`
235}
236
237// IsNull returns true if all Filter fields are empty.
238func (f Filter) IsNull() bool {
239 return f.Tag.IsEmpty() && f.And.IsEmpty() && f.Prefix == "" &&
240 f.ObjectSizeLessThan == 0 && f.ObjectSizeGreaterThan == 0
241}
242
243// MarshalJSON customizes json encoding by removing empty values.
244func (f Filter) MarshalJSON() ([]byte, error) {
245 type filter struct {
246 And *And `json:"And,omitempty"`
247 Prefix string `json:"Prefix,omitempty"`
248 Tag *Tag `json:"Tag,omitempty"`
249 ObjectSizeLessThan int64 `json:"ObjectSizeLessThan,omitempty"`
250 ObjectSizeGreaterThan int64 `json:"ObjectSizeGreaterThan,omitempty"`
251 }
252
253 newf := filter{
254 Prefix: f.Prefix,
255 }
256 if !f.Tag.IsEmpty() {
257 newf.Tag = &f.Tag
258 }
259 if !f.And.IsEmpty() {
260 newf.And = &f.And
261 }
262 newf.ObjectSizeLessThan = f.ObjectSizeLessThan
263 newf.ObjectSizeGreaterThan = f.ObjectSizeGreaterThan
264 return json.Marshal(newf)
265}
266
267// MarshalXML - produces the xml representation of the Filter struct
268// only one of Prefix, And and Tag should be present in the output.
269func (f Filter) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
270 if err := e.EncodeToken(start); err != nil {
271 return err
272 }
273
274 switch {
275 case !f.And.IsEmpty():
276 if err := e.EncodeElement(f.And, xml.StartElement{Name: xml.Name{Local: "And"}}); err != nil {
277 return err
278 }
279 case !f.Tag.IsEmpty():
280 if err := e.EncodeElement(f.Tag, xml.StartElement{Name: xml.Name{Local: "Tag"}}); err != nil {
281 return err
282 }
283 default:
284 if f.ObjectSizeLessThan > 0 {
285 if err := e.EncodeElement(f.ObjectSizeLessThan, xml.StartElement{Name: xml.Name{Local: "ObjectSizeLessThan"}}); err != nil {
286 return err
287 }
288 break
289 }
290 if f.ObjectSizeGreaterThan > 0 {
291 if err := e.EncodeElement(f.ObjectSizeGreaterThan, xml.StartElement{Name: xml.Name{Local: "ObjectSizeGreaterThan"}}); err != nil {
292 return err
293 }
294 break
295 }
296 // Print empty Prefix field only when everything else is empty
297 if err := e.EncodeElement(f.Prefix, xml.StartElement{Name: xml.Name{Local: "Prefix"}}); err != nil {
298 return err
299 }
300 }
301
302 return e.EncodeToken(xml.EndElement{Name: start.Name})
303}
304
305// ExpirationDays is a type alias to unmarshal Days in Expiration
306type ExpirationDays int
307
308// MarshalXML encodes number of days to expire if it is non-zero and
309// encodes empty string otherwise
310func (eDays ExpirationDays) MarshalXML(e *xml.Encoder, startElement xml.StartElement) error {
311 if eDays == 0 {
312 return nil
313 }
314 return e.EncodeElement(int(eDays), startElement)
315}
316
317// ExpirationDate is a embedded type containing time.Time to unmarshal
318// Date in Expiration
319type ExpirationDate struct {
320 time.Time
321}
322
323// MarshalXML encodes expiration date if it is non-zero and encodes
324// empty string otherwise
325func (eDate ExpirationDate) MarshalXML(e *xml.Encoder, startElement xml.StartElement) error {
326 if eDate.Time.IsZero() {
327 return nil
328 }
329 return e.EncodeElement(eDate.Format(time.RFC3339), startElement)
330}
331
332// ExpireDeleteMarker represents value of ExpiredObjectDeleteMarker field in Expiration XML element.
333type ExpireDeleteMarker ExpirationBoolean
334
335// IsEnabled returns true if the auto delete-marker expiration is enabled
336func (e ExpireDeleteMarker) IsEnabled() bool {
337 return bool(e)
338}
339
340// ExpirationBoolean represents an XML version of 'bool' type
341type ExpirationBoolean bool
342
343// MarshalXML encodes delete marker boolean into an XML form.
344func (b ExpirationBoolean) MarshalXML(e *xml.Encoder, startElement xml.StartElement) error {
345 if !b {
346 return nil
347 }
348 type booleanWrapper ExpirationBoolean
349 return e.EncodeElement(booleanWrapper(b), startElement)
350}
351
352// IsEnabled returns true if the expiration boolean is enabled
353func (b ExpirationBoolean) IsEnabled() bool {
354 return bool(b)
355}
356
357// Expiration structure - expiration details of lifecycle configuration
358type Expiration struct {
359 XMLName xml.Name `xml:"Expiration,omitempty" json:"-"`
360 Date ExpirationDate `xml:"Date,omitempty" json:"Date,omitempty"`
361 Days ExpirationDays `xml:"Days,omitempty" json:"Days,omitempty"`
362 DeleteMarker ExpireDeleteMarker `xml:"ExpiredObjectDeleteMarker,omitempty" json:"ExpiredObjectDeleteMarker,omitempty"`
363 DeleteAll ExpirationBoolean `xml:"ExpiredObjectAllVersions,omitempty" json:"ExpiredObjectAllVersions,omitempty"`
364}
365
366// MarshalJSON customizes json encoding by removing empty day/date specification.
367func (e Expiration) MarshalJSON() ([]byte, error) {
368 type expiration struct {
369 Date *ExpirationDate `json:"Date,omitempty"`
370 Days *ExpirationDays `json:"Days,omitempty"`
371 DeleteMarker ExpireDeleteMarker `json:"ExpiredObjectDeleteMarker,omitempty"`
372 DeleteAll ExpirationBoolean `json:"ExpiredObjectAllVersions,omitempty"`
373 }
374
375 newexp := expiration{
376 DeleteMarker: e.DeleteMarker,
377 DeleteAll: e.DeleteAll,
378 }
379 if !e.IsDaysNull() {
380 newexp.Days = &e.Days
381 }
382 if !e.IsDateNull() {
383 newexp.Date = &e.Date
384 }
385 return json.Marshal(newexp)
386}
387
388// IsDaysNull returns true if days field is null
389func (e Expiration) IsDaysNull() bool {
390 return e.Days == ExpirationDays(0)
391}
392
393// IsDateNull returns true if date field is null
394func (e Expiration) IsDateNull() bool {
395 return e.Date.Time.IsZero()
396}
397
398// IsDeleteMarkerExpirationEnabled returns true if the auto-expiration of delete marker is enabled
399func (e Expiration) IsDeleteMarkerExpirationEnabled() bool {
400 return e.DeleteMarker.IsEnabled()
401}
402
403// IsNull returns true if both date and days fields are null
404func (e Expiration) IsNull() bool {
405 return e.IsDaysNull() && e.IsDateNull() && !e.IsDeleteMarkerExpirationEnabled()
406}
407
408// MarshalXML is expiration is non null
409func (e Expiration) MarshalXML(en *xml.Encoder, startElement xml.StartElement) error {
410 if e.IsNull() {
411 return nil
412 }
413 type expirationWrapper Expiration
414 return en.EncodeElement(expirationWrapper(e), startElement)
415}
416
417// MarshalJSON customizes json encoding by omitting empty values
418func (r Rule) MarshalJSON() ([]byte, error) {
419 type rule struct {
420 AbortIncompleteMultipartUpload *AbortIncompleteMultipartUpload `json:"AbortIncompleteMultipartUpload,omitempty"`
421 Expiration *Expiration `json:"Expiration,omitempty"`
422 ID string `json:"ID"`
423 RuleFilter *Filter `json:"Filter,omitempty"`
424 NoncurrentVersionExpiration *NoncurrentVersionExpiration `json:"NoncurrentVersionExpiration,omitempty"`
425 NoncurrentVersionTransition *NoncurrentVersionTransition `json:"NoncurrentVersionTransition,omitempty"`
426 Prefix string `json:"Prefix,omitempty"`
427 Status string `json:"Status"`
428 Transition *Transition `json:"Transition,omitempty"`
429 }
430 newr := rule{
431 Prefix: r.Prefix,
432 Status: r.Status,
433 ID: r.ID,
434 }
435
436 if !r.RuleFilter.IsNull() {
437 newr.RuleFilter = &r.RuleFilter
438 }
439 if !r.AbortIncompleteMultipartUpload.IsDaysNull() {
440 newr.AbortIncompleteMultipartUpload = &r.AbortIncompleteMultipartUpload
441 }
442 if !r.Expiration.IsNull() {
443 newr.Expiration = &r.Expiration
444 }
445 if !r.Transition.IsNull() {
446 newr.Transition = &r.Transition
447 }
448 if !r.NoncurrentVersionExpiration.isNull() {
449 newr.NoncurrentVersionExpiration = &r.NoncurrentVersionExpiration
450 }
451 if !r.NoncurrentVersionTransition.isNull() {
452 newr.NoncurrentVersionTransition = &r.NoncurrentVersionTransition
453 }
454
455 return json.Marshal(newr)
456}
457
458// Rule represents a single rule in lifecycle configuration
459type Rule struct {
460 XMLName xml.Name `xml:"Rule,omitempty" json:"-"`
461 AbortIncompleteMultipartUpload AbortIncompleteMultipartUpload `xml:"AbortIncompleteMultipartUpload,omitempty" json:"AbortIncompleteMultipartUpload,omitempty"`
462 Expiration Expiration `xml:"Expiration,omitempty" json:"Expiration,omitempty"`
463 ID string `xml:"ID" json:"ID"`
464 RuleFilter Filter `xml:"Filter,omitempty" json:"Filter,omitempty"`
465 NoncurrentVersionExpiration NoncurrentVersionExpiration `xml:"NoncurrentVersionExpiration,omitempty" json:"NoncurrentVersionExpiration,omitempty"`
466 NoncurrentVersionTransition NoncurrentVersionTransition `xml:"NoncurrentVersionTransition,omitempty" json:"NoncurrentVersionTransition,omitempty"`
467 Prefix string `xml:"Prefix,omitempty" json:"Prefix,omitempty"`
468 Status string `xml:"Status" json:"Status"`
469 Transition Transition `xml:"Transition,omitempty" json:"Transition,omitempty"`
470}
471
472// Configuration is a collection of Rule objects.
473type Configuration struct {
474 XMLName xml.Name `xml:"LifecycleConfiguration,omitempty" json:"-"`
475 Rules []Rule `xml:"Rule"`
476}
477
478// Empty check if lifecycle configuration is empty
479func (c *Configuration) Empty() bool {
480 if c == nil {
481 return true
482 }
483 return len(c.Rules) == 0
484}
485
486// NewConfiguration initializes a fresh lifecycle configuration
487// for manipulation, such as setting and removing lifecycle rules
488// and filters.
489func NewConfiguration() *Configuration {
490 return &Configuration{}
491}