Skip to content

Commit

Permalink
Always validate Namespace and ProjectRequest for the organization lab…
Browse files Browse the repository at this point in the history
…el (#97)

The ProjectRequest validation in Kyverno does not work for unknown reasons.
This fixes users without default organizations allowed to create projects.
  • Loading branch information
bastjan authored May 29, 2024
1 parent 3811f05 commit ad9b101
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 9 deletions.
7 changes: 3 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,9 @@ func main() {
Client: mgr.GetClient(),
Decoder: admission.NewDecoder(mgr.GetScheme()),

Skipper: skipper.NewMultiSkipper(
skipper.StaticSkipper{ShouldSkip: disableUsageProfiles},
psk,
),
Skipper: psk,

SkipValidateQuota: disableUsageProfiles,

OrganizationLabel: conf.OrganizationLabel,
UserDefaultOrganizationAnnotation: conf.UserDefaultOrganizationAnnotation,
Expand Down
13 changes: 12 additions & 1 deletion webhooks/namespace_quota_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ import (
// +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch
// +kubebuilder:rbac:groups=user.openshift.io,resources=users,verbs=get;list;watch

// NamespaceQuotaValidator checks namespaces for allowed node selectors.
// NamespaceQuotaValidator checks if a user is allowed to create a namespace.
// The user or the namespace must have a label with the organization name.
// The organization name is used to count the number of namespaces for the organization.
type NamespaceQuotaValidator struct {
Decoder *admission.Decoder

Expand All @@ -34,6 +36,10 @@ type NamespaceQuotaValidator struct {

Skipper skipper.Skipper

// SkipValidateQuota allows skipping the quota validation.
// If the validation is skipped only the organization label is checked.
SkipValidateQuota bool

OrganizationLabel string
UserDefaultOrganizationAnnotation string

Expand Down Expand Up @@ -89,6 +95,11 @@ func (v *NamespaceQuotaValidator) Handle(ctx context.Context, req admission.Requ
l.Info("got default organization from user", "user", req.UserInfo.Username, "organization", organizationName)
}

if v.SkipValidateQuota {
l.V(1).Info("allowed: skipped quota validation")
return admission.Allowed("skipped quota validation")
}

if v.SelectedProfile == "" {
return admission.Denied("No ZoneUsageProfile selected")
}
Expand Down
47 changes: 43 additions & 4 deletions webhooks/namespace_quota_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ func TestNamespaceQuotaValidator_Handle(t *testing.T) {
const nsLimit = 2

tests := map[string]struct {
initObjects []client.Object
object client.Object
allowed bool
matchMessage string
initObjects []client.Object
object client.Object
allowed bool
skipQuotaValidation bool
matchMessage string
}{
"Allow Namespace": {
initObjects: []client.Object{
Expand Down Expand Up @@ -158,6 +159,42 @@ func TestNamespaceQuotaValidator_Handle(t *testing.T) {
},
allowed: false,
},

"SkipQuotaValidation Allow Namespace TooMany": {
initObjects: []client.Object{newNamespace("a", map[string]string{orgLabel: "testorg"}, nil), newNamespace("b", map[string]string{orgLabel: "testorg"}, nil)},
object: &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Labels: map[string]string{
orgLabel: "testorg",
},
},
},
skipQuotaValidation: true,
allowed: true,
},
"SkipQuotaValidation Allow ProjectRequest TooMany": {
initObjects: []client.Object{newNamespace("a", map[string]string{orgLabel: "testorg"}, nil), newNamespace("b", map[string]string{orgLabel: "testorg"}, nil)},
object: &projectv1.ProjectRequest{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
Labels: map[string]string{
orgLabel: "testorg",
},
},
},
skipQuotaValidation: true,
allowed: true,
},
"SkipQuotaValidation Deny NoOrganizationLabelAndNoUser": {
object: &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
},
},
skipQuotaValidation: true,
allowed: false,
},
}

for name, test := range tests {
Expand All @@ -168,6 +205,8 @@ func TestNamespaceQuotaValidator_Handle(t *testing.T) {
Client: c,
Skipper: skipper.StaticSkipper{ShouldSkip: false},

SkipValidateQuota: test.skipQuotaValidation,

OrganizationLabel: orgLabel,
UserDefaultOrganizationAnnotation: userDefaultOrgAnnotation,

Expand Down

0 comments on commit ad9b101

Please sign in to comment.