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  }