diff options
Diffstat (limited to 'vendor/github.com/minio/minio-go/v7/pkg/lifecycle')
-rw-r--r-- | vendor/github.com/minio/minio-go/v7/pkg/lifecycle/lifecycle.go | 491 |
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. | ||
19 | package lifecycle | ||
20 | |||
21 | import ( | ||
22 | "encoding/json" | ||
23 | "encoding/xml" | ||
24 | "errors" | ||
25 | "time" | ||
26 | ) | ||
27 | |||
28 | var errMissingStorageClass = errors.New("storage-class cannot be empty") | ||
29 | |||
30 | // AbortIncompleteMultipartUpload structure, not supported yet on MinIO | ||
31 | type 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 | ||
37 | func (n AbortIncompleteMultipartUpload) IsDaysNull() bool { | ||
38 | return n.DaysAfterInitiation == ExpirationDays(0) | ||
39 | } | ||
40 | |||
41 | // MarshalXML if days after initiation is set to non-zero value | ||
42 | func (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. | ||
55 | type 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. | ||
62 | func (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 | ||
71 | func (n NoncurrentVersionExpiration) IsDaysNull() bool { | ||
72 | return n.NoncurrentDays == ExpirationDays(0) | ||
73 | } | ||
74 | |||
75 | func (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. | ||
82 | type 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 | ||
90 | func (n NoncurrentVersionTransition) IsDaysNull() bool { | ||
91 | return n.NoncurrentDays == ExpirationDays(0) | ||
92 | } | ||
93 | |||
94 | // IsStorageClassEmpty returns true if storage class field is empty | ||
95 | func (n NoncurrentVersionTransition) IsStorageClassEmpty() bool { | ||
96 | return n.StorageClass == "" | ||
97 | } | ||
98 | |||
99 | func (n NoncurrentVersionTransition) isNull() bool { | ||
100 | return n.StorageClass == "" | ||
101 | } | ||
102 | |||
103 | // UnmarshalJSON implements NoncurrentVersionTransition JSONify | ||
104 | func (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 | ||
121 | func (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 | ||
130 | type 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. | ||
137 | func (tag Tag) IsEmpty() bool { | ||
138 | return tag.Key == "" | ||
139 | } | ||
140 | |||
141 | // Transition structure - transition details of lifecycle configuration | ||
142 | type 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. | ||
150 | func (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 | ||
166 | func (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 | ||
189 | func (t Transition) IsDaysNull() bool { | ||
190 | return t.Days == ExpirationDays(0) | ||
191 | } | ||
192 | |||
193 | // IsDateNull returns true if date field is null | ||
194 | func (t Transition) IsDateNull() bool { | ||
195 | return t.Date.Time.IsZero() | ||
196 | } | ||
197 | |||
198 | // IsNull returns true if no storage-class is set. | ||
199 | func (t Transition) IsNull() bool { | ||
200 | return t.StorageClass == "" | ||
201 | } | ||
202 | |||
203 | // MarshalXML is transition is non null | ||
204 | func (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 | ||
213 | type 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 | ||
222 | func (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 | ||
228 | type 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. | ||
238 | func (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. | ||
244 | func (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. | ||
269 | func (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 | ||
306 | type ExpirationDays int | ||
307 | |||
308 | // MarshalXML encodes number of days to expire if it is non-zero and | ||
309 | // encodes empty string otherwise | ||
310 | func (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 | ||
319 | type ExpirationDate struct { | ||
320 | time.Time | ||
321 | } | ||
322 | |||
323 | // MarshalXML encodes expiration date if it is non-zero and encodes | ||
324 | // empty string otherwise | ||
325 | func (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. | ||
333 | type ExpireDeleteMarker ExpirationBoolean | ||
334 | |||
335 | // IsEnabled returns true if the auto delete-marker expiration is enabled | ||
336 | func (e ExpireDeleteMarker) IsEnabled() bool { | ||
337 | return bool(e) | ||
338 | } | ||
339 | |||
340 | // ExpirationBoolean represents an XML version of 'bool' type | ||
341 | type ExpirationBoolean bool | ||
342 | |||
343 | // MarshalXML encodes delete marker boolean into an XML form. | ||
344 | func (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 | ||
353 | func (b ExpirationBoolean) IsEnabled() bool { | ||
354 | return bool(b) | ||
355 | } | ||
356 | |||
357 | // Expiration structure - expiration details of lifecycle configuration | ||
358 | type 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. | ||
367 | func (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 | ||
389 | func (e Expiration) IsDaysNull() bool { | ||
390 | return e.Days == ExpirationDays(0) | ||
391 | } | ||
392 | |||
393 | // IsDateNull returns true if date field is null | ||
394 | func (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 | ||
399 | func (e Expiration) IsDeleteMarkerExpirationEnabled() bool { | ||
400 | return e.DeleteMarker.IsEnabled() | ||
401 | } | ||
402 | |||
403 | // IsNull returns true if both date and days fields are null | ||
404 | func (e Expiration) IsNull() bool { | ||
405 | return e.IsDaysNull() && e.IsDateNull() && !e.IsDeleteMarkerExpirationEnabled() | ||
406 | } | ||
407 | |||
408 | // MarshalXML is expiration is non null | ||
409 | func (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 | ||
418 | func (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 | ||
459 | type 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. | ||
473 | type 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 | ||
479 | func (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. | ||
489 | func NewConfiguration() *Configuration { | ||
490 | return &Configuration{} | ||
491 | } | ||