Skip to content

Commit

Permalink
VReplication: Validate min set of user permissions in traffic switch …
Browse files Browse the repository at this point in the history
…prechecks (#16762)

Signed-off-by: Matt Lord <[email protected]>
  • Loading branch information
mattlord authored Sep 24, 2024
1 parent 83b37b8 commit 9e7a63a
Show file tree
Hide file tree
Showing 20 changed files with 2,273 additions and 972 deletions.
60 changes: 60 additions & 0 deletions go/test/endtoend/vreplication/vreplication_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"fmt"
"io"
"maps"
"net/http"
"runtime"
"strconv"
Expand Down Expand Up @@ -797,6 +798,11 @@ func shardCustomer(t *testing.T, testReverse bool, cells []*Cell, sourceCellOrAl
commit, _ = vc.startQuery(t, openTxQuery)
}
switchWritesDryRun(t, workflowType, ksWorkflow, dryRunResultsSwitchWritesCustomerShard)
shardNames := make([]string, 0, len(vc.Cells[defaultCell.Name].Keyspaces[sourceKs].Shards))
for shardName := range maps.Keys(vc.Cells[defaultCell.Name].Keyspaces[sourceKs].Shards) {
shardNames = append(shardNames, shardName)
}
testSwitchTrafficPermissionChecks(t, workflowType, sourceKs, shardNames, targetKs, workflow)
switchWrites(t, workflowType, ksWorkflow, false)

checkThatVDiffFails(t, targetKs, workflow)
Expand Down Expand Up @@ -1589,6 +1595,60 @@ func switchWritesDryRun(t *testing.T, workflowType, ksWorkflow string, dryRunRes
validateDryRunResults(t, output, dryRunResults)
}

// testSwitchTrafficPermissionsChecks confirms that for the SwitchTraffic command, the
// necessary permissions are checked properly on the source keyspace's primary tablets.
// This ensures that we can create and manage the reverse vreplication workflow.
func testSwitchTrafficPermissionChecks(t *testing.T, workflowType, sourceKeyspace string, sourceShards []string, targetKeyspace, workflow string) {
applyPrivileges := func(query string) {
for _, shard := range sourceShards {
primary := vc.getPrimaryTablet(t, sourceKeyspace, shard)
_, err := primary.QueryTablet(query, primary.Keyspace, false)
require.NoError(t, err)
}
}
runDryRunCmd := func(expectErr bool) {
_, err := vc.VtctldClient.ExecuteCommandWithOutput(workflowType, "--workflow", workflow, "--target-keyspace", targetKeyspace,
"SwitchTraffic", "--tablet-types=primary", "--dry-run")
require.True(t, ((err != nil) == expectErr), "expected error: %t, got: %v", expectErr, err)
}

defer func() {
// Put the default global privs back in place.
applyPrivileges("grant select,insert,update,delete on *.* to vt_filtered@localhost")
}()

t.Run("test switch traffic permission checks", func(t *testing.T) {
t.Run("test without global privileges", func(t *testing.T) {
applyPrivileges("revoke select,insert,update,delete on *.* from vt_filtered@localhost")
runDryRunCmd(true)
})

t.Run("test with db level privileges", func(t *testing.T) {
applyPrivileges(fmt.Sprintf("grant select,insert,update,delete on %s.* to vt_filtered@localhost",
sidecarDBIdentifier))
runDryRunCmd(false)
})

t.Run("test without global or db level privileges", func(t *testing.T) {
applyPrivileges(fmt.Sprintf("revoke select,insert,update,delete on %s.* from vt_filtered@localhost",
sidecarDBIdentifier))
runDryRunCmd(true)
})

t.Run("test with table level privileges", func(t *testing.T) {
applyPrivileges(fmt.Sprintf("grant select,insert,update,delete on %s.vreplication to vt_filtered@localhost",
sidecarDBIdentifier))
runDryRunCmd(false)
})

t.Run("test without global, db, or table level privileges", func(t *testing.T) {
applyPrivileges(fmt.Sprintf("revoke select,insert,update,delete on %s.vreplication from vt_filtered@localhost",
sidecarDBIdentifier))
runDryRunCmd(true)
})
})
}

// restartWorkflow confirms that a workflow can be successfully
// stopped and started.
func restartWorkflow(t *testing.T, ksWorkflow string) {
Expand Down
Loading

0 comments on commit 9e7a63a

Please sign in to comment.