Skip to content

Commit 1da5dd5

Browse files
Per Goncalves da Silvaperdasilva
Per Goncalves da Silva
authored andcommitted
Add name validation for strategy deployment and webhook configurations
Signed-off-by: Per Goncalves da Silva <[email protected]>
1 parent 05f4d6b commit 1da5dd5

File tree

3 files changed

+151
-18
lines changed

3 files changed

+151
-18
lines changed

internal/operator-controller/rukpak/convert/registryv1_test.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ func getBaseCsvAndService() (v1alpha1.ClusterServiceVersion, corev1.Service) {
206206
}),
207207
WithStrategyDeploymentSpecs(
208208
v1alpha1.StrategyDeploymentSpec{
209-
Name: "testDeployment",
209+
Name: "test-deployment",
210210
Spec: appsv1.DeploymentSpec{
211211
Template: corev1.PodTemplateSpec{
212212
Spec: corev1.PodSpec{
@@ -271,7 +271,7 @@ func TestRegistryV1SuiteGenerateAllNamespace(t *testing.T) {
271271
require.Len(t, plainBundle.Objects, 5)
272272

273273
t.Log("By verifying olm.targetNamespaces annotation in the deployment's pod template")
274-
dep := findObjectByName("testDeployment", plainBundle.Objects)
274+
dep := findObjectByName("test-deployment", plainBundle.Objects)
275275
require.NotNil(t, dep)
276276
require.Contains(t, dep.(*appsv1.Deployment).Spec.Template.Annotations, olmNamespaces)
277277
require.Equal(t, strings.Join(watchNamespaces, ","), dep.(*appsv1.Deployment).Spec.Template.Annotations[olmNamespaces])
@@ -304,7 +304,7 @@ func TestRegistryV1SuiteGenerateMultiNamespace(t *testing.T) {
304304
require.Len(t, plainBundle.Objects, 7)
305305

306306
t.Log("By verifying olm.targetNamespaces annotation in the deployment's pod template")
307-
dep := findObjectByName("testDeployment", plainBundle.Objects)
307+
dep := findObjectByName("test-deployment", plainBundle.Objects)
308308
require.NotNil(t, dep)
309309
require.Contains(t, dep.(*appsv1.Deployment).Spec.Template.Annotations, olmNamespaces)
310310
require.Equal(t, strings.Join(watchNamespaces, ","), dep.(*appsv1.Deployment).Spec.Template.Annotations[olmNamespaces])
@@ -337,7 +337,7 @@ func TestRegistryV1SuiteGenerateSingleNamespace(t *testing.T) {
337337
require.Len(t, plainBundle.Objects, 5)
338338

339339
t.Log("By verifying olm.targetNamespaces annotation in the deployment's pod template")
340-
dep := findObjectByName("testDeployment", plainBundle.Objects)
340+
dep := findObjectByName("test-deployment", plainBundle.Objects)
341341
require.NotNil(t, dep)
342342
require.Contains(t, dep.(*appsv1.Deployment).Spec.Template.Annotations, olmNamespaces)
343343
require.Equal(t, strings.Join(watchNamespaces, ","), dep.(*appsv1.Deployment).Spec.Template.Annotations[olmNamespaces])
@@ -370,7 +370,7 @@ func TestRegistryV1SuiteGenerateOwnNamespace(t *testing.T) {
370370
require.Len(t, plainBundle.Objects, 5)
371371

372372
t.Log("By verifying olm.targetNamespaces annotation in the deployment's pod template")
373-
dep := findObjectByName("testDeployment", plainBundle.Objects)
373+
dep := findObjectByName("test-deployment", plainBundle.Objects)
374374
require.NotNil(t, dep)
375375
require.Contains(t, dep.(*appsv1.Deployment).Spec.Template.Annotations, olmNamespaces)
376376
require.Equal(t, strings.Join(watchNamespaces, ","), dep.(*appsv1.Deployment).Spec.Template.Annotations[olmNamespaces])
@@ -575,7 +575,7 @@ func TestRegistryV1SuiteGenerateWebhooks_WebhookSupportFGEnabled(t *testing.T) {
575575
CRDs: []apiextensionsv1.CustomResourceDefinition{
576576
{
577577
ObjectMeta: metav1.ObjectMeta{
578-
Name: "fake-webhook.package-with-webhooks.io",
578+
Name: "fake-webhook.package-with-webhooks",
579579
},
580580
},
581581
},
@@ -584,7 +584,7 @@ func TestRegistryV1SuiteGenerateWebhooks_WebhookSupportFGEnabled(t *testing.T) {
584584
WithInstallModeSupportFor(v1alpha1.InstallModeTypeAllNamespaces),
585585
WithOwnedCRDs(
586586
v1alpha1.CRDDescription{
587-
Name: "fake-webhook.package-with-webhooks.io",
587+
Name: "fake-webhook.package-with-webhooks",
588588
},
589589
),
590590
WithStrategyDeploymentSpecs(
@@ -595,8 +595,9 @@ func TestRegistryV1SuiteGenerateWebhooks_WebhookSupportFGEnabled(t *testing.T) {
595595
WithWebhookDefinitions(
596596
v1alpha1.WebhookDescription{
597597
Type: v1alpha1.ConversionWebhook,
598-
ConversionCRDs: []string{"fake-webhook.package-with-webhooks.io"},
598+
ConversionCRDs: []string{"fake-webhook.package-with-webhooks"},
599599
DeploymentName: "some-deployment",
600+
GenerateName: "my-conversion-webhook",
600601
},
601602
),
602603
),

internal/operator-controller/rukpak/render/validators/validator.go

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import (
44
"cmp"
55
"errors"
66
"fmt"
7-
"k8s.io/apimachinery/pkg/util/validation"
87
"maps"
98
"slices"
109
"strings"
1110

1211
"k8s.io/apimachinery/pkg/util/sets"
12+
"k8s.io/apimachinery/pkg/util/validation"
1313

1414
"github.com/operator-framework/api/pkg/operators/v1alpha1"
1515

@@ -22,11 +22,13 @@ var RegistryV1BundleValidator = render.BundleValidator{
2222
// you bring the same changes over to that test. This helps ensure all validation rules are executed
2323
// while giving us the flexibility to test each validation function individually
2424
CheckDeploymentSpecUniqueness,
25+
CheckDeploymentNameIsDNS1123SubDomain,
2526
CheckCRDResourceUniqueness,
2627
CheckOwnedCRDExistence,
2728
CheckPackageNameNotEmpty,
2829
CheckWebhookDeploymentReferentialIntegrity,
2930
CheckWebhookNameUniqueness,
31+
CheckWebhookNameIsDNS1123SubDomain,
3032
CheckConversionWebhookCRDReferenceUniqueness,
3133
CheckConversionWebhooksReferenceOwnedCRDs,
3234
}
@@ -62,7 +64,7 @@ func CheckDeploymentNameIsDNS1123SubDomain(rv1 *render.RegistryV1) []error {
6264
}
6365
}
6466

65-
var errs []error
67+
errs := make([]error, 0, len(deploymentNameErrMap))
6668
for _, dep := range slices.Sorted(maps.Keys(deploymentNameErrMap)) {
6769
errs = append(errs, fmt.Errorf("invalid cluster service version strategy deployment name '%s': %s", dep, strings.Join(deploymentNameErrMap[dep], ", ")))
6870
}
@@ -158,7 +160,7 @@ func CheckWebhookDeploymentReferentialIntegrity(rv1 *render.RegistryV1) []error
158160
return cmp.Or(cmp.Compare(a.Type, b.Type), cmp.Compare(a.GenerateName, b.GenerateName))
159161
})
160162
for _, webhookDef := range webhookDefns {
161-
errs = append(errs, fmt.Errorf("webhook '%s' of type '%s' references non-existent deployment '%s'", webhookDef.GenerateName, webhookDef.Type, webhookDef.DeploymentName))
163+
errs = append(errs, fmt.Errorf("webhook of type '%s' with name '%s' references non-existent deployment '%s'", webhookDef.Type, webhookDef.GenerateName, webhookDef.DeploymentName))
162164
}
163165
}
164166
return errs
@@ -256,3 +258,26 @@ func CheckConversionWebhookCRDReferenceUniqueness(rv1 *render.RegistryV1) []erro
256258
}
257259
return errs
258260
}
261+
262+
// CheckWebhookNameIsDNS1123SubDomain checks each webhook configuration name complies with the Kubernetes resource naming conversions
263+
func CheckWebhookNameIsDNS1123SubDomain(rv1 *render.RegistryV1) []error {
264+
invalidWebhooksByType := map[v1alpha1.WebhookAdmissionType]map[string][]string{}
265+
for _, wh := range rv1.CSV.Spec.WebhookDefinitions {
266+
if _, ok := invalidWebhooksByType[wh.Type]; !ok {
267+
invalidWebhooksByType[wh.Type] = map[string][]string{}
268+
}
269+
errs := validation.IsDNS1123Subdomain(wh.GenerateName)
270+
if len(errs) > 0 {
271+
slices.Sort(errs)
272+
invalidWebhooksByType[wh.Type][wh.GenerateName] = errs
273+
}
274+
}
275+
276+
var errs []error
277+
for _, whType := range slices.Sorted(maps.Keys(invalidWebhooksByType)) {
278+
for _, webhookName := range slices.Sorted(maps.Keys(invalidWebhooksByType[whType])) {
279+
errs = append(errs, fmt.Errorf("webhook of type '%s' has invalid name '%s': %s", whType, webhookName, strings.Join(invalidWebhooksByType[whType][webhookName], ",")))
280+
}
281+
}
282+
return errs
283+
}

internal/operator-controller/rukpak/render/validators/validator_test.go

Lines changed: 114 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ import (
1919
func Test_BundleValidatorHasAllValidationFns(t *testing.T) {
2020
expectedValidationFns := []func(v1 *render.RegistryV1) []error{
2121
validators.CheckDeploymentSpecUniqueness,
22+
validators.CheckDeploymentNameIsDNS1123SubDomain,
2223
validators.CheckCRDResourceUniqueness,
2324
validators.CheckOwnedCRDExistence,
2425
validators.CheckPackageNameNotEmpty,
2526
validators.CheckWebhookDeploymentReferentialIntegrity,
2627
validators.CheckWebhookNameUniqueness,
28+
validators.CheckWebhookNameIsDNS1123SubDomain,
2729
validators.CheckConversionWebhookCRDReferenceUniqueness,
2830
validators.CheckConversionWebhooksReferenceOwnedCRDs,
2931
}
@@ -92,6 +94,48 @@ func Test_CheckDeploymentSpecUniqueness(t *testing.T) {
9294
}
9395
}
9496

97+
func Test_CheckDeploymentNameIsDNS1123SubDomain(t *testing.T) {
98+
for _, tc := range []struct {
99+
name string
100+
bundle *render.RegistryV1
101+
expectedErrs []error
102+
}{
103+
{
104+
name: "accepts valid deployment strategy spec names",
105+
bundle: &render.RegistryV1{
106+
CSV: MakeCSV(
107+
WithStrategyDeploymentSpecs(
108+
v1alpha1.StrategyDeploymentSpec{Name: "test-deployment-one"},
109+
v1alpha1.StrategyDeploymentSpec{Name: "test-deployment-two"},
110+
),
111+
),
112+
},
113+
expectedErrs: []error{},
114+
}, {
115+
name: "rejects bundles with invalid deployment strategy spec names - errors are sorted by name",
116+
bundle: &render.RegistryV1{
117+
CSV: MakeCSV(
118+
WithStrategyDeploymentSpecs(
119+
v1alpha1.StrategyDeploymentSpec{Name: "-bad-name"},
120+
v1alpha1.StrategyDeploymentSpec{Name: "b-name-is-waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay-too-long"},
121+
v1alpha1.StrategyDeploymentSpec{Name: "a-name-is-waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay-too-long-and-bad-"},
122+
),
123+
),
124+
},
125+
expectedErrs: []error{
126+
errors.New("invalid cluster service version strategy deployment name '-bad-name': a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"),
127+
errors.New("invalid cluster service version strategy deployment name 'a-name-is-waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay-too-long-and-bad-': a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*'), must be no more than 253 characters"),
128+
errors.New("invalid cluster service version strategy deployment name 'b-name-is-waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay-too-long': must be no more than 253 characters"),
129+
},
130+
},
131+
} {
132+
t.Run(tc.name, func(t *testing.T) {
133+
errs := validators.CheckDeploymentNameIsDNS1123SubDomain(tc.bundle)
134+
require.Equal(t, tc.expectedErrs, errs)
135+
})
136+
}
137+
}
138+
95139
func Test_CRDResourceUniqueness(t *testing.T) {
96140
for _, tc := range []struct {
97141
name string
@@ -356,7 +400,7 @@ func Test_CheckWebhookDeploymentReferentialIntegrity(t *testing.T) {
356400
),
357401
},
358402
expectedErrs: []error{
359-
errors.New("webhook 'test-webhook' of type 'ValidatingAdmissionWebhook' references non-existent deployment 'test-deployment-two'"),
403+
errors.New("webhook of type 'ValidatingAdmissionWebhook' with name 'test-webhook' references non-existent deployment 'test-deployment-two'"),
360404
},
361405
}, {
362406
name: "errors are ordered by deployment strategy spec name, webhook type, and webhook name",
@@ -398,12 +442,12 @@ func Test_CheckWebhookDeploymentReferentialIntegrity(t *testing.T) {
398442
),
399443
},
400444
expectedErrs: []error{
401-
errors.New("webhook 'test-mute-webhook-a' of type 'MutatingAdmissionWebhook' references non-existent deployment 'test-deployment-a'"),
402-
errors.New("webhook 'test-conv-webhook-b' of type 'ConversionWebhook' references non-existent deployment 'test-deployment-b'"),
403-
errors.New("webhook 'test-conv-webhook-c-a' of type 'ConversionWebhook' references non-existent deployment 'test-deployment-c'"),
404-
errors.New("webhook 'test-conv-webhook-c-b' of type 'ConversionWebhook' references non-existent deployment 'test-deployment-c'"),
405-
errors.New("webhook 'test-mute-webhook-c' of type 'MutatingAdmissionWebhook' references non-existent deployment 'test-deployment-c'"),
406-
errors.New("webhook 'test-val-webhook-c' of type 'ValidatingAdmissionWebhook' references non-existent deployment 'test-deployment-c'"),
445+
errors.New("webhook of type 'MutatingAdmissionWebhook' with name 'test-mute-webhook-a' references non-existent deployment 'test-deployment-a'"),
446+
errors.New("webhook of type 'ConversionWebhook' with name 'test-conv-webhook-b' references non-existent deployment 'test-deployment-b'"),
447+
errors.New("webhook of type 'ConversionWebhook' with name 'test-conv-webhook-c-a' references non-existent deployment 'test-deployment-c'"),
448+
errors.New("webhook of type 'ConversionWebhook' with name 'test-conv-webhook-c-b' references non-existent deployment 'test-deployment-c'"),
449+
errors.New("webhook of type 'MutatingAdmissionWebhook' with name 'test-mute-webhook-c' references non-existent deployment 'test-deployment-c'"),
450+
errors.New("webhook of type 'ValidatingAdmissionWebhook' with name 'test-val-webhook-c' references non-existent deployment 'test-deployment-c'"),
407451
},
408452
},
409453
} {
@@ -837,3 +881,66 @@ func Test_CheckConversionWebhookCRDReferenceUniqueness(t *testing.T) {
837881
})
838882
}
839883
}
884+
885+
func Test_CheckWebhookNameIsDNS1123SubDomain(t *testing.T) {
886+
for _, tc := range []struct {
887+
name string
888+
bundle *render.RegistryV1
889+
expectedErrs []error
890+
}{
891+
{
892+
name: "accepts bundles without webhook definitions",
893+
bundle: &render.RegistryV1{
894+
CSV: MakeCSV(),
895+
},
896+
}, {
897+
name: "rejects bundles with invalid webhook definitions names and orders errors by webhook type and name",
898+
bundle: &render.RegistryV1{
899+
CSV: MakeCSV(
900+
WithWebhookDefinitions(
901+
v1alpha1.WebhookDescription{
902+
Type: v1alpha1.ValidatingAdmissionWebhook,
903+
GenerateName: "b-name-is-waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay-too-long-and-bad-",
904+
}, v1alpha1.WebhookDescription{
905+
Type: v1alpha1.ValidatingAdmissionWebhook,
906+
GenerateName: "a-name-is-waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay-too-long",
907+
},
908+
v1alpha1.WebhookDescription{
909+
Type: v1alpha1.ValidatingAdmissionWebhook,
910+
GenerateName: "-bad-name",
911+
},
912+
v1alpha1.WebhookDescription{
913+
Type: v1alpha1.ConversionWebhook,
914+
GenerateName: "b-bad-name-",
915+
},
916+
v1alpha1.WebhookDescription{
917+
Type: v1alpha1.MutatingAdmissionWebhook,
918+
GenerateName: "b-name-is-waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay-too-long-and-bad-",
919+
}, v1alpha1.WebhookDescription{
920+
Type: v1alpha1.MutatingAdmissionWebhook,
921+
GenerateName: "a-bad-name-",
922+
},
923+
v1alpha1.WebhookDescription{
924+
Type: v1alpha1.ConversionWebhook,
925+
GenerateName: "a-bad-name-",
926+
},
927+
),
928+
),
929+
},
930+
expectedErrs: []error{
931+
errors.New("webhook of type 'ConversionWebhook' has invalid name 'a-bad-name-': a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"),
932+
errors.New("webhook of type 'ConversionWebhook' has invalid name 'b-bad-name-': a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"),
933+
errors.New("webhook of type 'MutatingAdmissionWebhook' has invalid name 'a-bad-name-': a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"),
934+
errors.New("webhook of type 'MutatingAdmissionWebhook' has invalid name 'b-name-is-waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay-too-long-and-bad-': a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*'),must be no more than 253 characters"),
935+
errors.New("webhook of type 'ValidatingAdmissionWebhook' has invalid name '-bad-name': a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')"),
936+
errors.New("webhook of type 'ValidatingAdmissionWebhook' has invalid name 'a-name-is-waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay-too-long': must be no more than 253 characters"),
937+
errors.New("webhook of type 'ValidatingAdmissionWebhook' has invalid name 'b-name-is-waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaay-too-long-and-bad-': a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*'),must be no more than 253 characters"),
938+
},
939+
},
940+
} {
941+
t.Run(tc.name, func(t *testing.T) {
942+
errs := validators.CheckWebhookNameIsDNS1123SubDomain(tc.bundle)
943+
require.Equal(t, tc.expectedErrs, errs)
944+
})
945+
}
946+
}

0 commit comments

Comments
 (0)