github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/quota-set.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  	"fmt"
    22  
    23  	"github.com/dustin/go-humanize"
    24  	"github.com/fatih/color"
    25  	"github.com/minio/cli"
    26  	json "github.com/minio/colorjson"
    27  	"github.com/minio/madmin-go/v3"
    28  	"github.com/minio/mc/pkg/probe"
    29  	"github.com/minio/pkg/v2/console"
    30  )
    31  
    32  var quotaSetFlags = []cli.Flag{
    33  	cli.StringFlag{
    34  		Name:  "size",
    35  		Usage: "set a hard quota, disallowing writes after quota is reached",
    36  	},
    37  }
    38  
    39  var quotaSetCmd = cli.Command{
    40  	Name:         "set",
    41  	Usage:        "set bucket quota",
    42  	Action:       mainQuotaSet,
    43  	OnUsageError: onUsageError,
    44  	Before:       setGlobalsFromContext,
    45  	Flags:        append(quotaSetFlags, globalFlags...),
    46  	CustomHelpTemplate: `NAME:
    47    {{.HelpName}} - {{.Usage}}
    48  
    49  USAGE:
    50    {{.HelpName}} TARGET [--size QUOTA]
    51  
    52  QUOTA
    53    quota accepts human-readable case-insensitive number
    54    suffixes such as "k", "m", "g" and "t" referring to the metric units KB,
    55    MB, GB and TB respectively. Adding an "i" to these prefixes, uses the IEC
    56    units, so that "gi" refers to "gibibyte" or "GiB". A "b" at the end is
    57    also accepted. Without suffixes the unit is bytes.
    58  
    59  FLAGS:
    60    {{range .VisibleFlags}}{{.}}
    61    {{end}}
    62  EXAMPLES:
    63    1. Set hard quota of 1gb for a bucket "mybucket" on MinIO.
    64       {{.Prompt}} {{.HelpName}} myminio/mybucket --size 1GB
    65  `,
    66  }
    67  
    68  // quotaMessage container for content message structure
    69  type quotaMessage struct {
    70  	op        string
    71  	Status    string `json:"status"`
    72  	Bucket    string `json:"bucket"`
    73  	Quota     uint64 `json:"quota,omitempty"`
    74  	QuotaType string `json:"type,omitempty"`
    75  }
    76  
    77  func (q quotaMessage) String() string {
    78  	switch q.op {
    79  	case "set":
    80  		return console.Colorize("QuotaMessage",
    81  			fmt.Sprintf("Successfully set bucket quota of %s on `%s`", humanize.IBytes(q.Quota), q.Bucket))
    82  	case "clear":
    83  		return console.Colorize("QuotaMessage",
    84  			fmt.Sprintf("Successfully cleared bucket quota configured on `%s`", q.Bucket))
    85  	default:
    86  		return console.Colorize("QuotaInfo",
    87  			fmt.Sprintf("Bucket `%s` has %s quota of %s", q.Bucket, q.QuotaType, humanize.IBytes(q.Quota)))
    88  	}
    89  }
    90  
    91  func (q quotaMessage) JSON() string {
    92  	jsonMessageBytes, e := json.MarshalIndent(q, "", " ")
    93  	fatalIf(probe.NewError(e), "Unable to marshal into JSON.")
    94  
    95  	return string(jsonMessageBytes)
    96  }
    97  
    98  // checkQuotaSetSyntax - validate all the passed arguments
    99  func checkQuotaSetSyntax(ctx *cli.Context) {
   100  	if len(ctx.Args()) == 0 || len(ctx.Args()) > 1 {
   101  		showCommandHelpAndExit(ctx, 1) // last argument is exit code
   102  	}
   103  }
   104  
   105  // mainQuotaSet is the handler for "mc quota set" command.
   106  func mainQuotaSet(ctx *cli.Context) error {
   107  	checkQuotaSetSyntax(ctx)
   108  
   109  	console.SetColor("QuotaMessage", color.New(color.FgGreen))
   110  	console.SetColor("QuotaInfo", color.New(color.FgBlue))
   111  
   112  	// Get the alias parameter from cli
   113  	args := ctx.Args()
   114  	aliasedURL := args.Get(0)
   115  
   116  	// Create a new MinIO Admin Client
   117  	client, err := newAdminClient(aliasedURL)
   118  	fatalIf(err, "Unable to initialize admin connection.")
   119  
   120  	_, targetURL := url2Alias(args[0])
   121  	if !ctx.IsSet("size") {
   122  		fatalIf(errInvalidArgument().Trace(ctx.Args().Tail()...),
   123  			"--size flag needs to be set.")
   124  	}
   125  	qType := madmin.HardQuota
   126  	quotaStr := ctx.String("size")
   127  	quota, e := humanize.ParseBytes(quotaStr)
   128  	fatalIf(probe.NewError(e).Trace(quotaStr), "Unable to parse quota")
   129  
   130  	fatalIf(probe.NewError(client.SetBucketQuota(globalContext, targetURL, &madmin.BucketQuota{
   131  		Quota: quota,
   132  		Type:  qType,
   133  	})).Trace(args...), "Unable to set bucket quota")
   134  
   135  	printMsg(quotaMessage{
   136  		op:        ctx.Command.Name,
   137  		Bucket:    targetURL,
   138  		Quota:     quota,
   139  		QuotaType: string(qType),
   140  		Status:    "success",
   141  	})
   142  
   143  	return nil
   144  }