-
Notifications
You must be signed in to change notification settings - Fork 515
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
admin bucket quota
command to manage quota
- Loading branch information
Poorna Krishnamoorthy
committed
Apr 24, 2020
1 parent
20dd701
commit 73b9817
Showing
5 changed files
with
266 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
/* | ||
* MinIO Client (C) 2020 MinIO, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
|
||
humanize "github.com/dustin/go-humanize" | ||
"github.com/fatih/color" | ||
"github.com/minio/cli" | ||
json "github.com/minio/mc/pkg/colorjson" | ||
"github.com/minio/mc/pkg/probe" | ||
"github.com/minio/minio/pkg/console" | ||
"github.com/minio/minio/pkg/madmin" | ||
) | ||
|
||
var adminQuotaFlags = []cli.Flag{ | ||
cli.StringFlag{ | ||
Name: "fifo", | ||
Usage: "Set fifo quota, allowing automatic deletion of older content", | ||
}, | ||
cli.StringFlag{ | ||
Name: "hard", | ||
Usage: "Set a hard quota, disallowing writes after quota is reached", | ||
}, | ||
cli.BoolFlag{ | ||
Name: "clear", | ||
Usage: "Clears bucket quota configured for bucket", | ||
}, | ||
} | ||
|
||
// quotaMessage container for content message structure | ||
type quotaMessage struct { | ||
op string | ||
Status string `json:"status"` | ||
Bucket string `json:"bucket"` | ||
Quota uint64 `json:"quota,omitempty"` | ||
QuotaType string `json:"type,omitempty"` | ||
} | ||
|
||
func (q quotaMessage) String() string { | ||
if q.op == "set" { | ||
return console.Colorize("QuotaMessage", | ||
fmt.Sprintf("Successfully set bucket quota of %s with %s type on `%s`", humanize.IBytes(q.Quota), q.QuotaType, q.Bucket)) | ||
} | ||
if q.op == "unset" { | ||
return console.Colorize("QuotaMessage", | ||
fmt.Sprintf("Successfully cleared bucket quota configured on `%s`", q.Bucket)) | ||
} | ||
return console.Colorize("QuotaInfo", | ||
fmt.Sprintf("Bucket `%s` has %s quota of %s", q.Bucket, q.QuotaType, humanize.IBytes(q.Quota))) | ||
} | ||
|
||
func (q quotaMessage) JSON() string { | ||
q.Status = "success" | ||
jsonMessageBytes, e := json.MarshalIndent(q, "", " ") | ||
fatalIf(probe.NewError(e), "Unable to marshal into JSON.") | ||
|
||
return string(jsonMessageBytes) | ||
} | ||
|
||
var adminBucketQuotaCmd = cli.Command{ | ||
Name: "quota", | ||
Usage: "Manage bucket quota", | ||
Action: mainAdminBucketQuota, | ||
Before: setGlobalsFromContext, | ||
Flags: append(adminQuotaFlags, globalFlags...), | ||
CustomHelpTemplate: `NAME: | ||
{{.HelpName}} - {{.Usage}} | ||
USAGE: | ||
{{.HelpName}} TARGET [--fifo | --hard] [QUOTA] | ||
QUOTA | ||
quota accepts human-readable case-insensitive number | ||
suffixes such as "k", "m", "g" and "t" referring to the metric units KB, | ||
MB, GB and TB respectively. Adding an "i" to these prefixes, uses the IEC | ||
units, so that "gi" refers to "gibibyte" or "GiB". A "b" at the end is | ||
also accepted. Without suffixes the unit is bytes. | ||
FLAGS: | ||
{{range .VisibleFlags}}{{.}} | ||
{{end}} | ||
EXAMPLES: | ||
1. Display bucket quota configured for "mybucket" on MinIO. | ||
{{.Prompt}} {{.HelpName}} myminio/mybucket | ||
2. Set FIFO quota for a bucket "mybucket" on MinIO. | ||
{{.Prompt}} {{.HelpName}} myminio/mybucket --fifo 64kB | ||
3. Set hard quota of 1gb for a bucket "mybucket" on MinIO. | ||
{{.Prompt}} {{.HelpName}} myminio/mybucket --hard 1gb | ||
4. Clear bucket quota configured for bucket "mybucket" on MinIO. | ||
{{.Prompt}} {{.HelpName}} myminio/mybucket --clear | ||
`, | ||
} | ||
|
||
// checkAdminBucketQuotaSyntax - validate all the passed arguments | ||
func checkAdminBucketQuotaSyntax(ctx *cli.Context) { | ||
if len(ctx.Args()) == 0 || len(ctx.Args()) > 1 { | ||
cli.ShowCommandHelpAndExit(ctx, "quota", 1) // last argument is exit code | ||
} | ||
|
||
if ctx.IsSet("hard") && ctx.IsSet("fifo") { | ||
fatalIf(errInvalidArgument(), "Only one of --hard or --fifo flags can be set") | ||
} | ||
if (ctx.IsSet("hard") || ctx.IsSet("fifo")) && len(ctx.Args()) == 0 { | ||
fatalIf(errInvalidArgument().Trace(ctx.Args()...), "please specify bucket and quota") | ||
} | ||
if ctx.IsSet("clear") && len(ctx.Args()) == 0 { | ||
fatalIf(errInvalidArgument().Trace(ctx.Args()...), "clear flag must be passed with target alone") | ||
} | ||
} | ||
|
||
// mainAdminBucketQuota is the handler for "mc admin bucket quota" command. | ||
func mainAdminBucketQuota(ctx *cli.Context) error { | ||
checkAdminBucketQuotaSyntax(ctx) | ||
|
||
console.SetColor("QuotaMessage", color.New(color.FgGreen)) | ||
console.SetColor("QuotaInfo", color.New(color.FgBlue)) | ||
|
||
// Get the alias parameter from cli | ||
args := ctx.Args() | ||
aliasedURL := args.Get(0) | ||
|
||
// Create a new MinIO Admin Client | ||
client, err := newAdminClient(aliasedURL) | ||
fatalIf(err, "Unable to initialize admin connection.") | ||
quotaStr := ctx.String("fifo") | ||
if ctx.IsSet("hard") { | ||
quotaStr = ctx.String("hard") | ||
} | ||
_, targetURL := url2Alias(args[0]) | ||
if ctx.IsSet("fifo") || ctx.IsSet("hard") && len(args) == 1 { | ||
qType := madmin.FIFOQuota | ||
if ctx.IsSet("hard") { | ||
qType = madmin.HardQuota | ||
} | ||
quota, err := humanize.ParseBytes(quotaStr) | ||
fatalIf(probe.NewError(err).Trace(quotaStr), "Unable to parse quota") | ||
if err = client.SetBucketQuota(globalContext, targetURL, quota, qType); err != nil { | ||
fatalIf(probe.NewError(err).Trace(args...), "Cannot set bucket quota") | ||
|
||
} | ||
printMsg(quotaMessage{ | ||
op: "set", | ||
Bucket: targetURL, | ||
Quota: quota, | ||
QuotaType: string(qType), | ||
}) | ||
} else if ctx.Bool("clear") && len(args) == 1 { | ||
if err := client.RemoveBucketQuota(globalContext, targetURL); err != nil { | ||
fatalIf(probe.NewError(err).Trace(args...), "Cannot clear bucket quota config") | ||
} | ||
printMsg(quotaMessage{ | ||
op: "unset", | ||
Bucket: targetURL, | ||
}) | ||
|
||
} else { | ||
qCfg, e := client.GetBucketQuota(globalContext, targetURL) | ||
fatalIf(probe.NewError(e).Trace(args...), "Cannot get bucket quota") | ||
printMsg(quotaMessage{ | ||
op: "get", | ||
Bucket: targetURL, | ||
Quota: qCfg.Quota, | ||
QuotaType: string(qCfg.Type), | ||
}) | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* MinIO Client (C) 2020 MinIO, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package cmd | ||
|
||
import "github.com/minio/cli" | ||
|
||
var adminBucketCmd = cli.Command{ | ||
Name: "bucket", | ||
Usage: "manage buckets defined in the MinIO server", | ||
Action: mainAdminBucket, | ||
Before: setGlobalsFromContext, | ||
Flags: globalFlags, | ||
Subcommands: []cli.Command{ | ||
adminBucketQuotaCmd, | ||
}, | ||
HideHelpCommand: true, | ||
} | ||
|
||
// mainAdminBucket is the handle for "mc admin bucket" command. | ||
func mainAdminBucket(ctx *cli.Context) error { | ||
cli.ShowCommandHelp(ctx, ctx.Args().First()) | ||
return nil | ||
// Sub-commands like "quota", "usage" have their own main. | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -52,6 +52,7 @@ var adminCmd = cli.Command{ | |
adminPrometheusCmd, | ||
adminKMSCmd, | ||
adminOBDCmd, | ||
adminBucketCmd, | ||
}, | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters