Skip to content

Commit ad9b101

Browse files
authored
Always validate Namespace and ProjectRequest for the organization label (#97)
The ProjectRequest validation in Kyverno does not work for unknown reasons. This fixes users without default organizations allowed to create projects.
1 parent 3811f05 commit ad9b101

File tree

3 files changed

+58
-9
lines changed

3 files changed

+58
-9
lines changed

main.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,9 @@ func main() {
229229
Client: mgr.GetClient(),
230230
Decoder: admission.NewDecoder(mgr.GetScheme()),
231231

232-
Skipper: skipper.NewMultiSkipper(
233-
skipper.StaticSkipper{ShouldSkip: disableUsageProfiles},
234-
psk,
235-
),
232+
Skipper: psk,
233+
234+
SkipValidateQuota: disableUsageProfiles,
236235

237236
OrganizationLabel: conf.OrganizationLabel,
238237
UserDefaultOrganizationAnnotation: conf.UserDefaultOrganizationAnnotation,

webhooks/namespace_quota_validator.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ import (
2525
// +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch
2626
// +kubebuilder:rbac:groups=user.openshift.io,resources=users,verbs=get;list;watch
2727

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

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

3537
Skipper skipper.Skipper
3638

39+
// SkipValidateQuota allows skipping the quota validation.
40+
// If the validation is skipped only the organization label is checked.
41+
SkipValidateQuota bool
42+
3743
OrganizationLabel string
3844
UserDefaultOrganizationAnnotation string
3945

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

98+
if v.SkipValidateQuota {
99+
l.V(1).Info("allowed: skipped quota validation")
100+
return admission.Allowed("skipped quota validation")
101+
}
102+
92103
if v.SelectedProfile == "" {
93104
return admission.Denied("No ZoneUsageProfile selected")
94105
}

webhooks/namespace_quota_validator_test.go

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ func TestNamespaceQuotaValidator_Handle(t *testing.T) {
2323
const nsLimit = 2
2424

2525
tests := map[string]struct {
26-
initObjects []client.Object
27-
object client.Object
28-
allowed bool
29-
matchMessage string
26+
initObjects []client.Object
27+
object client.Object
28+
allowed bool
29+
skipQuotaValidation bool
30+
matchMessage string
3031
}{
3132
"Allow Namespace": {
3233
initObjects: []client.Object{
@@ -158,6 +159,42 @@ func TestNamespaceQuotaValidator_Handle(t *testing.T) {
158159
},
159160
allowed: false,
160161
},
162+
163+
"SkipQuotaValidation Allow Namespace TooMany": {
164+
initObjects: []client.Object{newNamespace("a", map[string]string{orgLabel: "testorg"}, nil), newNamespace("b", map[string]string{orgLabel: "testorg"}, nil)},
165+
object: &corev1.Namespace{
166+
ObjectMeta: metav1.ObjectMeta{
167+
Name: "test",
168+
Labels: map[string]string{
169+
orgLabel: "testorg",
170+
},
171+
},
172+
},
173+
skipQuotaValidation: true,
174+
allowed: true,
175+
},
176+
"SkipQuotaValidation Allow ProjectRequest TooMany": {
177+
initObjects: []client.Object{newNamespace("a", map[string]string{orgLabel: "testorg"}, nil), newNamespace("b", map[string]string{orgLabel: "testorg"}, nil)},
178+
object: &projectv1.ProjectRequest{
179+
ObjectMeta: metav1.ObjectMeta{
180+
Name: "test",
181+
Labels: map[string]string{
182+
orgLabel: "testorg",
183+
},
184+
},
185+
},
186+
skipQuotaValidation: true,
187+
allowed: true,
188+
},
189+
"SkipQuotaValidation Deny NoOrganizationLabelAndNoUser": {
190+
object: &corev1.Namespace{
191+
ObjectMeta: metav1.ObjectMeta{
192+
Name: "test",
193+
},
194+
},
195+
skipQuotaValidation: true,
196+
allowed: false,
197+
},
161198
}
162199

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

208+
SkipValidateQuota: test.skipQuotaValidation,
209+
171210
OrganizationLabel: orgLabel,
172211
UserDefaultOrganizationAnnotation: userDefaultOrgAnnotation,
173212

0 commit comments

Comments
 (0)