vitess.io/vitess@v0.16.2/go/cmd/vtctldclient/command/shard_routing_rules.go (about) 1 /* 2 Copyright 2022 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package command 18 19 import ( 20 "errors" 21 "fmt" 22 "os" 23 "strings" 24 25 "github.com/spf13/cobra" 26 27 "vitess.io/vitess/go/cmd/vtctldclient/cli" 28 "vitess.io/vitess/go/json2" 29 30 vschemapb "vitess.io/vitess/go/vt/proto/vschema" 31 vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" 32 ) 33 34 var ( 35 // ApplyShardRoutingRules makes an ApplyShardRoutingRules gRPC call to a vtctld. 36 ApplyShardRoutingRules = &cobra.Command{ 37 Use: "ApplyShardRoutingRules {--rules RULES | --rules-file RULES_FILE} [--cells=c1,c2,...] [--skip-rebuild] [--dry-run]", 38 Short: "Applies the provided shard routing rules.", 39 DisableFlagsInUseLine: true, 40 Args: cobra.NoArgs, 41 RunE: commandApplyShardRoutingRules, 42 } 43 // GetShardRoutingRules makes a GetShardRoutingRules gRPC call to a vtctld. 44 GetShardRoutingRules = &cobra.Command{ 45 Use: "GetShardRoutingRules", 46 Short: "Displays the currently active shard routing rules as a JSON document.", 47 Long: `Displays the currently active shard routing rules as a JSON document. 48 49 See the documentation on shard level migrations[1] for more information. 50 51 [1]: https://vitess.io/docs/reference/vreplication/shardlevelmigrations/`, 52 DisableFlagsInUseLine: true, 53 Args: cobra.NoArgs, 54 RunE: commandGetShardRoutingRules, 55 } 56 ) 57 58 var applyShardRoutingRulesOptions = struct { 59 Rules string 60 RulesFilePath string 61 Cells []string 62 SkipRebuild bool 63 DryRun bool 64 }{} 65 66 func commandApplyShardRoutingRules(cmd *cobra.Command, args []string) error { 67 if applyShardRoutingRulesOptions.Rules != "" && applyShardRoutingRulesOptions.RulesFilePath != "" { 68 return fmt.Errorf("cannot pass both --rules (=%s) and --rules-file (=%s)", applyShardRoutingRulesOptions.Rules, applyShardRoutingRulesOptions.RulesFilePath) 69 } 70 71 if applyShardRoutingRulesOptions.Rules == "" && applyShardRoutingRulesOptions.RulesFilePath == "" { 72 return errors.New("must pass exactly one of --rules or --rules-file") 73 } 74 75 cli.FinishedParsing(cmd) 76 77 var rulesBytes []byte 78 if applyShardRoutingRulesOptions.RulesFilePath != "" { 79 data, err := os.ReadFile(applyShardRoutingRulesOptions.RulesFilePath) 80 if err != nil { 81 return err 82 } 83 84 rulesBytes = data 85 } else { 86 rulesBytes = []byte(applyShardRoutingRulesOptions.Rules) 87 } 88 89 srr := &vschemapb.ShardRoutingRules{} 90 if err := json2.Unmarshal(rulesBytes, &srr); err != nil { 91 return err 92 } 93 // Round-trip so when we display the result it's readable. 94 data, err := cli.MarshalJSON(srr) 95 if err != nil { 96 return err 97 } 98 99 if applyShardRoutingRulesOptions.DryRun { 100 fmt.Printf("[DRY RUN] Would have saved new ShardRoutingRules object:\n%s\n", data) 101 102 if applyRoutingRulesOptions.SkipRebuild { 103 fmt.Println("[DRY RUN] Would not have rebuilt VSchema graph, would have required operator to run RebuildVSchemaGraph for changes to take effect.") 104 } else { 105 fmt.Print("[DRY RUN] Would have rebuilt the VSchema graph") 106 if len(applyRoutingRulesOptions.Cells) == 0 { 107 fmt.Print(" in all cells\n") 108 } else { 109 fmt.Printf(" in the following cells: %s.\n", strings.Join(applyShardRoutingRulesOptions.Cells, ", ")) 110 } 111 } 112 113 return nil 114 } 115 116 _, err = client.ApplyShardRoutingRules(commandCtx, &vtctldatapb.ApplyShardRoutingRulesRequest{ 117 ShardRoutingRules: srr, 118 SkipRebuild: applyShardRoutingRulesOptions.SkipRebuild, 119 RebuildCells: applyShardRoutingRulesOptions.Cells, 120 }) 121 if err != nil { 122 return err 123 } 124 125 fmt.Printf("New ShardRoutingRules object:\n%s\nIf this is not what you expected, check the input data (as JSON parsing will skip unexpected fields).\n", data) 126 127 if applyRoutingRulesOptions.SkipRebuild { 128 fmt.Println("Skipping rebuild of VSchema graph as requested, you will need to run RebuildVSchemaGraph for the changes to take effect.") 129 } 130 131 return nil 132 } 133 134 func commandGetShardRoutingRules(cmd *cobra.Command, args []string) error { 135 cli.FinishedParsing(cmd) 136 137 resp, err := client.GetShardRoutingRules(commandCtx, &vtctldatapb.GetShardRoutingRulesRequest{}) 138 if err != nil { 139 return err 140 } 141 142 data, err := cli.MarshalJSON(resp.ShardRoutingRules) 143 if err != nil { 144 return err 145 } 146 147 fmt.Printf("%s\n", data) 148 149 return nil 150 } 151 152 func init() { 153 ApplyShardRoutingRules.Flags().StringVarP(&applyShardRoutingRulesOptions.Rules, "rules", "r", "", "Shard routing rules, specified as a string") 154 ApplyShardRoutingRules.Flags().StringVarP(&applyShardRoutingRulesOptions.RulesFilePath, "rules-file", "f", "", "Path to a file containing shard routing rules specified as JSON") 155 ApplyShardRoutingRules.Flags().StringSliceVarP(&applyShardRoutingRulesOptions.Cells, "cells", "c", nil, "Limit the VSchema graph rebuilding to the specified cells. Ignored if --skip-rebuild is specified.") 156 ApplyShardRoutingRules.Flags().BoolVar(&applyShardRoutingRulesOptions.SkipRebuild, "skip-rebuild", false, "Skip rebuilding the SrvVSchema objects.") 157 ApplyShardRoutingRules.Flags().BoolVarP(&applyShardRoutingRulesOptions.DryRun, "dry-run", "d", false, "Validate the specified shard routing rules and note actions that would be taken, but do not actually apply the rules to the topo.") 158 Root.AddCommand(ApplyShardRoutingRules) 159 160 Root.AddCommand(GetShardRoutingRules) 161 }