Skip to content

Commit

Permalink
Minor tweaks
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Lord <mattalord@gmail.com>
  • Loading branch information
mattlord committed Sep 12, 2024
1 parent fee35f2 commit 815493f
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 24 deletions.
7 changes: 7 additions & 0 deletions go/vt/vtctl/workflow/framework_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,13 @@ func (tmc *testTMClient) UpdateVReplicationWorkflow(ctx context.Context, tablet
}, nil
}

func (tmc *testTMClient) ValidateVReplicationPermissions(ctx context.Context, tablet *topodatapb.Tablet, req *tabletmanagerdatapb.ValidateVReplicationPermissionsRequest) (*tabletmanagerdatapb.ValidateVReplicationPermissionsResponse, error) {
return &tabletmanagerdatapb.ValidateVReplicationPermissionsResponse{
User: "vt_filtered",
Ok: true,
}, nil
}

func (tmc *testTMClient) setPrimaryPosition(tablet *topodatapb.Tablet, position string) {
tmc.mu.Lock()
defer tmc.mu.Unlock()
Expand Down
32 changes: 15 additions & 17 deletions go/vt/vtctl/workflow/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -666,23 +666,21 @@ func areTabletsAvailableToStreamFrom(ctx context.Context, req *vtctldatapb.Workf
allErrors.RecordError(fmt.Errorf("no tablet found to source data in keyspace %s, shard %s", keyspace, shard.ShardName()))
return
}
if req.GetEnableReverseReplication() {
// Ensure the tablet has the minimum privileges required on the sidecar database
// table in order to manage the reverse workflow as part of the traffic switch.
for _, tablet := range tablets {
wg.Add(1)
go func() {
defer wg.Done()
res, err := ts.ws.tmc.ValidateVReplicationPermissions(ctx, tablet.Tablet, nil)
if err != nil {
allErrors.RecordError(vterrors.Wrapf(err, "failed to validate required vreplication metadata permissions on tablet %s", topoproto.TabletAliasString(tablet.Alias)))
}
if !res.GetOk() {
allErrors.RecordError(fmt.Errorf("user %s does not have the required set of permissions (insert,update,delete) on the %s.vreplication table on tablet %s",
res.GetUser(), sidecar.GetIdentifier(), topoproto.TabletAliasString(tablet.Alias)))
}
}()
}
// Ensure the tablet has the minimum privileges required on the sidecar database
// table in order to manage the reverse workflow as part of the traffic switch.
for _, tablet := range tablets {
wg.Add(1)
go func() {
defer wg.Done()
res, err := ts.ws.tmc.ValidateVReplicationPermissions(ctx, tablet.Tablet, nil)
if err != nil {
allErrors.RecordError(vterrors.Wrapf(err, "failed to validate required vreplication metadata permissions on tablet %s", topoproto.TabletAliasString(tablet.Alias)))
}
if !res.GetOk() {
allErrors.RecordError(fmt.Errorf("user %s does not have the required set of permissions (insert,update,delete) on the %s.vreplication table on tablet %s",
res.GetUser(), sidecar.GetIdentifier(), topoproto.TabletAliasString(tablet.Alias)))
}
}()
}
}(cells, keyspace, shard)
}
Expand Down
17 changes: 10 additions & 7 deletions go/vt/vttablet/tabletmanager/rpc_vreplication.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,22 @@ const (
// Check if workflow is still copying.
sqlGetVReplicationCopyStatus = "select distinct vrepl_id from %s.copy_state where vrepl_id = %d"
// Validate the minimum set of permissions needed to manage vreplication metadata.
// This is a simple check for a matching user rather than any specific user@host
// combination.
sqlValidateVReplicationPermissions = `
select if(count(*)>0, 1, 0) as good from mysql.user as u
left join mysql.db as d on (u.user = d.user)
left join mysql.tables_priv as t on (u.user = t.user)
where u.user = %a
and (
(u.insert_priv = 'y' and u.update_priv = 'y' and u.delete_priv = 'y')
or (d.db = %a and u.insert_priv = 'y' and u.update_priv = 'y' and u.delete_priv = 'y')
or (t.db = %a and t.table_name = 'vreplication'
(u.insert_priv = 'y' and u.update_priv = 'y' and u.delete_priv = 'y') /* user has global privs */
or (d.db = %a and u.insert_priv = 'y' and u.update_priv = 'y' and u.delete_priv = 'y') /* user has db privs */
or (t.db = %a and t.table_name = 'vreplication' /* user has table privs */
and find_in_set('insert', t.table_priv)
and find_in_set('update', t.table_priv)
and find_in_set('delete', t.table_priv)
)
)
) limit 1
`
)

Expand Down Expand Up @@ -549,7 +551,7 @@ func (tm *TabletManager) UpdateVReplicationWorkflows(ctx context.Context, req *t

// ValidateVReplicationPermissions validates that the --db_filtered_user has
// the minimum permissions required on the sidecardb vreplication table
// needed in order to manager vreplication metadata.
// needed in order to manage vreplication metadata.
func (tm *TabletManager) ValidateVReplicationPermissions(ctx context.Context, req *tabletmanagerdatapb.ValidateVReplicationPermissionsRequest) (*tabletmanagerdatapb.ValidateVReplicationPermissionsResponse, error) {
query, err := sqlparser.ParseAndBind(sqlValidateVReplicationPermissions,
sqltypes.StringBindVariable(tm.DBConfigs.Filtered.User),
Expand All @@ -573,8 +575,9 @@ func (tm *TabletManager) ValidateVReplicationPermissions(ctx context.Context, re
query, qr)
}
val, err := qr.Rows[0][0].ToBool()
if err != nil {
return nil, err
if err != nil { // Should never happen
return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unexpected result for query %s: expected boolean-like value, got: %q",
query, qr.Rows[0][0].ToString())
}
return &tabletmanagerdatapb.ValidateVReplicationPermissionsResponse{
User: tm.DBConfigs.Filtered.User,
Expand Down

0 comments on commit 815493f

Please sign in to comment.