diff --git a/go/cmd/vtctldclient/command/permissions.go b/go/cmd/vtctldclient/command/permissions.go new file mode 100644 index 00000000000..25f0357582e --- /dev/null +++ b/go/cmd/vtctldclient/command/permissions.go @@ -0,0 +1,123 @@ +/* +Copyright 2025 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package command + +import ( + "fmt" + + "github.com/spf13/cobra" + + "vitess.io/vitess/go/cmd/vtctldclient/cli" + "vitess.io/vitess/go/vt/topo/topoproto" + + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" +) + +var ( + // GetPermissions makes a GetPermissions gRPC call to a vtctld. + GetPermissions = &cobra.Command{ + Use: "GetPermissions ", + Short: "Displays the permissions for a tablet.", + DisableFlagsInUseLine: true, + Args: cobra.ExactArgs(1), + RunE: commandGetPermissions, + } + // ValidatePermissionsShard makes a ValidatePermissionsKeyspace gRPC call to a + // vtctld with the specified shard to examine in the keyspace. + ValidatePermissionsShard = &cobra.Command{ + Use: "ValidatePermissionsShard ", + Short: "Validates that the permissions on the primary match all of the replicas.", + DisableFlagsInUseLine: true, + Args: cobra.ExactArgs(1), + RunE: commandValidatePermissionsShard, + } + // ValidatePermissionsKeyspace makes a ValidatePermissionsKeyspace gRPC call to a + // vtctld. + ValidatePermissionsKeyspace = &cobra.Command{ + Use: "ValidatePermissionsKeyspace ", + Short: "Validates that the permissions on the primary of the first shard match those of all of the other tablets in the keyspace.", + DisableFlagsInUseLine: true, + Args: cobra.ExactArgs(1), + RunE: commandValidatePermissionsKeyspace, + } +) + +func commandGetPermissions(cmd *cobra.Command, args []string) error { + alias, err := topoproto.ParseTabletAlias(cmd.Flags().Arg(0)) + if err != nil { + return err + } + + cli.FinishedParsing(cmd) + + resp, err := client.GetPermissions(commandCtx, &vtctldatapb.GetPermissionsRequest{ + TabletAlias: alias, + }) + if err != nil { + return err + } + // Obfuscate the checksum so as not to potentially display sensitive info. + if resp != nil && resp.Permissions != nil { + for _, up := range resp.Permissions.UserPermissions { + if up != nil { + up.PasswordChecksum = 0 + } + } + } + cli.DefaultMarshalOptions.EmitUnpopulated = false + p, err := cli.MarshalJSON(resp.Permissions) + if err != nil { + return err + } + fmt.Printf("%s\n", p) + + return nil +} + +func commandValidatePermissionsKeyspace(cmd *cobra.Command, args []string) error { + keyspace := cmd.Flags().Arg(0) + + cli.FinishedParsing(cmd) + + _, err := client.ValidatePermissionsKeyspace(commandCtx, &vtctldatapb.ValidatePermissionsKeyspaceRequest{ + Keyspace: keyspace, + }) + + return err +} + +func commandValidatePermissionsShard(cmd *cobra.Command, args []string) error { + keyspace, shard, err := topoproto.ParseKeyspaceShard(cmd.Flags().Arg(0)) + if err != nil { + return err + } + + cli.FinishedParsing(cmd) + + _, err = client.ValidatePermissionsKeyspace(commandCtx, &vtctldatapb.ValidatePermissionsKeyspaceRequest{ + Keyspace: keyspace, + Shards: []string{shard}, + }) + + return err +} + +func init() { + Root.AddCommand(GetPermissions) + Root.AddCommand(ValidatePermissionsKeyspace) + Root.AddCommand(ValidatePermissionsShard) +}