Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to enable disable ILM expiry for site replication #4698

Merged
merged 12 commits into from
Nov 22, 2023
Merged
16 changes: 14 additions & 2 deletions cmd/admin-replicate-add.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,20 @@ import (
"github.com/minio/pkg/v2/console"
)

var adminReplicateAddFlags = []cli.Flag{
cli.BoolFlag{
Name: "replicate-ilm-expiry",
Usage: "replicate ILM expiry rules",
},
}

var adminReplicateAddCmd = cli.Command{
Name: "add",
Usage: "add one or more sites for replication",
Action: mainAdminReplicateAdd,
OnUsageError: onUsageError,
Before: setGlobalsFromContext,
Flags: globalFlags,
Flags: append(globalFlags, adminReplicateAddFlags...),
CustomHelpTemplate: `NAME:
{{.HelpName}} - {{.Usage}}

Expand All @@ -48,6 +55,9 @@ FLAGS:
EXAMPLES:
1. Add a site for cluster-level replication:
{{.Prompt}} {{.HelpName}} minio1 minio2

2. Add a site for cluster-level replication with replication of ILM expiry rules:
{{.Prompt}} {{.HelpName}} minio1 minio2 --replicate-ilm-expiry
`,
}

Expand Down Expand Up @@ -106,7 +116,9 @@ func mainAdminReplicateAdd(ctx *cli.Context) error {
})
}

res, e := client.SiteReplicationAdd(globalContext, ps, madmin.SRAddOptions{})
var opts madmin.SRAddOptions
opts.ReplicateILMExpiry = ctx.Bool("replicate-ilm-expiry")
res, e := client.SiteReplicationAdd(globalContext, ps, opts)
fatalIf(probe.NewError(e).Trace(args...), "Unable to add sites for replication")

printMsg(successMessage(res))
Expand Down
10 changes: 7 additions & 3 deletions cmd/admin-replicate-info.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package cmd

import (
"fmt"
"strconv"
"strings"

humanize "github.com/dustin/go-humanize"
Expand Down Expand Up @@ -75,7 +76,8 @@ func (i srInfo) String() string {
Field{"Endpoint", 46},
Field{"Sync", 4},
Field{"Bandwidth", 10},
).buildRow("Deployment ID", "Site Name", "Endpoint", "Sync", "Bandwidth"))
Field{"ILM Expiry Replication", 25},
).buildRow("Deployment ID", "Site Name", "Endpoint", "Sync", "Bandwidth", "ILM Expiry Replication"))
shtripat marked this conversation as resolved.
Show resolved Hide resolved
messages = append(messages, r)

r = console.Colorize("THeaders", newPrettyTable(" | ",
Expand All @@ -85,7 +87,8 @@ func (i srInfo) String() string {
Field{"Endpoint", 46},
Field{"Sync", 4},
Field{"Bandwidth", 10},
).buildRow("", "", "", "", "Per Bucket"))
Field{"ILM Expiry Replication", 25},
).buildRow("", "", "", "", "Per Bucket", ""))
messages = append(messages, r)
for _, peer := range info.Sites {
var chk string
Expand All @@ -103,7 +106,8 @@ func (i srInfo) String() string {
Field{"Endpoint", 46},
Field{"Sync", 4},
Field{"Bandwidth", 10},
).buildRow(peer.DeploymentID, peer.Name, peer.Endpoint, chk, limit))
Field{"ILM Expiry Replication", 25},
).buildRow(peer.DeploymentID, peer.Name, peer.Endpoint, chk, limit, strconv.FormatBool(peer.ReplicateILMExpiry)))
messages = append(messages, r)
}
} else {
Expand Down
115 changes: 108 additions & 7 deletions cmd/admin-replicate-status.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ var adminReplicateStatusFlags = []cli.Flag{
Name: "groups",
Usage: "display only groups",
},
cli.BoolFlag{
Name: "ilm-expiry-rules",
Usage: "display only ilm expiry rules",
},
cli.BoolFlag{
Name: "all",
Usage: "display all available site replication status",
Expand All @@ -70,6 +74,10 @@ var adminReplicateStatusFlags = []cli.Flag{
Name: "group",
Usage: "display group sync status",
},
cli.StringFlag{
Name: "ilm-expiry-rule",
Usage: "display ILM expiry rule sync status",
},
}

// Some cell values
Expand Down Expand Up @@ -312,6 +320,42 @@ func (i srStatus) String() string {
}
}
}
if i.opts.ILMExpiryRules {
messages = append(messages,
console.Colorize("SummaryHdr", "ILM Expiry Rules replication status:"))
switch {
case i.MaxILMExpiryRules == 0:
messages = append(messages, console.Colorize("Summary", "No ILM Expiry Rules present\n"))
default:
msg := console.Colorize(i.getTheme(len(info.ILMExpiryStats) == 0), fmt.Sprintf("%d/%d ILM Expiry Rules in sync", info.MaxILMExpiryRules-len(info.ILMExpiryStats), info.MaxILMExpiryRules)) + "\n"
messages = append(messages, fmt.Sprintf("%s %s", coloredDot, msg))
if len(i.ILMExpiryStats) > 0 {
messages = append(messages, i.siteHeader(siteNames, "ILM Expiry Rules"))
}
var detailFields []Field
for b, ssMap := range i.ILMExpiryStats {
var details []string
details = append(details, b)
detailFields = append(detailFields, legendFields[0])
for _, sname := range siteNames {
detailFields = append(detailFields, legendFields[0])
dID := nameIDMap[sname]
ss := ssMap[dID]
switch {
case !ss.HasILMExpiryRules:
details = append(details, blankCell)
case ss.ILMExpiryRuleMismatch:
details = append(details, fmt.Sprintf("%s in-sync", crossTickCell))
default:
details = append(details, fmt.Sprintf("%s in-sync", tickCell))
}
}
messages = append(messages, newPrettyTable(" | ",
detailFields...).buildRow(details...))
messages = append(messages, "")
}
}
}

