Skip to content

Commit

Permalink
Fix ClusterRoleBinding subject growth
Browse files Browse the repository at this point in the history
Fixed an issue where failing to include APIGroup on the subjects caused the reconcile helpers to think the subject needed to be re-added every time RKE2 starts up.

Signed-off-by: Brad Davidson <[email protected]>
  • Loading branch information
brandond committed Jul 9, 2024
1 parent 61cebda commit af73b78
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
35 changes: 35 additions & 0 deletions pkg/rke2/clusterrole.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ package rke2

import (
"context"
"encoding/json"
"sync"

"github.com/k3s-io/k3s/pkg/cli/cmds"
"github.com/sirupsen/logrus"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
genericapiserver "k8s.io/apiserver/pkg/server"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
rbacrest "k8s.io/kubernetes/pkg/registry/rbac/rest"
)
Expand All @@ -21,6 +26,10 @@ func setClusterRoles() cmds.StartupHook {
logrus.Info("Applying Cluster Role Bindings")

config, err := clientcmd.BuildConfigFromFlags("", args.KubeConfigSupervisor)
if err != nil {
logrus.Fatalf("clusterrole: new k8s restConfig: %v", err)
}
client, err := kubernetes.NewForConfig(config)
if err != nil {
logrus.Fatalf("clusterrole: new k8s client: %v", err)
}
Expand All @@ -45,6 +54,32 @@ func setClusterRoles() cmds.StartupHook {
logrus.Fatalf("clusterrole: EnsureRBACPolicy failed: %v", err)
}

// Begin remediation for https://github.com/rancher/rke2/issues/6272
// This can be removed after ~1 year of shipping releases not affected by this issue.

// stub binding/clusterrolebinding for marshalling the patch json
type binding struct {
Subjects []rbacv1.Subject `json:"subjects"`
}

// It is not critical if these fail, the excess subjects just need to be cleaned up eventually
for ns, rbs := range policy.RoleBindings {
for _, rb := range rbs {
b, _ := json.Marshal(binding{Subjects: rb.Subjects})
if _, err := client.RbacV1().RoleBindings(ns).Patch(ctx, rb.Name, types.MergePatchType, b, metav1.PatchOptions{}); err != nil {
logrus.Debugf("Failed to patch RoleBinding %s/%s subjects: %v", ns, rb.Name, err)
}
}
}
for _, crb := range policy.ClusterRoleBindings {
b, _ := json.Marshal(binding{Subjects: crb.Subjects})
if _, err := client.RbacV1().ClusterRoleBindings().Patch(ctx, crb.Name, types.MergePatchType, b, metav1.PatchOptions{}); err != nil {
logrus.Debugf("Failed to patch ClusterRoleBinding %s subjects: %v", crb.Name, err)
}
}

// End remediation for https://github.com/rancher/rke2/issues/6272

logrus.Info("Cluster Role Bindings applied successfully")
}()
return nil
Expand Down
4 changes: 2 additions & 2 deletions pkg/rke2/clusterrole_bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func roleBindings() map[string][]rbacv1.RoleBinding {
// For some reason the core helpers don't have any methods for adding namespaced users, only namespaced service accounts.
func RoleBindingNamespacedUsers(r *rbacv1helpers.RoleBindingBuilder, namespace string, users ...string) *rbacv1helpers.RoleBindingBuilder {
for _, user := range users {
r.RoleBinding.Subjects = append(r.RoleBinding.Subjects, rbacv1.Subject{Kind: rbacv1.UserKind, Namespace: namespace, Name: user})
r.RoleBinding.Subjects = append(r.RoleBinding.Subjects, rbacv1.Subject{APIGroup: rbacv1.GroupName, Kind: rbacv1.UserKind, Namespace: namespace, Name: user})
}
return r
}
Expand All @@ -119,7 +119,7 @@ func RoleBindingName(r *rbacv1helpers.RoleBindingBuilder, name string) *rbacv1he
// For some reason the core helpers don't have any methods for adding namespaced users, only namespaced service accounts.
func ClusterRoleBindingNamespacedUsers(r *rbacv1helpers.ClusterRoleBindingBuilder, namespace string, users ...string) *rbacv1helpers.ClusterRoleBindingBuilder {
for _, user := range users {
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, rbacv1.Subject{Kind: rbacv1.UserKind, Namespace: namespace, Name: user})
r.ClusterRoleBinding.Subjects = append(r.ClusterRoleBinding.Subjects, rbacv1.Subject{APIGroup: rbacv1.GroupName, Kind: rbacv1.UserKind, Namespace: namespace, Name: user})
}
return r
}
Expand Down

0 comments on commit af73b78

Please sign in to comment.