github.com/minio/mc@v0.0.0-20240507152021-646712d5e5fb/cmd/replicate-remove.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/fatih/color" 24 "github.com/minio/cli" 25 json "github.com/minio/colorjson" 26 "github.com/minio/mc/pkg/probe" 27 "github.com/minio/minio-go/v7/pkg/replication" 28 "github.com/minio/pkg/v2/console" 29 ) 30 31 var replicateRemoveFlags = []cli.Flag{ 32 cli.StringFlag{ 33 Name: "id", 34 Usage: "id for the rule, should be a unique value", 35 }, 36 cli.BoolFlag{ 37 Name: "force", 38 Usage: "force remove all the replication configuration rules on the bucket", 39 }, 40 cli.BoolFlag{ 41 Name: "all", 42 Usage: "remove all replication configuration rules of the bucket, force flag enforced", 43 }, 44 } 45 46 var replicateRemoveCmd = cli.Command{ 47 Name: "remove", 48 ShortName: "rm", 49 Usage: "remove a server side replication configuration rule", 50 Action: mainReplicateRemove, 51 OnUsageError: onUsageError, 52 Before: setGlobalsFromContext, 53 Flags: append(globalFlags, replicateRemoveFlags...), 54 CustomHelpTemplate: `NAME: 55 {{.HelpName}} - {{.Usage}} 56 57 USAGE: 58 {{.HelpName}} TARGET 59 60 FLAGS: 61 {{range .VisibleFlags}}{{.}} 62 {{end}} 63 EXAMPLES: 64 1. Remove replication configuration rule on bucket "mybucket" for alias "myminio" with rule id "bsib5mgt874bi56l0fmg". 65 {{.Prompt}} {{.HelpName}} --id "bsib5mgt874bi56l0fmg" myminio/mybucket 66 67 2. Remove all the replication configuration rules on bucket "mybucket" for alias "myminio". --force flag is required. 68 {{.Prompt}} {{.HelpName}} --all --force myminio/mybucket 69 `, 70 } 71 72 // checkReplicateRemoveSyntax - validate all the passed arguments 73 func checkReplicateRemoveSyntax(ctx *cli.Context) { 74 if len(ctx.Args()) != 1 { 75 showCommandHelpAndExit(ctx, 1) // last argument is exit code 76 } 77 rmAll := ctx.Bool("all") 78 rmForce := ctx.Bool("force") 79 rID := ctx.String("id") 80 81 rmChk := (rmAll && rmForce) || (!rmAll && !rmForce) 82 if !rmChk { 83 fatalIf(errInvalidArgument(), 84 "It is mandatory to specify --all and --force flag together for mc "+ctx.Command.FullName()+".") 85 } 86 if rmAll && rmForce { 87 return 88 } 89 90 if rID == "" { 91 fatalIf(errInvalidArgument().Trace(rID), "rule ID cannot be empty") 92 } 93 } 94 95 type replicateRemoveMessage struct { 96 Op string `json:"op"` 97 Status string `json:"status"` 98 URL string `json:"url"` 99 ID string `json:"id"` 100 } 101 102 func (l replicateRemoveMessage) JSON() string { 103 l.Status = "success" 104 jsonMessageBytes, e := json.MarshalIndent(l, "", " ") 105 fatalIf(probe.NewError(e), "Unable to marshal into JSON.") 106 return string(jsonMessageBytes) 107 } 108 109 func (l replicateRemoveMessage) String() string { 110 if l.ID != "" { 111 return console.Colorize("replicateRemoveMessage", "Replication configuration rule with ID `"+l.ID+"`removed from "+l.URL+".") 112 } 113 return console.Colorize("replicateRemoveMessage", "Replication configuration removed from "+l.URL+" successfully.") 114 } 115 116 func mainReplicateRemove(cliCtx *cli.Context) error { 117 ctx, cancelReplicateRemove := context.WithCancel(globalContext) 118 defer cancelReplicateRemove() 119 120 console.SetColor("replicateRemoveMessage", color.New(color.FgGreen)) 121 122 checkReplicateRemoveSyntax(cliCtx) 123 124 // Get the alias parameter from cli 125 args := cliCtx.Args() 126 aliasedURL := args.Get(0) 127 // Create a new Client 128 client, err := newClient(aliasedURL) 129 fatalIf(err, "Unable to initialize connection.") 130 rcfg, err := client.GetReplication(ctx) 131 fatalIf(err.Trace(args...), "Unable to get replication configuration") 132 133 rmAll := cliCtx.Bool("all") 134 rmForce := cliCtx.Bool("force") 135 ruleID := cliCtx.String("id") 136 137 if rcfg.Empty() && !rmAll { 138 printMsg(replicateRemoveMessage{ 139 Op: cliCtx.Command.Name, 140 Status: "success", 141 URL: aliasedURL, 142 }) 143 return nil 144 } 145 if rmAll && rmForce { 146 fatalIf(client.RemoveReplication(ctx), "Unable to remove replication configuration") 147 } else { 148 var removeArn string 149 for _, rule := range rcfg.Rules { 150 if rule.ID == ruleID { 151 removeArn = rule.Destination.Bucket 152 } 153 } 154 opts := replication.Options{ 155 ID: ruleID, 156 Op: replication.RemoveOption, 157 } 158 fatalIf(client.SetReplication(ctx, &rcfg, opts), "Could not remove replication rule") 159 admclient, cerr := newAdminClient(aliasedURL) 160 fatalIf(cerr.Trace(aliasedURL), "Unable to initialize admin connection.") 161 _, sourceBucket := url2Alias(args[0]) 162 fatalIf(probe.NewError(admclient.RemoveRemoteTarget(globalContext, sourceBucket, removeArn)).Trace(args...), "Unable to remove remote target") 163 164 } 165 printMsg(replicateRemoveMessage{ 166 Op: cliCtx.Command.Name, 167 Status: "success", 168 URL: aliasedURL, 169 ID: ruleID, 170 }) 171 return nil 172 }