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  }