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  }