github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/retention-clear.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 "time" 23 24 "github.com/fatih/color" 25 "github.com/minio/cli" 26 "github.com/minio/minio-go/v7" 27 "github.com/minio/pkg/v2/console" 28 ) 29 30 var retentionClearFlags = []cli.Flag{ 31 cli.BoolFlag{ 32 Name: "recursive, r", 33 Usage: "clear retention recursively", 34 }, 35 cli.StringFlag{ 36 Name: "version-id, vid", 37 Usage: "clear retention of a specific object version", 38 }, 39 cli.StringFlag{ 40 Name: "rewind", 41 Usage: "roll back object(s) to current version at specified time", 42 }, 43 cli.BoolFlag{ 44 Name: "versions", 45 Usage: "clear retention of object(s) and all its versions", 46 }, 47 cli.BoolFlag{ 48 Name: "default", 49 Usage: "set default bucket locking", 50 }, 51 } 52 53 var retentionClearCmd = cli.Command{ 54 Name: "clear", 55 Usage: "clear all retention settings on object(s)", 56 Action: mainRetentionClear, 57 OnUsageError: onUsageError, 58 Before: setGlobalsFromContext, 59 Flags: append(retentionClearFlags, globalFlags...), 60 CustomHelpTemplate: `NAME: 61 {{.HelpName}} - {{.Usage}} 62 63 USAGE: 64 {{.HelpName}} [FLAGS] TARGET 65 66 FLAGS: 67 {{range .VisibleFlags}}{{.}} 68 {{end}} 69 70 EXAMPLES: 71 1. Clear object retention for a specific object 72 $ {{.HelpName}} myminio/mybucket/prefix/obj.csv 73 74 2. Clear object retention for recursively for all objects at a given prefix 75 $ {{.HelpName}} myminio/mybucket/prefix --recursive 76 77 3. Clear object retention for a specific version of a specific object 78 $ {{.HelpName}} myminio/mybucket/prefix/obj.csv --version-id "3Jr2x6fqlBUsVzbvPihBO3HgNpgZgAnp" 79 80 4. Clear object retention for recursively for all versions of all objects 81 $ {{.HelpName}} myminio/mybucket/prefix --recursive --versions 82 83 5. Clear object retention for recursively for all versions created one year ago 84 $ {{.HelpName}} myminio/mybucket/prefix --recursive --versions --rewind 365d 85 86 6. Clear a bucket retention configuration 87 $ {{.HelpName}} --default myminio/mybucket/ 88 `, 89 } 90 91 func parseClearRetentionArgs(cliCtx *cli.Context) (target, versionID string, timeRef time.Time, withVersions, recursive, bucketMode bool) { 92 args := cliCtx.Args() 93 94 if len(args) != 1 { 95 showCommandHelpAndExit(cliCtx, 1) 96 } 97 98 target = args[0] 99 if target == "" { 100 fatalIf(errInvalidArgument().Trace(), "invalid target url '%v'", target) 101 } 102 103 versionID = cliCtx.String("version-id") 104 timeRef = parseRewindFlag(cliCtx.String("rewind")) 105 withVersions = cliCtx.Bool("versions") 106 recursive = cliCtx.Bool("recursive") 107 bucketMode = cliCtx.Bool("default") 108 109 if bucketMode && (versionID != "" || !timeRef.IsZero() || withVersions || recursive) { 110 fatalIf(errDummy(), "--default cannot be specified with any of --version-id, --rewind, --versions or --recursive.") 111 } 112 113 return 114 } 115 116 // Clear Retention for one object/version or many objects within a given prefix, bypass governance is always enabled 117 func clearRetention(ctx context.Context, target, versionID string, timeRef time.Time, withOlderVersions, isRecursive bool) error { 118 return applyRetention(ctx, lockOpClear, target, versionID, timeRef, withOlderVersions, isRecursive, "", 0, minio.Days, true) 119 } 120 121 func clearBucketLock(urlStr string) error { 122 return applyBucketLock(lockOpClear, urlStr, "", 0, "") 123 } 124 125 // main for retention clear command. 126 func mainRetentionClear(cliCtx *cli.Context) error { 127 ctx, cancelSetRetention := context.WithCancel(globalContext) 128 defer cancelSetRetention() 129 130 console.SetColor("RetentionSuccess", color.New(color.FgGreen, color.Bold)) 131 console.SetColor("RetentionFailure", color.New(color.FgYellow)) 132 133 target, versionID, rewind, withVersions, recursive, bucketMode := parseClearRetentionArgs(cliCtx) 134 135 fatalIfBucketLockNotSupported(ctx, target) 136 137 if bucketMode { 138 return clearBucketLock(target) 139 } 140 141 if withVersions && rewind.IsZero() { 142 rewind = time.Now().UTC() 143 } 144 145 return clearRetention(ctx, target, versionID, rewind, withVersions, recursive) 146 }