From e4b4a1599e668e4c22ce8dd9c894546e82d45dbb Mon Sep 17 00:00:00 2001 From: weilaaa <35529370+weilaaa@users.noreply.github.com> Date: Tue, 16 Jan 2024 14:59:45 +0800 Subject: [PATCH] fix user name as label over length (#365) fix user name as label over length --- pkg/ctrlmgr/controllers/binding/common.go | 3 ++- pkg/utils/hash/hash.go | 8 +++++++ .../localmgr/controllers/user/helper.go | 10 ++++++++ .../controllers/user/user_controller.go | 23 +++++++------------ 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/pkg/ctrlmgr/controllers/binding/common.go b/pkg/ctrlmgr/controllers/binding/common.go index 6d2117df2..d92d88219 100644 --- a/pkg/ctrlmgr/controllers/binding/common.go +++ b/pkg/ctrlmgr/controllers/binding/common.go @@ -22,6 +22,7 @@ import ( "strings" "github.com/kubecube-io/kubecube/pkg/utils/constants" + "github.com/kubecube-io/kubecube/pkg/utils/hash" rbacv1 "k8s.io/api/rbac/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/util/retry" @@ -125,7 +126,7 @@ func setBindingUserLabel(labels map[string]string, user string) map[string]strin labels = make(map[string]string) } - labels[constants.LabelRelationship] = user + labels[constants.LabelRelationship] = hash.GenerateUserHash(user) return labels } diff --git a/pkg/utils/hash/hash.go b/pkg/utils/hash/hash.go index afe1ac87d..83074fe7c 100644 --- a/pkg/utils/hash/hash.go +++ b/pkg/utils/hash/hash.go @@ -46,3 +46,11 @@ func GenerateBindingName(user, role, namespace string) string { DeepHashObject(hasher, bindingName) return fmt.Sprintf("%s-%s", user, rand.SafeEncodeString(fmt.Sprint(hasher.Sum32()))) } + +// GenerateUserHash generates fixed length hash for hexed user to +// prevent hexed username as label over length. +func GenerateUserHash(user string) string { + hasher := fnv.New32a() + DeepHashObject(hasher, user) + return rand.SafeEncodeString(fmt.Sprint(hasher.Sum32())) +} diff --git a/pkg/warden/localmgr/controllers/user/helper.go b/pkg/warden/localmgr/controllers/user/helper.go index ae88aa4b1..83847e1d2 100644 --- a/pkg/warden/localmgr/controllers/user/helper.go +++ b/pkg/warden/localmgr/controllers/user/helper.go @@ -25,6 +25,7 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/util/retry" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) func updateUserStatus(ctx context.Context, cli client.Client, user *v1.User) error { @@ -48,6 +49,15 @@ func updateUserStatus(ctx context.Context, cli client.Client, user *v1.User) err }) } +func createObjOrUpdateObjLabels(ctx context.Context, cli client.Client, obj client.Object) error { + labels := obj.GetLabels() + _, err := controllerutil.CreateOrUpdate(ctx, cli, obj, func() error { + obj.SetLabels(labels) + return nil + }) + return err +} + func updateUserStatusErrStr(user string, err error) string { return fmt.Sprintf("update user %v status failed: %v", user, err) } diff --git a/pkg/warden/localmgr/controllers/user/user_controller.go b/pkg/warden/localmgr/controllers/user/user_controller.go index 199ad26e9..201440188 100644 --- a/pkg/warden/localmgr/controllers/user/user_controller.go +++ b/pkg/warden/localmgr/controllers/user/user_controller.go @@ -137,7 +137,7 @@ func (r *UserReconciler) refreshStatus(ctx context.Context, user *userv1.User) e } func (r *UserReconciler) cleanOrphanBindings(ctx context.Context, user *userv1.User) error { - ls, err := labels.Parse(fmt.Sprintf("%v=%v", constants.LabelRelationship, user.Name)) + ls, err := labels.Parse(fmt.Sprintf("%v=%v", constants.LabelRelationship, hash.GenerateUserHash(user.Name))) if err != nil { return err } @@ -243,7 +243,7 @@ func (r *UserReconciler) generateClusterRoleBinding(ctx context.Context, user st ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ constants.RbacLabel: constants.TrueStr, - constants.LabelRelationship: user, + constants.LabelRelationship: hash.GenerateUserHash(user), constants.PlatformLabel: constants.ClusterRolePlatform, }, }, @@ -267,7 +267,7 @@ func (r *UserReconciler) generateClusterRoleBinding(ctx context.Context, user st clusterRoleBinding.Name = "gen-" + hash.GenerateBindingName(user, clusterRoleBinding.RoleRef.Name, "") - return ignoreAlreadyExistErr(r.Create(ctx, clusterRoleBinding)) + return createObjOrUpdateObjLabels(ctx, r.Client, clusterRoleBinding) } // refreshNsBinding refresh the RoleBinding of tenant or project under current cluster. @@ -279,7 +279,7 @@ func (r *UserReconciler) refreshNsBinding(ctx context.Context, user string, bind lb := map[string]string{ constants.RbacLabel: constants.TrueStr, - constants.LabelRelationship: user, + constants.LabelRelationship: hash.GenerateUserHash(user), } if binding.ScopeType == userv1.TenantScope { @@ -312,7 +312,7 @@ func (r *UserReconciler) refreshNsBinding(ctx context.Context, user string, bind }, }, } - errs = append(errs, ignoreAlreadyExistErr(r.Create(ctx, b))) + errs = append(errs, createObjOrUpdateObjLabels(ctx, r.Client, b)) } if len(errs) > 0 { // any error occurs when refreshing bindings will do retry @@ -329,7 +329,7 @@ func (r *UserReconciler) refreshPlatformBinding(ctx context.Context, user string Name: hash.GenerateBindingName(user, binding.Role, ""), Labels: map[string]string{ constants.RbacLabel: constants.TrueStr, - constants.LabelRelationship: user, + constants.LabelRelationship: hash.GenerateUserHash(user), constants.PlatformLabel: constants.ClusterRolePlatform, }, // we do not need warden sync here, every warden should process user event in self cluster @@ -348,12 +348,12 @@ func (r *UserReconciler) refreshPlatformBinding(ctx context.Context, user string }, } - return ignoreAlreadyExistErr(r.Create(ctx, b)) + return createObjOrUpdateObjLabels(ctx, r.Client, b) } // bindingsGc clean up RoleBindings or ClusterRoleBindings which are under scope bindings. func (r *UserReconciler) bindingsGc(ctx context.Context, user string) error { - ls, err := labels.Parse(fmt.Sprintf("%v=%v", constants.LabelRelationship, user)) + ls, err := labels.Parse(fmt.Sprintf("%v=%v", constants.LabelRelationship, hash.GenerateUserHash(user))) if err != nil { return err } @@ -462,13 +462,6 @@ func (r *UserReconciler) removeFinalizer(ctx context.Context, user *userv1.User) return nil } -func ignoreAlreadyExistErr(err error) error { - if errors.IsAlreadyExists(err) { - return nil - } - return err -} - // SetupWithManager sets up the controller with the Manager. func SetupWithManager(mgr ctrl.Manager, _ *options.Options) error { r, err := newReconciler(mgr)