Skip to content

Commit

Permalink
Allow dynamic configuration of vschema acl (#17333)
Browse files Browse the repository at this point in the history
Signed-off-by: Dirkjan Bussink <[email protected]>
  • Loading branch information
dbussink authored Dec 10, 2024
1 parent 2c2b8a4 commit 0fe256e
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 86 deletions.
1 change: 1 addition & 0 deletions go/test/endtoend/cluster/vtgate_process.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ func (vtgate *VtgateProcess) Setup() (err error) {
return err
}
vtgate.proc.Stderr = errFile
vtgate.ErrorLog = errFile.Name()

vtgate.proc.Env = append(vtgate.proc.Env, os.Environ()...)
vtgate.proc.Env = append(vtgate.proc.Env, DefaultVttestEnv)
Expand Down
45 changes: 41 additions & 4 deletions go/test/endtoend/vtgate/vschema/vschema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,25 @@ package vschema

import (
"context"
"encoding/json"
"flag"
"fmt"
"os"
"path"
"testing"
"time"

"vitess.io/vitess/go/test/endtoend/utils"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"vitess.io/vitess/go/mysql"
"vitess.io/vitess/go/test/endtoend/cluster"
"vitess.io/vitess/go/test/endtoend/utils"
)

var (
clusterInstance *cluster.LocalProcessCluster
configFile string
vtParams mysql.ConnParams
hostname = "localhost"
keyspaceName = "ks"
Expand All @@ -53,7 +57,6 @@ var (
)

func TestMain(m *testing.M) {
defer cluster.PanicHandler(nil)
flag.Parse()

exitcode, err := func() (int, error) {
Expand All @@ -66,7 +69,21 @@ func TestMain(m *testing.M) {
}

// List of users authorized to execute vschema ddl operations
clusterInstance.VtGateExtraArgs = []string{"--vschema_ddl_authorized_users=%", "--schema_change_signal=false"}
if utils.BinaryIsAtLeastAtVersion(22, "vtgate") {
timeNow := time.Now().Unix()
configFile = path.Join(os.TempDir(), fmt.Sprintf("vtgate-config-%d.json", timeNow))
err := writeConfig(configFile, map[string]string{
"vschema_ddl_authorized_users": "%",
})
if err != nil {
return 1, err
}
defer os.Remove(configFile)

clusterInstance.VtGateExtraArgs = []string{fmt.Sprintf("--config-file=%s", configFile), "--schema_change_signal=false"}
} else {
clusterInstance.VtGateExtraArgs = []string{"--vschema_ddl_authorized_users=%", "--schema_change_signal=false"}
}

// Start keyspace
keyspace := &cluster.Keyspace{
Expand Down Expand Up @@ -96,6 +113,15 @@ func TestMain(m *testing.M) {

}

func writeConfig(path string, cfg map[string]string) error {
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
return json.NewEncoder(file).Encode(cfg)
}

func TestVSchema(t *testing.T) {
defer cluster.PanicHandler(t)
ctx := context.Background()
Expand Down Expand Up @@ -138,4 +164,15 @@ func TestVSchema(t *testing.T) {

utils.AssertMatches(t, conn, "delete from vt_user", `[]`)

if utils.BinaryIsAtLeastAtVersion(22, "vtgate") {
writeConfig(configFile, map[string]string{
"vschema_ddl_authorized_users": "",
})

require.EventuallyWithT(t, func(t *assert.CollectT) {
_, err = conn.ExecuteFetch("ALTER VSCHEMA DROP TABLE main", 1000, false)
assert.Error(t, err)
assert.ErrorContains(t, err, "is not authorized to perform vschema operations")
}, 5*time.Second, 100*time.Millisecond)
}
}
2 changes: 1 addition & 1 deletion go/viperutil/internal/sync/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (v *Viper) Set(key string, value any) {
v.m.Lock()
defer v.m.Unlock()

// We must not update v.disk here; explicit calls to Set will supercede all
// We must not update v.disk here; explicit calls to Set will supersede all
// future config reloads.
v.live.Set(key, value)

Expand Down
1 change: 0 additions & 1 deletion go/vt/vtgate/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ func NewExecutor(
// setting the vcursor config.
e.initVConfig(warnOnShardedOnly, pv)

vschemaacl.Init()
// we subscribe to update from the VSchemaManager
e.vm = &VSchemaManager{
subscriber: e.SaveVSchema,
Expand Down
12 changes: 6 additions & 6 deletions go/vt/vtgate/executor_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -401,21 +401,21 @@ func TestExecutorSetMetadata(t *testing.T) {
})

t.Run("Session 2", func(t *testing.T) {
vschemaacl.AuthorizedDDLUsers = "%"
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%"))
defer func() {
vschemaacl.AuthorizedDDLUsers = ""
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers(""))
}()

executor, _, _, _, ctx := createExecutorEnv(t)
session := econtext.NewSafeSession(&vtgatepb.Session{TargetString: "@primary", Autocommit: true})

set := "set @@vitess_metadata.app_keyspace_v1= '1'"
_, err := executor.Execute(ctx, nil, "TestExecute", session, set, nil)
assert.NoError(t, err, "%s error: %v", set, err)
require.NoError(t, err, "%s error: %v", set, err)

show := `show vitess_metadata variables like 'app\\_keyspace\\_v_'`
result, err := executor.Execute(ctx, nil, "TestExecute", session, show, nil)
assert.NoError(t, err)
require.NoError(t, err)

want := "1"
got := result.Rows[0][1].ToString()
Expand All @@ -424,11 +424,11 @@ func TestExecutorSetMetadata(t *testing.T) {
// Update metadata
set = "set @@vitess_metadata.app_keyspace_v2='2'"
_, err = executor.Execute(ctx, nil, "TestExecute", session, set, nil)
assert.NoError(t, err, "%s error: %v", set, err)
require.NoError(t, err, "%s error: %v", set, err)

show = `show vitess_metadata variables like 'app\\_keyspace\\_v%'`
gotqr, err := executor.Execute(ctx, nil, "TestExecute", session, show, nil)
assert.NoError(t, err)
require.NoError(t, err)

wantqr := &sqltypes.Result{
Fields: buildVarCharFields("Key", "Value"),
Expand Down
24 changes: 11 additions & 13 deletions go/vt/vtgate/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,9 +335,9 @@ func TestExecutorTransactionsAutoCommitStreaming(t *testing.T) {
}

func TestExecutorDeleteMetadata(t *testing.T) {
vschemaacl.AuthorizedDDLUsers = "%"
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%"))
defer func() {
vschemaacl.AuthorizedDDLUsers = ""
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers(""))
}()

executor, _, _, _, ctx := createExecutorEnv(t)
Expand Down Expand Up @@ -1318,9 +1318,9 @@ func TestExecutorDDLFk(t *testing.T) {
}

func TestExecutorAlterVSchemaKeyspace(t *testing.T) {
vschemaacl.AuthorizedDDLUsers = "%"
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%"))
defer func() {
vschemaacl.AuthorizedDDLUsers = ""
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers(""))
}()

executor, _, _, _, ctx := createExecutorEnv(t)
Expand All @@ -1347,9 +1347,9 @@ func TestExecutorAlterVSchemaKeyspace(t *testing.T) {
}

func TestExecutorCreateVindexDDL(t *testing.T) {
vschemaacl.AuthorizedDDLUsers = "%"
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%"))
defer func() {
vschemaacl.AuthorizedDDLUsers = ""
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers(""))
}()
executor, sbc1, sbc2, sbclookup, ctx := createExecutorEnv(t)
ks := "TestExecutor"
Expand Down Expand Up @@ -1417,9 +1417,9 @@ func TestExecutorCreateVindexDDL(t *testing.T) {
}

func TestExecutorAddDropVschemaTableDDL(t *testing.T) {
vschemaacl.AuthorizedDDLUsers = "%"
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%"))
defer func() {
vschemaacl.AuthorizedDDLUsers = ""
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers(""))
}()
executor, sbc1, sbc2, sbclookup, ctx := createExecutorEnv(t)
ks := KsTestUnsharded
Expand Down Expand Up @@ -1486,8 +1486,7 @@ func TestExecutorVindexDDLACL(t *testing.T) {
require.EqualError(t, err, `User 'blueUser' is not authorized to perform vschema operations`)

// test when all users are enabled
vschemaacl.AuthorizedDDLUsers = "%"
vschemaacl.Init()
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%"))
_, err = executor.Execute(ctxRedUser, nil, "TestExecute", session, stmt, nil)
if err != nil {
t.Errorf("unexpected error '%v'", err)
Expand All @@ -1499,8 +1498,7 @@ func TestExecutorVindexDDLACL(t *testing.T) {
}

// test when only one user is enabled
vschemaacl.AuthorizedDDLUsers = "orangeUser, blueUser, greenUser"
vschemaacl.Init()
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("orangeUser, blueUser, greenUser"))
_, err = executor.Execute(ctxRedUser, nil, "TestExecute", session, stmt, nil)
require.EqualError(t, err, `User 'redUser' is not authorized to perform vschema operations`)

Expand All @@ -1511,7 +1509,7 @@ func TestExecutorVindexDDLACL(t *testing.T) {
}

// restore the disallowed state
vschemaacl.AuthorizedDDLUsers = ""
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers(""))
}

func TestExecutorUnrecognized(t *testing.T) {
Expand Down
40 changes: 19 additions & 21 deletions go/vt/vtgate/executor_vschema_ddl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,9 @@ func waitForColVindexes(t *testing.T, ks, table string, names []string, executor
}

func TestPlanExecutorAlterVSchemaKeyspace(t *testing.T) {
vschemaacl.AuthorizedDDLUsers = "%"
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%"))
defer func() {
vschemaacl.AuthorizedDDLUsers = ""
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers(""))
}()
executor, _, _, _, ctx := createExecutorEnv(t)
session := econtext.NewSafeSession(&vtgatepb.Session{TargetString: "@primary", Autocommit: true})
Expand All @@ -163,9 +163,9 @@ func TestPlanExecutorAlterVSchemaKeyspace(t *testing.T) {
}

func TestPlanExecutorCreateVindexDDL(t *testing.T) {
vschemaacl.AuthorizedDDLUsers = "%"
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%"))
defer func() {
vschemaacl.AuthorizedDDLUsers = ""
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers(""))
}()
executor, _, _, _, ctx := createExecutorEnv(t)
ks := "TestExecutor"
Expand Down Expand Up @@ -205,9 +205,9 @@ func TestPlanExecutorCreateVindexDDL(t *testing.T) {
}

func TestPlanExecutorDropVindexDDL(t *testing.T) {
vschemaacl.AuthorizedDDLUsers = "%"
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%"))
defer func() {
vschemaacl.AuthorizedDDLUsers = ""
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers(""))
}()
executor, _, _, _, ctx := createExecutorEnv(t)
ks := "TestExecutor"
Expand Down Expand Up @@ -274,9 +274,9 @@ func TestPlanExecutorDropVindexDDL(t *testing.T) {
}

func TestPlanExecutorAddDropVschemaTableDDL(t *testing.T) {
vschemaacl.AuthorizedDDLUsers = "%"
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%"))
defer func() {
vschemaacl.AuthorizedDDLUsers = ""
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers(""))
}()
executor, sbc1, sbc2, sbclookup, ctx := createExecutorEnv(t)
ks := KsTestUnsharded
Expand Down Expand Up @@ -331,9 +331,9 @@ func TestPlanExecutorAddDropVschemaTableDDL(t *testing.T) {
}

func TestExecutorAddSequenceDDL(t *testing.T) {
vschemaacl.AuthorizedDDLUsers = "%"
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%"))
defer func() {
vschemaacl.AuthorizedDDLUsers = ""
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers(""))
}()
executor, _, _, _, ctx := createExecutorEnv(t)
ks := KsTestUnsharded
Expand Down Expand Up @@ -391,9 +391,9 @@ func TestExecutorAddSequenceDDL(t *testing.T) {
}

func TestExecutorDropSequenceDDL(t *testing.T) {
vschemaacl.AuthorizedDDLUsers = "%"
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%"))
defer func() {
vschemaacl.AuthorizedDDLUsers = ""
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers(""))
}()
executor, _, _, _, ctx := createExecutorEnv(t)
ks := KsTestUnsharded
Expand Down Expand Up @@ -442,9 +442,9 @@ func TestExecutorDropSequenceDDL(t *testing.T) {
}

func TestExecutorDropAutoIncDDL(t *testing.T) {
vschemaacl.AuthorizedDDLUsers = "%"
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%"))
defer func() {
vschemaacl.AuthorizedDDLUsers = ""
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers(""))
}()
executor, _, _, _, ctx := createExecutorEnv(t)
ks := KsTestUnsharded
Expand Down Expand Up @@ -484,9 +484,9 @@ func TestExecutorDropAutoIncDDL(t *testing.T) {
}

func TestExecutorAddDropVindexDDL(t *testing.T) {
vschemaacl.AuthorizedDDLUsers = "%"
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%"))
defer func() {
vschemaacl.AuthorizedDDLUsers = ""
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers(""))
}()
executor, sbc1, sbc2, sbclookup, ctx := createExecutorEnv(t)
ks := "TestExecutor"
Expand Down Expand Up @@ -747,8 +747,7 @@ func TestPlanExecutorVindexDDLACL(t *testing.T) {
require.EqualError(t, err, `User 'blueUser' is not authorized to perform vschema operations`)

// test when all users are enabled
vschemaacl.AuthorizedDDLUsers = "%"
vschemaacl.Init()
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("%"))
_, err = executor.Execute(ctxRedUser, nil, "TestExecute", session, stmt, nil)
if err != nil {
t.Errorf("unexpected error '%v'", err)
Expand All @@ -760,8 +759,7 @@ func TestPlanExecutorVindexDDLACL(t *testing.T) {
}

// test when only one user is enabled
vschemaacl.AuthorizedDDLUsers = "orangeUser, blueUser, greenUser"
vschemaacl.Init()
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers("orangeUser, blueUser, greenUser"))
_, err = executor.Execute(ctxRedUser, nil, "TestExecute", session, stmt, nil)
require.EqualError(t, err, `User 'redUser' is not authorized to perform vschema operations`)

Expand All @@ -772,5 +770,5 @@ func TestPlanExecutorVindexDDLACL(t *testing.T) {
}

// restore the disallowed state
vschemaacl.AuthorizedDDLUsers = ""
vschemaacl.AuthorizedDDLUsers.Set(vschemaacl.NewAuthorizedDDLUsers(""))
}
Loading

0 comments on commit 0fe256e

Please sign in to comment.