switch i.opts.Entity {
case madmin.SRBucketEntity:
Expand All @@ -322,7 +366,8 @@ func (i srStatus) String() string {
messages = append(messages, i.getUserStatusSummary(siteNames, nameIDMap, "User")...)
case madmin.SRGroupEntity:
messages = append(messages, i.getGroupStatusSummary(siteNames, nameIDMap, "Group")...)

case madmin.SRILMExpiryRuleEntity:
messages = append(messages, i.getILMExpiryStatusSummary(siteNames, nameIDMap, "ILMExpiryRule")...)
}
if i.opts.Metrics {
uiFn := func(theme string) func(string) string {
Expand Down Expand Up @@ -716,29 +761,85 @@ func (i srStatus) getGroupStatusSummary(siteNames []string, nameIDMap map[string
return messages
}

func (i srStatus) getILMExpiryStatusSummary(siteNames []string, nameIDMap map[string]string, legend string) []string {
var messages []string
coloredDot := console.Colorize("Status", dot)
var found bool
for _, st := range i.SRStatusInfo.ILMExpiryStats[i.opts.EntityValue] {
if st.HasILMExpiryRules {
found = true
break
}
}
if !found {
messages = append(messages, console.Colorize("Summary", fmt.Sprintf("ILM Expiry Rule %s not found\n", i.opts.EntityValue)))
return messages
}

rowLegend := []string{"ILM Expiry Rule"}
detailFields := make([][]Field, len(rowLegend))

var rules []string
detailFields[0] = make([]Field, len(siteNames)+1)
detailFields[0][0] = Field{"Entity", 15}
rules = append(rules, "ILM Expiry Rule")
rows := make([]string, len(rowLegend))
for j, sname := range siteNames {
dID := nameIDMap[sname]
ss := i.SRStatusInfo.ILMExpiryStats[i.opts.EntityValue][dID]
var theme, msgStr string
for r := range rowLegend {
switch r {
case 0:
theme, msgStr = syncStatus(ss.ILMExpiryRuleMismatch, ss.HasILMExpiryRules)
rules = append(rules, msgStr)
detailFields[r][j+1] = Field{theme, fieldLen}
}
}
}
for r := range rowLegend {
switch r {
case 0:
rows[r] = newPrettyTable(" | ",
detailFields[r]...).buildRow(rules...)
}
}
messages = append(messages,
console.Colorize("SummaryHdr", fmt.Sprintf("%s %s\n", coloredDot, console.Colorize("Summary", "ILM Expiry Rule replication summary for: ")+console.Colorize("UserMessage", i.opts.EntityValue))))
siteHdr := i.siteHeader(siteNames, legend)
messages = append(messages, siteHdr)

messages = append(messages, rows...)
return messages
}

// Calculate srstatus options for command line flags
func srStatusOpts(ctx *cli.Context) (opts madmin.SRStatusOptions) {
if !(ctx.IsSet("buckets") ||
ctx.IsSet("users") ||
ctx.IsSet("groups") ||
ctx.IsSet("policies") ||
ctx.IsSet("ilm-expiry-rules") ||
ctx.IsSet("bucket") ||
ctx.IsSet("user") ||
ctx.IsSet("group") ||
ctx.IsSet("policy") ||
ctx.IsSet("ilm-expiry-rule") ||
ctx.IsSet("all")) || ctx.IsSet("all") {
opts.Buckets = true
opts.Users = true
opts.Groups = true
opts.Policies = true
opts.Metrics = true
opts.ILMExpiryRules = true
return
}
opts.Buckets = ctx.Bool("buckets")
opts.Policies = ctx.Bool("policies")
opts.Users = ctx.Bool("users")
opts.Groups = ctx.Bool("groups")
for _, name := range []string{"bucket", "user", "group", "policy"} {
opts.ILMExpiryRules = ctx.Bool("ilm-expiry-rules")
for _, name := range []string{"bucket", "user", "group", "policy", "ilm-expiry-rule"} {
if ctx.IsSet(name) {
opts.Entity = madmin.GetSREntityType(name)
opts.EntityValue = ctx.String(name)
Expand All @@ -756,13 +857,13 @@ func mainAdminReplicationStatus(ctx *cli.Context) error {
fatalIf(errInvalidArgument().Trace(ctx.Args().Tail()...),
"Need exactly one alias argument.")
}
groupStatus := ctx.IsSet("buckets") || ctx.IsSet("groups") || ctx.IsSet("users") || ctx.IsSet("policies")
indivStatus := ctx.IsSet("bucket") || ctx.IsSet("group") || ctx.IsSet("user") || ctx.IsSet("policy")
groupStatus := ctx.IsSet("buckets") || ctx.IsSet("groups") || ctx.IsSet("users") || ctx.IsSet("policies") || ctx.IsSet("ilm-expiry-rules")
indivStatus := ctx.IsSet("bucket") || ctx.IsSet("group") || ctx.IsSet("user") || ctx.IsSet("policy") || ctx.IsSet("ilm-expiry-rule")
if groupStatus && indivStatus {
fatalIf(errInvalidArgument().Trace(ctx.Args().Tail()...),
"Cannot specify both (bucket|group|policy|user) flag and one or more of buckets|groups|policies|users) flag(s)")
"Cannot specify both (bucket|group|policy|user|ilm-expiry-rule) flag and one or more of buckets|groups|policies|users|ilm-expiry-rules) flag(s)")
}
setSlc := []bool{ctx.IsSet("bucket"), ctx.IsSet("user"), ctx.IsSet("group"), ctx.IsSet("policy")}
setSlc := []bool{ctx.IsSet("bucket"), ctx.IsSet("user"), ctx.IsSet("group"), ctx.IsSet("policy"), ctx.IsSet("ilm-expiry-rule")}
count := 0
for _, s := range setSlc {
if s {
Expand All @@ -771,7 +872,7 @@ func mainAdminReplicationStatus(ctx *cli.Context) error {
}
if count > 1 {
fatalIf(errInvalidArgument().Trace(ctx.Args().Tail()...),
"Cannot specify more than one of --bucket, --policy, --user, --group flags at the same time")
"Cannot specify more than one of --bucket, --policy, --user, --group, --ilm-expiry-rule flags at the same time")
}
}

Expand Down
31 changes: 27 additions & 4 deletions cmd/admin-replicate-update.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ var adminReplicateUpdateFlags = []cli.Flag{
Name: "bucket-bandwidth",
Usage: "Set default bandwidth limit for bucket in bits per second (K,B,G,T for metric and Ki,Bi,Gi,Ti for IEC units)",
},
cli.BoolFlag{
Name: "disable-ilm-expiry-replication",
Usage: "disable ILM expiry rules replication",
},
cli.BoolFlag{
Name: "enable-ilm-expiry-replication",
Usage: "enable ILM expiry rules replication",
},
}

var adminReplicateUpdateCmd = cli.Command{
Expand Down Expand Up @@ -80,6 +88,12 @@ EXAMPLES:

2. Edit a site in cluster-level replication to set default bandwidth limit for bucket:
{{.Prompt}} {{.HelpName}} myminio --deployment-id c1758167-4426-454f-9aae-5c3dfdf6df64 --bucket-bandwidth "2G"

3. Disable replication of ILM expiry in cluster-level replication:
{{.Prompt}} {{.HelpName}} myminio --disable-ilm-expiry-replication

4. Enable replication of ILM expiry in cluster-level replication:
{{.Prompt}} {{.HelpName}} myminio --enable-ilm-expiry-replication
`,
}

Expand Down Expand Up @@ -125,15 +139,21 @@ func mainAdminReplicateUpdate(ctx *cli.Context) error {
client, err := newAdminClient(aliasedURL)
fatalIf(err, "Unable to initialize admin connection.")

if !ctx.IsSet("deployment-id") {
if !ctx.IsSet("deployment-id") && !ctx.IsSet("disable-ilm-expiry-replication") && !ctx.IsSet("enable-ilm-expiry-replication") {
fatalIf(errInvalidArgument(), "--deployment-id is a required flag")
}
if !ctx.IsSet("endpoint") && !ctx.IsSet("mode") && !ctx.IsSet("sync") && !ctx.IsSet("bucket-bandwidth") {
fatalIf(errInvalidArgument(), "--endpoint, --mode or --bucket-bandwidth is a required flag")
if !ctx.IsSet("endpoint") && !ctx.IsSet("mode") && !ctx.IsSet("sync") && !ctx.IsSet("bucket-bandwidth") && !ctx.IsSet("disable-ilm-expiry-replication") && !ctx.IsSet("enable-ilm-expiry-replication") {
fatalIf(errInvalidArgument(), "--endpoint, --mode, --bucket-bandwidth, --disable-ilm-expiry-replication or --enable-ilm-expiry-replication is a required flag")
}
if ctx.IsSet("mode") && ctx.IsSet("sync") {
fatalIf(errInvalidArgument(), "either --sync or --mode flag should be specified")
}
if ctx.IsSet("disable-ilm-expiry-replication") && ctx.IsSet("enable-ilm-expiry-replication") {
fatalIf(errInvalidArgument(), "either --disable-ilm-expiry-replication or --enable-ilm-expiry-replication flag should be specified")
}
if (ctx.IsSet("disable-ilm-expiry-replication") || ctx.IsSet("enable-ilm-expiry-replication")) && ctx.IsSet("deployment-id") {
fatalIf(errInvalidArgument(), "--deployment-id should not be set with --disable-ilm-expiry-replication or --enable-ilm-expiry-replication")
}

var syncState string
if ctx.IsSet("sync") { // for backward compatibility - deprecated Jul 2023
Expand Down Expand Up @@ -175,12 +195,15 @@ func mainAdminReplicateUpdate(ctx *cli.Context) error {
}
ep = u.String()
}
var opts madmin.SREditOptions
opts.DisableILMExpiryReplication = ctx.Bool("disable-ilm-expiry-replication")
opts.EnableILMExpiryReplication = ctx.Bool("enable-ilm-expiry-replication")
res, e := client.SiteReplicationEdit(globalContext, madmin.PeerInfo{
DeploymentID: ctx.String("deployment-id"),
Endpoint: ep,
SyncState: madmin.SyncStatus(syncState),
DefaultBandwidth: bwDefaults,
}, madmin.SREditOptions{})
}, opts)
fatalIf(probe.NewError(e).Trace(args...), "Unable to edit cluster replication site endpoint")

printMsg(updateSuccessMessage(res))
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ require (
github.com/gdamore/tcell/v2 v2.6.0
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/juju/ratelimit v1.0.2
github.com/minio/madmin-go/v3 v3.0.29
github.com/minio/madmin-go/v3 v3.0.32
github.com/minio/pkg/v2 v2.0.2
github.com/muesli/reflow v0.3.0
github.com/navidys/tvxwidgets v0.3.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ github.com/minio/colorjson v1.0.6 h1:m7TUvpvt0u7FBmVIEQNIa0T4NBQlxrcMBp4wJKsg2Ik
github.com/minio/colorjson v1.0.6/go.mod h1:LUXwS5ZGNb6Eh9f+t+3uJiowD3XsIWtsvTriUBeqgYs=
github.com/minio/filepath v1.0.0 h1:fvkJu1+6X+ECRA6G3+JJETj4QeAYO9sV43I79H8ubDY=
github.com/minio/filepath v1.0.0/go.mod h1:/nRZA2ldl5z6jT9/KQuvZcQlxZIMQoFFQPvEXx9T/Bw=
github.com/minio/madmin-go/v3 v3.0.29 h1:3bNLArtxIFud5wyb5/DnF5DGLBvcSJyzCA44EclX1Ow=
github.com/minio/madmin-go/v3 v3.0.29/go.mod h1:4QN2NftLSV7MdlT50dkrenOMmNVHluxTvlqJou3hte8=
github.com/minio/madmin-go/v3 v3.0.32 h1:2O0Up8V/R3eLRQl7wNj+fwoUCRiagYmsGVNUm5V72UA=
github.com/minio/madmin-go/v3 v3.0.32/go.mod h1:4QN2NftLSV7MdlT50dkrenOMmNVHluxTvlqJou3hte8=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.63 h1:GbZ2oCvaUdgT5640WJOpyDhhDxvknAJU2/T3yurwcbQ=
Expand Down
Loading