Commit 03c21d34 authored by Craig Jellick's avatar Craig Jellick
Browse files

Remove legacy role bindings

Bindings were not being cleaned up properly. This fix addresses that.
parent ec137736
release/v2.0 Tags unavailable
No related merge requests found
Showing with 103 additions and 14 deletions
+103 -14
......@@ -93,6 +93,7 @@ func Register(workload *config.UserContext) {
}
workload.Management.Management.Projects("").AddClusterScopedLifecycle("project-namespace-auth", workload.ClusterName, newProjectLifecycle(r))
workload.Management.Management.ProjectRoleTemplateBindings("").AddClusterScopedLifecycle("cluster-prtb-sync", workload.ClusterName, newPRTBLifecycle(r))
workload.RBAC.ClusterRoleBindings("").AddHandler("legacy-crb-cleaner-sync", newLegacyCRBCleaner(r).sync)
workload.Management.Management.ClusterRoleTemplateBindings("").AddClusterScopedLifecycle("cluster-crtb-sync", workload.ClusterName, newCRTBLifecycle(r))
workload.Management.Management.Clusters("").AddHandler("global-admin-cluster-sync", newClusterHandler(workload))
......
package rbac
import (
"regexp"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
var crbNamePattern = regexp.MustCompile("clusterrolebinding-.+")
var namespaceRoleRefPattern = regexp.MustCompile(".+-namespaces-.+")
var promotedRoleRefPattern = regexp.MustCompile(".+-promoted")
const createNSRoleRef = "create-ns"
func newLegacyCRBCleaner(m *manager) *crbCleaner {
return &crbCleaner{
m: m,
}
}
type crbCleaner struct {
m *manager
}
func (p *crbCleaner) sync(key string, obj *rbacv1.ClusterRoleBinding) error {
if key == "" || obj == nil {
return nil
}
eligible, err := p.eligibleForDeletion(obj)
if err != nil {
return err
}
if eligible {
if err := p.m.workload.RBAC.ClusterRoleBindings("").Delete(obj.Name, &metav1.DeleteOptions{}); err != nil {
if !errors.IsNotFound(err) {
return err
}
}
}
return nil
}
func (p *crbCleaner) eligibleForDeletion(crb *rbacv1.ClusterRoleBinding) (bool, error) {
if !crbNamePattern.MatchString(crb.Name) {
return false, nil
}
if noOwners, err := p.m.noRemainingOwnerLabels(crb); !noOwners || err != nil {
return false, err
}
roleRefName := crb.RoleRef.Name
if roleRefName == createNSRoleRef {
return true, nil
}
if namespaceRoleRefPattern.MatchString(roleRefName) {
return true, nil
}
if promotedRoleRefPattern.MatchString(roleRefName) {
return true, nil
}
return false, nil
}
......@@ -6,6 +6,7 @@ import (
"strings"
"github.com/pkg/errors"
"github.com/rancher/norman/types/convert"
"github.com/rancher/norman/types/slice"
"github.com/rancher/types/apis/management.cattle.io/v3"
"github.com/sirupsen/logrus"
......@@ -229,19 +230,6 @@ func (p *prtbLifecycle) reconcileProjectAccessToGlobalResources(binding *v3.Proj
}
func (p *prtbLifecycle) reconcileProjectAccessToGlobalResourcesForDelete(binding *v3.ProjectRoleTemplateBinding) error {
prtbs, err := p.m.prtbIndexer.ByIndex(prtbByProjecSubjectIndex, getPRTBProjectAndSubjectKey(binding))
if err != nil {
return err
}
if len(prtbs) != 0 {
for _, p := range prtbs {
pr := p.(*v3.ProjectRoleTemplateBinding)
if pr.DeletionTimestamp == nil {
return nil
}
}
}
bindingCli := p.m.workload.K8sClient.RbacV1().ClusterRoleBindings()
rtbUID := string(binding.UID)
set := labels.Set(map[string]string{rtbUID: owner})
......@@ -258,7 +246,12 @@ func (p *prtbLifecycle) reconcileProjectAccessToGlobalResourcesForDelete(binding
}
}
if len(crb.Labels) == 0 {
delete, err := p.m.noRemainingOwnerLabels(crb)
if err != nil {
return err
}
if delete {
if err := bindingCli.Delete(crb.Name, &metav1.DeleteOptions{}); err != nil {
if apierrors.IsNotFound(err) {
continue
......@@ -275,6 +268,29 @@ func (p *prtbLifecycle) reconcileProjectAccessToGlobalResourcesForDelete(binding
return nil
}
func (m *manager) noRemainingOwnerLabels(crb *rbacv1.ClusterRoleBinding) (bool, error) {
for k, v := range crb.Labels {
if v == owner {
if exists, err := m.ownerExists(k); exists || err != nil {
return false, err
}
}
if k == rtbOwnerLabel {
if exists, err := m.ownerExists(v); exists || err != nil {
return false, err
}
}
}
return true, nil
}
func (m *manager) ownerExists(uid interface{}) (bool, error) {
prtbs, err := m.prtbIndexer.ByIndex(prtbByUIDIndex, convert.ToString(uid))
return len(prtbs) > 0, err
}
// If the roleTemplate has rules granting access to non-namespaced (global) resource, return the verbs for those rules
func (m *manager) checkForGlobalResourceRules(role *v3.RoleTemplate, resource string) (map[string]bool, error) {
var rules []rbacv1.PolicyRule
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment