From 2771dd7c6103c41fef10c0b10ff0b5f8c8a4a01a Mon Sep 17 00:00:00 2001 From: Ryan Sanna Date: Fri, 25 Mar 2022 13:36:36 -0700 Subject: [PATCH] Update CRTB/PRTB validation handlers to disallow updates to referenced role template --- .../clusterroletemplatebinding/clusterrtb.go | 21 ++++++++++++++++++ .../projectroletemplatebinding/projectrtb.go | 22 ++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/pkg/resources/validation/clusterroletemplatebinding/clusterrtb.go b/pkg/resources/validation/clusterroletemplatebinding/clusterrtb.go index 7983b3233..2a4000a46 100644 --- a/pkg/resources/validation/clusterroletemplatebinding/clusterrtb.go +++ b/pkg/resources/validation/clusterroletemplatebinding/clusterrtb.go @@ -1,13 +1,17 @@ package clusterroletemplatebinding import ( + "fmt" + "net/http" "time" "github.com/rancher/webhook/pkg/auth" v3 "github.com/rancher/webhook/pkg/generated/controllers/management.cattle.io/v3" objectsv3 "github.com/rancher/webhook/pkg/generated/objects/management.cattle.io/v3" "github.com/rancher/wrangler/pkg/webhook" + admissionv1 "k8s.io/api/admission/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/trace" ) @@ -27,6 +31,23 @@ func (c *clusterRoleTemplateBindingValidator) Admit(response *webhook.Response, listTrace := trace.New("clusterRoleTemplateBindingValidator Admit", trace.Field{Key: "user", Value: request.UserInfo.Username}) defer listTrace.LogIfLong(2 * time.Second) + // disallow updates to the referenced role template + if request.Operation == admissionv1.Update { + oldCrtb, newCrtb, err := objectsv3.ClusterRoleTemplateBindingOldAndNewFromRequest(request) + if err != nil { + return err + } + if oldCrtb.RoleTemplateName != newCrtb.RoleTemplateName { + response.Result = &metav1.Status{ + Status: "Failure", + Message: fmt.Sprintf("cannot update referenced roleTemplate for clusterRoleTemplateBinding %s", oldCrtb.Name), + Reason: metav1.StatusReasonBadRequest, + Code: http.StatusBadRequest, + } + return nil + } + } + crtb, err := objectsv3.ClusterRoleTemplateBindingFromRequest(request) if err != nil { return err diff --git a/pkg/resources/validation/projectroletemplatebinding/projectrtb.go b/pkg/resources/validation/projectroletemplatebinding/projectrtb.go index 4330457d4..c5db2902e 100644 --- a/pkg/resources/validation/projectroletemplatebinding/projectrtb.go +++ b/pkg/resources/validation/projectroletemplatebinding/projectrtb.go @@ -1,6 +1,8 @@ package projectroletemplatebinding import ( + "fmt" + "net/http" "strings" "time" @@ -8,7 +10,9 @@ import ( v3 "github.com/rancher/webhook/pkg/generated/controllers/management.cattle.io/v3" objectsv3 "github.com/rancher/webhook/pkg/generated/objects/management.cattle.io/v3" "github.com/rancher/wrangler/pkg/webhook" + admissionv1 "k8s.io/api/admission/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/trace" ) @@ -28,13 +32,29 @@ func (p *projectRoleTemplateBindingValidator) Admit(response *webhook.Response, listTrace := trace.New("projectRoleTemplateBindingValidator Admit", trace.Field{Key: "user", Value: request.UserInfo.Username}) defer listTrace.LogIfLong(2 * time.Second) + // disallow updates to the referenced role template + if request.Operation == admissionv1.Update { + oldPrtb, newPrtb, err := objectsv3.ProjectRoleTemplateBindingOldAndNewFromRequest(request) + if err != nil { + return err + } + if oldPrtb.RoleTemplateName != newPrtb.RoleTemplateName { + response.Result = &metav1.Status{ + Status: "Failure", + Message: fmt.Sprintf("cannot update referenced roleTemplate for projectRoleTemplateBinding %s", oldPrtb.Name), + Reason: metav1.StatusReasonBadRequest, + Code: http.StatusBadRequest, + } + return nil + } + } + prtb, err := objectsv3.ProjectRoleTemplateBindingFromRequest(request) if err != nil { return err } clusterID, projectNS := clusterFromProject(prtb.ProjectName) - if clusterID != "local" { response.Allowed = true return nil