github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/ilm/utils.go (about) 1 // Copyright (c) 2022 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package ilm 19 20 import ( 21 "fmt" 22 "strings" 23 "time" 24 25 "github.com/minio/minio-go/v7/pkg/lifecycle" 26 ) 27 28 // getPrefix returns the prefix configured 29 func getPrefix(rule lifecycle.Rule) string { 30 // deprecated, but older ILM policies may have them 31 if rule.Prefix != "" { 32 return rule.Prefix 33 } 34 if rule.RuleFilter.Prefix != "" { 35 return rule.RuleFilter.Prefix 36 } 37 if rule.RuleFilter.And.Prefix != "" { 38 return rule.RuleFilter.And.Prefix 39 } 40 return "" 41 } 42 43 // getTags returns the tags configured as "k1=v1&k2=v2" 44 func getTags(rule lifecycle.Rule) string { 45 if !rule.RuleFilter.Tag.IsEmpty() { 46 return fmt.Sprintf("%s=%s", rule.RuleFilter.Tag.Key, rule.RuleFilter.Tag.Value) 47 } 48 if len(rule.RuleFilter.And.Tags) > 0 { 49 var tags strings.Builder 50 for i, tag := range rule.RuleFilter.And.Tags { 51 fmt.Fprintf(&tags, "%s=%s", tag.Key, tag.Value) 52 if i < len(rule.RuleFilter.And.Tags)-1 { 53 fmt.Fprintf(&tags, "&") 54 } 55 } 56 return tags.String() 57 } 58 return "" 59 } 60 61 // getExpirationDays returns the number of days to expire relative to 62 // time.Now().UTC() for the given rule. 63 func getExpirationDays(rule lifecycle.Rule) int { 64 if rule.Expiration.Days > 0 { 65 return int(rule.Expiration.Days) 66 } 67 if !rule.Expiration.Date.Time.IsZero() { 68 return int(time.Until(rule.Expiration.Date.Time).Hours() / 24) 69 } 70 71 return 0 72 } 73 74 // getTransitionDays returns the number of days to transition/tier relative to 75 // time.Now().UTC() for the given rule. 76 func getTransitionDays(rule lifecycle.Rule) int { 77 if !rule.Transition.Date.IsZero() { 78 return int(time.Now().UTC().Sub(rule.Transition.Date.Time).Hours() / 24) 79 } 80 81 return int(rule.Transition.Days) 82 } 83 84 // ToTables converts a lifecycle.Configuration into its tabular representation. 85 func ToTables(cfg *lifecycle.Configuration) []Table { 86 var tierCur tierCurrentTable 87 var tierNoncur tierNoncurrentTable 88 var expCur expirationCurrentTable 89 var expNoncur expirationNoncurrentTable 90 for _, rule := range cfg.Rules { 91 if !rule.Expiration.IsNull() { 92 expCur = append(expCur, expirationCurrentRow{ 93 ID: rule.ID, 94 Status: rule.Status, 95 Prefix: getPrefix(rule), 96 Tags: getTags(rule), 97 Days: getExpirationDays(rule), 98 ExpireDelMarker: bool(rule.Expiration.DeleteMarker), 99 }) 100 } 101 if !rule.NoncurrentVersionExpiration.IsDaysNull() || rule.NoncurrentVersionExpiration.NewerNoncurrentVersions > 0 { 102 expNoncur = append(expNoncur, expirationNoncurrentRow{ 103 ID: rule.ID, 104 Status: rule.Status, 105 Prefix: getPrefix(rule), 106 Tags: getTags(rule), 107 Days: int(rule.NoncurrentVersionExpiration.NoncurrentDays), 108 KeepVersions: rule.NoncurrentVersionExpiration.NewerNoncurrentVersions, 109 }) 110 } 111 if !rule.Transition.IsNull() { 112 tierCur = append(tierCur, tierCurrentRow{ 113 ID: rule.ID, 114 Status: rule.Status, 115 Prefix: getPrefix(rule), 116 Tags: getTags(rule), 117 Days: getTransitionDays(rule), 118 Tier: rule.Transition.StorageClass, 119 }) 120 } 121 if !rule.NoncurrentVersionTransition.IsStorageClassEmpty() { 122 tierNoncur = append(tierNoncur, tierNoncurrentRow{ 123 ID: rule.ID, 124 Status: rule.Status, 125 Prefix: getPrefix(rule), 126 Tags: getTags(rule), 127 Days: int(rule.NoncurrentVersionTransition.NoncurrentDays), 128 Tier: rule.NoncurrentVersionTransition.StorageClass, 129 }) 130 } 131 } 132 133 var table []Table 134 inclTbl := func(tbl Table) { 135 if len(tbl.Rows()) > 0 { 136 table = append(table, tbl) 137 } 138 } 139 inclTbl(expCur) 140 inclTbl(expNoncur) 141 inclTbl(tierCur) 142 inclTbl(tierNoncur) 143 return table 144 }