github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/admin-replicate-update.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 "net/url" 22 "strings" 23 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 adminReplicateUpdateFlags = []cli.Flag{ 33 cli.StringFlag{ 34 Name: "deployment-id", 35 Usage: "deployment id of the site, should be a unique value", 36 }, 37 cli.StringFlag{ 38 Name: "endpoint", 39 Usage: "endpoint for the site", 40 }, 41 cli.StringFlag{ 42 Name: "mode", 43 Usage: "change mode of replication for this target, valid values are ['sync', 'async'].", 44 Value: "", 45 }, 46 cli.StringFlag{ 47 Name: "sync", 48 Usage: "enable synchronous replication for this target, valid values are ['enable', 'disable'].", 49 Value: "disable", 50 Hidden: true, // deprecated Jul 2023 51 }, 52 cli.StringFlag{ 53 Name: "bucket-bandwidth", 54 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)", 55 }, 56 cli.BoolFlag{ 57 Name: "disable-ilm-expiry-replication", 58 Usage: "disable ILM expiry rules replication", 59 }, 60 cli.BoolFlag{ 61 Name: "enable-ilm-expiry-replication", 62 Usage: "enable ILM expiry rules replication", 63 }, 64 } 65 66 var adminReplicateUpdateCmd = cli.Command{ 67 Name: "update", 68 Aliases: []string{"edit"}, 69 HiddenAliases: true, 70 Usage: "modify endpoint of site participating in site replication", 71 Action: mainAdminReplicateUpdate, 72 OnUsageError: onUsageError, 73 Before: setGlobalsFromContext, 74 Flags: append(globalFlags, adminReplicateUpdateFlags...), 75 CustomHelpTemplate: `NAME: 76 {{.HelpName}} - {{.Usage}} 77 78 USAGE: 79 {{.HelpName}} ALIAS --deployment-id [DEPLOYMENT-ID] --endpoint [NEW-ENDPOINT] 80 81 FLAGS: 82 {{range .VisibleFlags}}{{.}} 83 {{end}} 84 85 EXAMPLES: 86 1. Edit a site endpoint participating in cluster-level replication: 87 {{.Prompt}} {{.HelpName}} myminio --deployment-id c1758167-4426-454f-9aae-5c3dfdf6df64 --endpoint https://minio2:9000 88 89 2. Set default bucket bandwidth limit for replication from myminio to the peer cluster with deployment-id c1758167-4426-454f-9aae-5c3dfdf6df64 90 {{.Prompt}} {{.HelpName}} myminio --deployment-id c1758167-4426-454f-9aae-5c3dfdf6df64 --bucket-bandwidth "2G" 91 92 3. Disable replication of ILM expiry in cluster-level replication: 93 {{.Prompt}} {{.HelpName}} myminio --disable-ilm-expiry-replication 94 95 4. Enable replication of ILM expiry in cluster-level replication: 96 {{.Prompt}} {{.HelpName}} myminio --enable-ilm-expiry-replication 97 `, 98 } 99 100 type updateSuccessMessage madmin.ReplicateEditStatus 101 102 func (m updateSuccessMessage) JSON() string { 103 bs, e := json.MarshalIndent(madmin.ReplicateEditStatus(m), "", " ") 104 fatalIf(probe.NewError(e), "Unable to marshal into JSON.") 105 return string(bs) 106 } 107 108 func (m updateSuccessMessage) String() string { 109 v := madmin.ReplicateEditStatus(m) 110 messages := []string{v.Status} 111 112 if v.ErrDetail != "" { 113 messages = append(messages, v.ErrDetail) 114 } 115 return console.Colorize("UserMessage", strings.Join(messages, "\n")) 116 } 117 118 func checkAdminReplicateUpdateSyntax(ctx *cli.Context) { 119 // Check argument count 120 argsNr := len(ctx.Args()) 121 if argsNr < 1 { 122 showCommandHelpAndExit(ctx, 1) // last argument is exit code 123 } 124 if argsNr != 1 { 125 fatalIf(errInvalidArgument().Trace(ctx.Args().Tail()...), 126 "Invalid arguments specified for edit command.") 127 } 128 } 129 130 func mainAdminReplicateUpdate(ctx *cli.Context) error { 131 checkAdminReplicateUpdateSyntax(ctx) 132 console.SetColor("UserMessage", color.New(color.FgGreen)) 133 134 // Get the alias parameter from cli 135 args := ctx.Args() 136 aliasedURL := args.Get(0) 137 138 // Create a new MinIO Admin Client 139 client, err := newAdminClient(aliasedURL) 140 fatalIf(err, "Unable to initialize admin connection.") 141 142 if !ctx.IsSet("deployment-id") && !ctx.IsSet("disable-ilm-expiry-replication") && !ctx.IsSet("enable-ilm-expiry-replication") { 143 fatalIf(errInvalidArgument(), "--deployment-id is a required flag") 144 } 145 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") { 146 fatalIf(errInvalidArgument(), "--endpoint, --mode, --bucket-bandwidth, --disable-ilm-expiry-replication or --enable-ilm-expiry-replication is a required flag") 147 } 148 if ctx.IsSet("mode") && ctx.IsSet("sync") { 149 fatalIf(errInvalidArgument(), "either --sync or --mode flag should be specified") 150 } 151 if ctx.IsSet("disable-ilm-expiry-replication") && ctx.IsSet("enable-ilm-expiry-replication") { 152 fatalIf(errInvalidArgument(), "either --disable-ilm-expiry-replication or --enable-ilm-expiry-replication flag should be specified") 153 } 154 if (ctx.IsSet("disable-ilm-expiry-replication") || ctx.IsSet("enable-ilm-expiry-replication")) && ctx.IsSet("deployment-id") { 155 fatalIf(errInvalidArgument(), "--deployment-id should not be set with --disable-ilm-expiry-replication or --enable-ilm-expiry-replication") 156 } 157 158 var syncState string 159 if ctx.IsSet("sync") { // for backward compatibility - deprecated Jul 2023 160 syncState = strings.ToLower(ctx.String("sync")) 161 switch syncState { 162 case "enable", "disable": 163 default: 164 fatalIf(errInvalidArgument().Trace(args...), "--sync can be either [enable|disable]") 165 } 166 } 167 168 if ctx.IsSet("mode") { 169 mode := strings.ToLower(ctx.String("mode")) 170 switch mode { 171 case "sync": 172 syncState = "enable" 173 case "async": 174 syncState = "disable" 175 default: 176 fatalIf(errInvalidArgument().Trace(args...), "--mode can be either [sync|async]") 177 } 178 } 179 180 var bwDefaults madmin.BucketBandwidth 181 if ctx.IsSet("bucket-bandwidth") { 182 bandwidthStr := ctx.String("bucket-bandwidth") 183 bandwidth, e := getBandwidthInBytes(bandwidthStr) 184 fatalIf(probe.NewError(e).Trace(bandwidthStr), "invalid bandwidth value") 185 186 bwDefaults.Limit = bandwidth 187 bwDefaults.IsSet = true 188 } 189 var ep string 190 if ctx.IsSet("endpoint") { 191 parsedURL := ctx.String("endpoint") 192 u, e := url.Parse(parsedURL) 193 if e != nil { 194 fatalIf(errInvalidArgument().Trace(parsedURL), "Unsupported URL format %v", e) 195 } 196 ep = u.String() 197 } 198 var opts madmin.SREditOptions 199 opts.DisableILMExpiryReplication = ctx.Bool("disable-ilm-expiry-replication") 200 opts.EnableILMExpiryReplication = ctx.Bool("enable-ilm-expiry-replication") 201 res, e := client.SiteReplicationEdit(globalContext, madmin.PeerInfo{ 202 DeploymentID: ctx.String("deployment-id"), 203 Endpoint: ep, 204 SyncState: madmin.SyncStatus(syncState), 205 DefaultBandwidth: bwDefaults, 206 }, opts) 207 fatalIf(probe.NewError(e).Trace(args...), "Unable to edit cluster replication site endpoint") 208 209 printMsg(updateSuccessMessage(res)) 210 211 return nil 212 }