mirror of
https://gitee.com/milvus-io/milvus.git
synced 2025-12-07 01:28:27 +08:00
#44892 fix etcd request context contamination by RBAC auth info ``` When RBAC is enabled, Milvus uses the gRPC metadata library to inject RBAC authentication information into the request context (ctx). Since etcd’s authentication mechanism also relies on the same metadata library, if the same ctx is passed down to the etcd request, the RBAC auth info from Milvus contaminates the auth information used by etcd. This causes the etcd server to report an invalid auth token error when RBAC is enabled but etcd auth is disabled. ``` #43638 upgrade wp to v0.1.10 Signed-off-by: tinswzy <zhenyuan.wei@zilliz.com>
62 lines
1.8 KiB
Go
62 lines
1.8 KiB
Go
package etcdkv
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"path"
|
|
"time"
|
|
|
|
clientv3 "go.etcd.io/etcd/client/v3"
|
|
"google.golang.org/grpc/metadata"
|
|
|
|
"github.com/milvus-io/milvus/pkg/v2/kv/predicates"
|
|
"github.com/milvus-io/milvus/pkg/v2/util"
|
|
"github.com/milvus-io/milvus/pkg/v2/util/merr"
|
|
)
|
|
|
|
func parsePredicates(rootPath string, preds ...predicates.Predicate) ([]clientv3.Cmp, error) {
|
|
if len(preds) == 0 {
|
|
return []clientv3.Cmp{}, nil
|
|
}
|
|
result := make([]clientv3.Cmp, 0, len(preds))
|
|
for _, pred := range preds {
|
|
switch pred.Target() {
|
|
case predicates.PredTargetValue:
|
|
pt, err := parsePredicateType(pred.Type())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cmp := clientv3.Compare(clientv3.Value(path.Join(rootPath, pred.Key())), pt, pred.TargetValue())
|
|
result = append(result, cmp)
|
|
default:
|
|
return nil, merr.WrapErrParameterInvalid("valid predicate target", fmt.Sprintf("%d", pred.Target()))
|
|
}
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
// parsePredicateType parse predicates.PredicateType to clientv3.Result
|
|
func parsePredicateType(pt predicates.PredicateType) (string, error) {
|
|
switch pt {
|
|
case predicates.PredTypeEqual:
|
|
return "=", nil
|
|
default:
|
|
return "", merr.WrapErrParameterInvalid("valid predicate type", fmt.Sprintf("%d", pt))
|
|
}
|
|
}
|
|
|
|
// getContextWithTimeout returns a context with timeout
|
|
func getContextWithTimeout(ctx context.Context, timeoutDuration time.Duration) (context.Context, context.CancelFunc) {
|
|
// Use original ctx as base to preserve context values,
|
|
// but remove RBAC auth info to avoid auth contamination in etcd requests
|
|
newCtx := ctx
|
|
|
|
// Extract a metadata copy from incoming context and remove auth-related keys
|
|
if mdCopy, ok := metadata.FromIncomingContext(ctx); ok {
|
|
mdCopy.Delete(util.HeaderAuthorize)
|
|
mdCopy.Delete(util.HeaderToken)
|
|
newCtx = metadata.NewIncomingContext(ctx, mdCopy)
|
|
}
|
|
return context.WithTimeout(newCtx, timeoutDuration)
|
|
}
|