Skip to content

Commit

Permalink
enhance: [2.4] support to drop the role which is related the privileg…
Browse files Browse the repository at this point in the history
…e list (milvus-io#35863)

- issue: milvus-io#35545
- pr: milvus-io#35727

Signed-off-by: SimFG <[email protected]>
  • Loading branch information
SimFG authored Aug 31, 2024
1 parent 5698d18 commit 8b70612
Show file tree
Hide file tree
Showing 13 changed files with 79 additions and 213 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,4 @@ internal/proto/**/*.pb.go
internal/core/src/pb/*.pb.h
internal/core/src/pb/*.pb.cc
**/legacypb/*.pb.go
*.pb.go
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ require (
github.com/go-playground/validator/v10 v10.14.0
github.com/gofrs/flock v0.8.1
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/protobuf v1.5.4
github.com/google/btree v1.1.2
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/klauspost/compress v1.17.7
Expand Down
7 changes: 4 additions & 3 deletions internal/datanode/compaction/mix_compactor.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import (
"time"

"github.com/cockroachdb/errors"
"github.com/samber/lo"
"go.opentelemetry.io/otel"
"go.uber.org/zap"

"github.com/milvus-io/milvus/internal/datanode/allocator"
"github.com/milvus-io/milvus/internal/datanode/io"
"github.com/milvus-io/milvus/internal/proto/datapb"
Expand All @@ -35,9 +39,6 @@ import (
"github.com/milvus-io/milvus/pkg/util/timerecord"
"github.com/milvus-io/milvus/pkg/util/tsoutil"
"github.com/milvus-io/milvus/pkg/util/typeutil"
"github.com/samber/lo"
"go.opentelemetry.io/otel"
"go.uber.org/zap"
)

type mixCompactionTask struct {
Expand Down
2 changes: 1 addition & 1 deletion internal/datanode/compaction/segment_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"context"
"math"

"github.com/samber/lo"
"go.uber.org/atomic"
"go.uber.org/zap"

Expand All @@ -21,7 +22,6 @@ import (
"github.com/milvus-io/milvus/pkg/log"
"github.com/milvus-io/milvus/pkg/util/paramtable"
"github.com/milvus-io/milvus/pkg/util/typeutil"
"github.com/samber/lo"
)

// Not concurrent safe.
Expand Down
20 changes: 17 additions & 3 deletions internal/metastore/kv/rootcoord/kv_catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -1167,11 +1167,25 @@ func (kc *Catalog) ListGrant(ctx context.Context, tenant string, entity *milvusp

func (kc *Catalog) DeleteGrant(ctx context.Context, tenant string, role *milvuspb.RoleEntity) error {
var (
k = funcutil.HandleTenantForEtcdKey(GranteePrefix, tenant, role.Name+"/")
err error
k = funcutil.HandleTenantForEtcdKey(GranteePrefix, tenant, role.Name+"/")
err error
removeKeys []string
)

if err = kc.Txn.RemoveWithPrefix(k); err != nil {
removeKeys = append(removeKeys, k)

// the values are the grantee id list
_, values, err := kc.Txn.LoadWithPrefix(k)
if err != nil {
log.Warn("fail to load grant privilege entities", zap.String("key", k), zap.Error(err))
return err
}
for _, v := range values {
granteeIDKey := funcutil.HandleTenantForEtcdKey(GranteeIDPrefix, tenant, v+"/")
removeKeys = append(removeKeys, granteeIDKey)
}

if err = kc.Txn.MultiSaveAndRemoveWithPrefix(nil, removeKeys); err != nil {
log.Error("fail to remove with the prefix", zap.String("key", k), zap.Error(err))
}
return err
Expand Down
15 changes: 11 additions & 4 deletions internal/metastore/kv/rootcoord/kv_catalog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2311,12 +2311,18 @@ func TestRBAC_Grant(t *testing.T) {
kvmock = mocks.NewTxnKV(t)
c = &Catalog{Txn: kvmock}

errorRole = "error-role"
errorRolePrefix = funcutil.HandleTenantForEtcdKey(GranteePrefix, tenant, errorRole+"/")
errorRole = "error-role"
errorRolePrefix = funcutil.HandleTenantForEtcdKey(GranteePrefix, tenant, errorRole+"/")
loadErrorRole = "load-error-role"
loadErrorRolePrefix = funcutil.HandleTenantForEtcdKey(GranteePrefix, tenant, loadErrorRole+"/")
granteeID = "123456"
granteePrefix = funcutil.HandleTenantForEtcdKey(GranteeIDPrefix, tenant, granteeID+"/")
)

kvmock.EXPECT().RemoveWithPrefix(errorRolePrefix).Call.Return(errors.New("mock removeWithPrefix error"))
kvmock.EXPECT().RemoveWithPrefix(mock.Anything).Call.Return(nil)
kvmock.EXPECT().LoadWithPrefix(loadErrorRolePrefix).Call.Return(nil, nil, errors.New("mock loadWithPrefix error"))
kvmock.EXPECT().LoadWithPrefix(mock.Anything).Call.Return(nil, []string{granteeID}, nil)
kvmock.EXPECT().MultiSaveAndRemoveWithPrefix(mock.Anything, []string{errorRolePrefix, granteePrefix}, mock.Anything).Call.Return(errors.New("mock removeWithPrefix error"))
kvmock.EXPECT().MultiSaveAndRemoveWithPrefix(mock.Anything, mock.Anything, mock.Anything).Call.Return(nil)

tests := []struct {
isValid bool
Expand All @@ -2326,6 +2332,7 @@ func TestRBAC_Grant(t *testing.T) {
}{
{true, "role1", "valid role1"},
{false, errorRole, "invalid errorRole"},
{false, loadErrorRole, "invalid load errorRole"},
}

for _, test := range tests {
Expand Down
6 changes: 6 additions & 0 deletions internal/proxy/meta_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,12 @@ func (m *MetaCache) RefreshPolicyInfo(op typeutil.CacheOp) (err error) {
for user := range m.userToRoles {
delete(m.userToRoles[user], op.OpKey)
}

for policy := range m.privilegeInfos {
if funcutil.PolicyCheckerWithRole(policy, op.OpKey) {
delete(m.privilegeInfos, policy)
}
}
case typeutil.CacheRefresh:
resp, err := m.rootCoord.ListPolicy(context.Background(), &internalpb.ListPolicyRequest{})
if err != nil {
Expand Down
10 changes: 7 additions & 3 deletions internal/proxy/meta_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -691,9 +691,13 @@ func TestMetaCache_PolicyInfo(t *testing.T) {
t.Run("Delete user or drop role", func(t *testing.T) {
client.listPolicy = func(ctx context.Context, in *internalpb.ListPolicyRequest) (*internalpb.ListPolicyResponse, error) {
return &internalpb.ListPolicyResponse{
Status: merr.Success(),
PolicyInfos: []string{"policy1", "policy2", "policy3"},
UserRoles: []string{funcutil.EncodeUserRoleCache("foo", "role1"), funcutil.EncodeUserRoleCache("foo", "role2"), funcutil.EncodeUserRoleCache("foo2", "role2"), funcutil.EncodeUserRoleCache("foo2", "role3")},
Status: merr.Success(),
PolicyInfos: []string{
funcutil.PolicyForPrivilege("role2", "Collection", "collection1", "read", "default"),
"policy2",
"policy3",
},
UserRoles: []string{funcutil.EncodeUserRoleCache("foo", "role1"), funcutil.EncodeUserRoleCache("foo", "role2"), funcutil.EncodeUserRoleCache("foo2", "role2"), funcutil.EncodeUserRoleCache("foo2", "role3")},
}, nil
}
err := InitMetaCache(context.Background(), client, qc, mgr)
Expand Down
28 changes: 20 additions & 8 deletions internal/rootcoord/root_coord.go
Original file line number Diff line number Diff line change
Expand Up @@ -2235,13 +2235,15 @@ func (c *Core) DropRole(ctx context.Context, in *milvuspb.DropRoleRequest) (*com
return merr.StatusWithErrorCode(errors.New(errMsg), commonpb.ErrorCode_DropRoleFailure), nil
}

grantEntities, err := c.meta.SelectGrant(util.DefaultTenant, &milvuspb.GrantEntity{
Role: &milvuspb.RoleEntity{Name: in.RoleName},
})
if len(grantEntities) != 0 {
errMsg := "fail to drop the role that it has privileges. Use REVOKE API to revoke privileges"
ctxLog.Warn(errMsg, zap.Any("grants", grantEntities), zap.Error(err))
return merr.StatusWithErrorCode(errors.New(errMsg), commonpb.ErrorCode_DropRoleFailure), nil
if !in.ForceDrop {
grantEntities, err := c.meta.SelectGrant(util.DefaultTenant, &milvuspb.GrantEntity{
Role: &milvuspb.RoleEntity{Name: in.RoleName},
})
if len(grantEntities) != 0 {
errMsg := "fail to drop the role that it has privileges. Use REVOKE API to revoke privileges"
ctxLog.Warn(errMsg, zap.Any("grants", grantEntities), zap.Error(err))
return merr.StatusWithErrorCode(errors.New(errMsg), commonpb.ErrorCode_DropRoleFailure), nil
}
}
redoTask := newBaseRedoTask(c.stepExecutor)
redoTask.AddSyncStep(NewSimpleStep("drop role meta data", func(ctx context.Context) ([]nestedStep, error) {
Expand All @@ -2251,6 +2253,16 @@ func (c *Core) DropRole(ctx context.Context, in *milvuspb.DropRoleRequest) (*com
}
return nil, err
}))
redoTask.AddAsyncStep(NewSimpleStep("drop the privilege list of this role", func(ctx context.Context) ([]nestedStep, error) {
if !in.ForceDrop {
return nil, nil
}
err := c.meta.DropGrant(util.DefaultTenant, &milvuspb.RoleEntity{Name: in.RoleName})
if err != nil {
ctxLog.Warn("drop the privilege list failed for the role", zap.Error(err))
}
return nil, err
}))
redoTask.AddAsyncStep(NewSimpleStep("drop role cache", func(ctx context.Context) ([]nestedStep, error) {
err := c.proxyClientManager.RefreshPolicyInfoCache(ctx, &proxypb.RefreshPolicyInfoCacheRequest{
OpType: int32(typeutil.CacheDropRole),
Expand All @@ -2261,7 +2273,7 @@ func (c *Core) DropRole(ctx context.Context, in *milvuspb.DropRoleRequest) (*com
}
return nil, err
}))
err = redoTask.Execute(ctx)
err := redoTask.Execute(ctx)
if err != nil {
errMsg := "fail to execute task when dropping the role"
ctxLog.Warn(errMsg, zap.Error(err))
Expand Down
177 changes: 0 additions & 177 deletions pkg/streaming/walimpls/impls/pulsar/message_id_data.pb.go

This file was deleted.

13 changes: 0 additions & 13 deletions pkg/streaming/walimpls/impls/pulsar/message_id_data.proto

This file was deleted.

4 changes: 4 additions & 0 deletions pkg/util/funcutil/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,3 +132,7 @@ func SplitObjectName(objectName string) (string, string) {
names := strings.Split(objectName, ".")
return names[0], names[1]
}

func PolicyCheckerWithRole(policy, roleName string) bool {
return strings.Contains(policy, fmt.Sprintf(`"V0":"%s"`, roleName))
}
Loading

0 comments on commit 8b70612

Please sign in to comment.