github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/ilm-rule-add.go (about) 1 // Copyright (c) 2015-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 cmd 19 20 import ( 21 "context" 22 23 "github.com/minio/cli" 24 json "github.com/minio/colorjson" 25 "github.com/minio/mc/cmd/ilm" 26 "github.com/minio/mc/pkg/probe" 27 "github.com/minio/minio-go/v7" 28 "github.com/minio/minio-go/v7/pkg/lifecycle" 29 "github.com/minio/pkg/v2/console" 30 ) 31 32 var ilmAddCmd = cli.Command{ 33 Name: "add", 34 Usage: "add a lifecycle configuration rule for a bucket", 35 Action: mainILMAdd, 36 OnUsageError: onUsageError, 37 Before: setGlobalsFromContext, 38 Flags: append(ilmAddFlags, globalFlags...), 39 CustomHelpTemplate: `NAME: 40 {{.HelpName}} - {{.Usage}} 41 42 USAGE: 43 {{.HelpName}} [COMMAND FLAGS] TARGET 44 45 FLAGS: 46 {{range .VisibleFlags}}{{.}} 47 {{end}} 48 DESCRIPTION: 49 Add a lifecycle configuration rule. 50 51 EXAMPLES: 52 1. Add a lifecycle rule with a transition and a noncurrent version transition action for objects with prefix doc/ whose size is greater than 1MiB in mybucket. 53 Tiers must exist in MinIO. Use existing tiers or add new tiers. 54 55 {{.Prompt}} mc ilm tier add minio myminio MINIOTIER-1 --endpoint https://warm-minio-1.com \ 56 --access-key ACCESSKEY --secret-key SECRETKEY --bucket bucket1 --prefix prefix1 57 58 {{.Prompt}} {{.HelpName}} --prefix "doc/" --size-gt 1MiB --transition-days "90" --transition-tier "MINIOTIER-1" \ 59 --noncurrent-transition-days "45" --noncurrent-transition-tier "MINIOTIER-1" \ 60 myminio/mybucket/ 61 62 2. Add a lifecycle rule with an expiration action for all objects in mybucket. 63 {{.Prompt}} {{.HelpName}} --expire-days "200" myminio/mybucket 64 65 3. Add a lifecycle rule with an expiration and a noncurrent version expiration action for all objects with prefix doc/ in mybucket. 66 {{.Prompt}} {{.HelpName}} --prefix "doc/" --expire-days "300" --noncurrent-expire-days "100" \ 67 myminio/mybucket/ 68 `, 69 } 70 71 var ilmAddFlags = []cli.Flag{ 72 cli.StringFlag{ 73 Name: "prefix", 74 Usage: "object prefix", 75 }, 76 cli.StringFlag{ 77 Name: "tags", 78 Usage: "key value pairs of the form '<key1>=<value1>&<key2>=<value2>&<key3>=<value3>'", 79 }, 80 cli.StringFlag{ 81 Name: "size-lt", 82 Usage: "objects with size less than this value will be selected for the lifecycle action", 83 }, 84 cli.StringFlag{ 85 Name: "size-gt", 86 Usage: "objects with size greater than this value will be selected for the lifecycle action", 87 }, 88 cli.StringFlag{ 89 Name: "expiry-date", 90 Usage: "format 'YYYY-MM-DD' the date of expiration", 91 Hidden: true, 92 }, 93 cli.StringFlag{ 94 Name: "expiry-days", 95 Usage: "the number of days to expiration", 96 Hidden: true, 97 }, 98 cli.StringFlag{ 99 Name: "expire-days", 100 Usage: "number of days to expire", 101 }, 102 cli.BoolFlag{ 103 Name: "expired-object-delete-marker", 104 Usage: "remove delete markers with no parallel versions", 105 Hidden: true, 106 }, 107 cli.BoolFlag{ 108 Name: "expire-delete-marker", 109 Usage: "expire zombie delete markers", 110 }, 111 cli.StringFlag{ 112 Name: "transition-date", 113 Usage: "format 'YYYY-MM-DD' for the date to transition", 114 Hidden: true, 115 }, 116 cli.StringFlag{ 117 Name: "transition-days", 118 Usage: "number of days to transition", 119 }, 120 cli.StringFlag{ 121 Name: "storage-class", 122 Usage: "storage class for current version to transition into. MinIO supports tiers configured via `mc-admin-tier-add`.", 123 Hidden: true, 124 }, 125 cli.StringFlag{ 126 Name: "tier", 127 Usage: "remote tier where current versions transition to", 128 Hidden: true, 129 }, 130 cli.StringFlag{ 131 Name: "transition-tier", 132 Usage: "remote tier name to transition", 133 }, 134 cli.IntFlag{ 135 Name: "noncurrentversion-expiration-days", 136 Usage: "the number of days to remove noncurrent versions", 137 Hidden: true, 138 }, 139 cli.StringFlag{ 140 Name: "noncurrent-expire-days", 141 Usage: "number of days to expire noncurrent versions", 142 }, 143 cli.IntFlag{ 144 Name: "newer-noncurrentversions-expiration", 145 Usage: "the number of noncurrent versions to retain", 146 Hidden: true, 147 }, 148 cli.IntFlag{ 149 Name: "noncurrent-expire-newer", 150 Usage: "number of newer noncurrent versions to retain", 151 }, 152 cli.IntFlag{ 153 Name: "noncurrentversion-transition-days", 154 Usage: "the number of days to transition noncurrent versions", 155 Hidden: true, 156 }, 157 cli.IntFlag{ 158 Name: "noncurrent-transition-days", 159 Usage: "number of days to transition noncurrent versions", 160 }, 161 cli.IntFlag{ 162 Name: "newer-noncurrentversions-transition", 163 Usage: "the number of noncurrent versions to retain. If there are this many more recent noncurrent versions they will be transitioned", 164 Hidden: true, 165 }, 166 cli.IntFlag{ 167 Name: "noncurrent-transition-newer", 168 Usage: "number of noncurrent versions to retain in hot tier", 169 Hidden: true, 170 }, 171 cli.StringFlag{ 172 Name: "noncurrentversion-transition-storage-class", 173 Usage: "storage class for noncurrent versions to transition into", 174 Hidden: true, 175 }, 176 cli.StringFlag{ 177 Name: "noncurrentversion-tier", 178 Usage: "remote tier where noncurrent versions transition to", 179 Hidden: true, 180 }, 181 cli.StringFlag{ 182 Name: "noncurrent-transition-tier", 183 Usage: "remote tier name to transition", 184 }, 185 cli.BoolFlag{ 186 Name: "expire-all-object-versions", 187 Usage: "expire all object versions", 188 }, 189 } 190 191 type ilmAddMessage struct { 192 Status string `json:"status"` 193 Target string `json:"target"` 194 ID string `json:"id"` 195 } 196 197 func (i ilmAddMessage) String() string { 198 return console.Colorize(ilmThemeResultSuccess, "Lifecycle configuration rule added with ID `"+i.ID+"` to "+i.Target+".") 199 } 200 201 func (i ilmAddMessage) JSON() string { 202 msgBytes, e := json.MarshalIndent(i, "", " ") 203 fatalIf(probe.NewError(e), "Unable to encode as JSON.") 204 return string(msgBytes) 205 } 206 207 // Validate user given arguments 208 func checkILMAddSyntax(ctx *cli.Context) { 209 if len(ctx.Args()) != 1 { 210 showCommandHelpAndExit(ctx, globalErrorExitStatus) 211 } 212 } 213 214 // Calls SetBucketLifecycle with the XML representation of lifecycleConfiguration type. 215 func mainILMAdd(cliCtx *cli.Context) error { 216 ctx, cancelILMAdd := context.WithCancel(globalContext) 217 defer cancelILMAdd() 218 219 checkILMAddSyntax(cliCtx) 220 setILMDisplayColorScheme() 221 args := cliCtx.Args() 222 urlStr := args.Get(0) 223 224 client, err := newClient(urlStr) 225 fatalIf(err.Trace(urlStr), "Unable to initialize client for "+urlStr) 226 227 // Configuration that is already set. 228 lfcCfg, _, err := client.GetLifecycle(ctx) 229 if err != nil { 230 if e := err.ToGoError(); minio.ToErrorResponse(e).Code == "NoSuchLifecycleConfiguration" { 231 lfcCfg = lifecycle.NewConfiguration() 232 } else { 233 fatalIf(err.Trace(args...), "Unable to fetch lifecycle rules for "+urlStr) 234 } 235 } 236 237 opts, err := ilm.GetLifecycleOptions(cliCtx) 238 fatalIf(err.Trace(args...), "Unable to generate new lifecycle rules for the input") 239 240 newRule, err := opts.ToILMRule() 241 fatalIf(err.Trace(args...), "Unable to generate new lifecycle rules for the input") 242 243 lfcCfg.Rules = append(lfcCfg.Rules, newRule) 244 245 fatalIf(client.SetLifecycle(ctx, lfcCfg).Trace(urlStr), "Unable to add this lifecycle rule") 246 247 printMsg(ilmAddMessage{ 248 Status: "success", 249 Target: urlStr, 250 ID: opts.ID, 251 }) 252 253 return nil 254 }