Skip to content

Commit 7900c94

Browse files
authored
Merge pull request kubernetes#82200 from liggitt/e2e-readyz-check
Make webhook/crd e2e tests behave in parallel and non-`--enable-aggregator-routing` test environments
2 parents 7d40536 + 2d9f46f commit 7900c94

File tree

3 files changed

+71
-4
lines changed

3 files changed

+71
-4
lines changed

test/e2e/apimachinery/crd_conversion_webhook.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3131
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3232
"k8s.io/apimachinery/pkg/util/intstr"
33+
"k8s.io/apimachinery/pkg/util/wait"
3334
"k8s.io/client-go/dynamic"
3435
clientset "k8s.io/client-go/kubernetes"
3536
"k8s.io/kubernetes/test/e2e/framework"
@@ -167,6 +168,7 @@ var _ = SIGDescribe("CustomResourceConversionWebhook [Privileged:ClusterAdmin]",
167168
return
168169
}
169170
defer testcrd.CleanUp()
171+
waitWebhookConversionReady(f, testcrd.Crd, testcrd.DynamicClients, "v2")
170172
testCustomResourceConversionWebhook(f, testcrd.Crd, testcrd.DynamicClients)
171173
})
172174

@@ -201,6 +203,7 @@ var _ = SIGDescribe("CustomResourceConversionWebhook [Privileged:ClusterAdmin]",
201203
return
202204
}
203205
defer testcrd.CleanUp()
206+
waitWebhookConversionReady(f, testcrd.Crd, testcrd.DynamicClients, "v2")
204207
testCRListConversion(f, testcrd)
205208
})
206209
})
@@ -292,6 +295,18 @@ func deployCustomResourceWebhookAndService(f *framework.Framework, image string,
292295
// Use a non-default port for containers.
293296
fmt.Sprintf("--port=%d", containerPort),
294297
},
298+
ReadinessProbe: &v1.Probe{
299+
Handler: v1.Handler{
300+
HTTPGet: &v1.HTTPGetAction{
301+
Scheme: v1.URISchemeHTTPS,
302+
Port: intstr.FromInt(int(containerPort)),
303+
Path: "/readyz",
304+
},
305+
},
306+
PeriodSeconds: 1,
307+
SuccessThreshold: 1,
308+
FailureThreshold: 30,
309+
},
295310
Image: image,
296311
Ports: []v1.ContainerPort{{ContainerPort: containerPort}},
297312
},
@@ -473,3 +488,29 @@ func testCRListConversion(f *framework.Framework, testCrd *crd.TestCrd) {
473488
verifyV2Object(f, crd, &list.Items[0])
474489
verifyV2Object(f, crd, &list.Items[1])
475490
}
491+
492+
// waitWebhookConversionReady sends stub custom resource creation requests requiring conversion until one succeeds.
493+
func waitWebhookConversionReady(f *framework.Framework, crd *apiextensionsv1.CustomResourceDefinition, customResourceClients map[string]dynamic.ResourceInterface, version string) {
494+
framework.ExpectNoError(wait.PollImmediate(100*time.Millisecond, 30*time.Second, func() (bool, error) {
495+
crInstance := &unstructured.Unstructured{
496+
Object: map[string]interface{}{
497+
"kind": crd.Spec.Names.Kind,
498+
"apiVersion": crd.Spec.Group + "/" + version,
499+
"metadata": map[string]interface{}{
500+
"name": f.UniqueName,
501+
"namespace": f.Namespace.Name,
502+
},
503+
},
504+
}
505+
_, err := customResourceClients[version].Create(crInstance, metav1.CreateOptions{})
506+
if err != nil {
507+
// tolerate clusters that do not set --enable-aggregator-routing and have to wait for kube-proxy
508+
// to program the service network, during which conversion requests return errors
509+
e2elog.Logf("error waiting for conversion to succeed during setup: %v", err)
510+
return false, nil
511+
}
512+
513+
framework.ExpectNoError(customResourceClients[version].Delete(crInstance.GetName(), nil), "cleaning up stub object")
514+
return true, nil
515+
}))
516+
}

test/e2e/apimachinery/webhook.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -419,13 +419,16 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() {
419419
},
420420
Webhooks: []admissionregistrationv1.ValidatingWebhook{
421421
newDenyConfigMapWebhookFixture(f, context, servicePort),
422+
newValidatingIsReadyWebhookFixture(f, context, servicePort),
422423
},
423424
})
424425
framework.ExpectNoError(err, "Creating validating webhook configuration")
425426
defer func() {
426427
err := client.AdmissionregistrationV1().ValidatingWebhookConfigurations().Delete(hook.Name, nil)
427428
framework.ExpectNoError(err, "Deleting validating webhook configuration")
428429
}()
430+
// ensure backend is ready before proceeding
431+
waitWebhookConfigurationReady(f)
429432
ginkgo.By("Creating a configMap that does not comply to the validation webhook rules")
430433
err = wait.PollImmediate(100*time.Millisecond, 30*time.Second, func() (bool, error) {
431434
cm := namedNonCompliantConfigMap(string(uuid.NewUUID()), f)
@@ -509,14 +512,16 @@ var _ = SIGDescribe("AdmissionWebhook [Privileged:ClusterAdmin]", func() {
509512
},
510513
Webhooks: []admissionregistrationv1.MutatingWebhook{
511514
newMutateConfigMapWebhookFixture(f, context, 1, servicePort),
515+
newMutatingIsReadyWebhookFixture(f, context, servicePort),
512516
},
513517
})
514518
framework.ExpectNoError(err, "Creating mutating webhook configuration")
515519
defer func() {
516520
err := client.AdmissionregistrationV1().MutatingWebhookConfigurations().Delete(hook.Name, nil)
517521
framework.ExpectNoError(err, "Deleting mutating webhook configuration")
518522
}()
519-
523+
// ensure backend is ready before proceeding
524+
waitWebhookConfigurationReady(f)
520525
hook, err = admissionClient.MutatingWebhookConfigurations().Get(f.UniqueName, metav1.GetOptions{})
521526
framework.ExpectNoError(err, "Getting mutating webhook configuration")
522527
ginkgo.By("Updating a mutating webhook configuration's rules to not include the create operation")
@@ -778,6 +783,18 @@ func deployWebhookAndService(f *framework.Framework, image string, context *cert
778783
// Use a non-default port for containers.
779784
fmt.Sprintf("--port=%d", containerPort),
780785
},
786+
ReadinessProbe: &v1.Probe{
787+
Handler: v1.Handler{
788+
HTTPGet: &v1.HTTPGetAction{
789+
Scheme: v1.URISchemeHTTPS,
790+
Port: intstr.FromInt(int(containerPort)),
791+
Path: "/readyz",
792+
},
793+
},
794+
PeriodSeconds: 1,
795+
SuccessThreshold: 1,
796+
FailureThreshold: 30,
797+
},
781798
Image: image,
782799
Ports: []v1.ContainerPort{{ContainerPort: containerPort}},
783800
},
@@ -2049,8 +2066,8 @@ func registerValidatingWebhookForCRD(f *framework.Framework, configName string,
20492066
},
20502067
SideEffects: &sideEffectsNone,
20512068
AdmissionReviewVersions: []string{"v1", "v1beta1"},
2052-
// Scope the webhook to just this namespace
2053-
NamespaceSelector: &metav1.LabelSelector{
2069+
// Scope the webhook to just this test
2070+
ObjectSelector: &metav1.LabelSelector{
20542071
MatchLabels: map[string]string{f.UniqueName: "true"},
20552072
},
20562073
},
@@ -2101,6 +2118,9 @@ func testCRDDenyWebhook(f *framework.Framework) {
21012118
ObjectMeta: metav1.ObjectMeta{
21022119
Name: name + "s." + group,
21032120
Labels: map[string]string{
2121+
// this label ensures our object is routed to this test's webhook
2122+
f.UniqueName: "true",
2123+
// this is the label the webhook disallows
21042124
"webhook-e2e-test": "webhook-disallow",
21052125
},
21062126
},
@@ -2434,6 +2454,7 @@ func waitWebhookConfigurationReady(f *framework.Framework) error {
24342454
// with "marker" requests via waitWebhookConfigurationReady to wait for a webhook configuration to be ready.
24352455
func newValidatingIsReadyWebhookFixture(f *framework.Framework, context *certContext, servicePort int32) admissionregistrationv1.ValidatingWebhook {
24362456
sideEffectsNone := admissionregistrationv1.SideEffectClassNone
2457+
failOpen := admissionregistrationv1.Ignore
24372458
return admissionregistrationv1.ValidatingWebhook{
24382459
Name: "validating-is-webhook-configuration-ready.k8s.io",
24392460
Rules: []admissionregistrationv1.RuleWithOperations{{
@@ -2453,6 +2474,8 @@ func newValidatingIsReadyWebhookFixture(f *framework.Framework, context *certCon
24532474
},
24542475
CABundle: context.signingCert,
24552476
},
2477+
// network failures while the service network routing is being set up should be ignored by the marker
2478+
FailurePolicy: &failOpen,
24562479
SideEffects: &sideEffectsNone,
24572480
AdmissionReviewVersions: []string{"v1", "v1beta1"},
24582481
// Scope the webhook to just the markers namespace
@@ -2470,6 +2493,7 @@ func newValidatingIsReadyWebhookFixture(f *framework.Framework, context *certCon
24702493
// with "marker" requests via waitWebhookConfigurationReady to wait for a webhook configuration to be ready.
24712494
func newMutatingIsReadyWebhookFixture(f *framework.Framework, context *certContext, servicePort int32) admissionregistrationv1.MutatingWebhook {
24722495
sideEffectsNone := admissionregistrationv1.SideEffectClassNone
2496+
failOpen := admissionregistrationv1.Ignore
24732497
return admissionregistrationv1.MutatingWebhook{
24742498
Name: "mutating-is-webhook-configuration-ready.k8s.io",
24752499
Rules: []admissionregistrationv1.RuleWithOperations{{
@@ -2489,6 +2513,8 @@ func newMutatingIsReadyWebhookFixture(f *framework.Framework, context *certConte
24892513
},
24902514
CABundle: context.signingCert,
24912515
},
2516+
// network failures while the service network routing is being set up should be ignored by the marker
2517+
FailurePolicy: &failOpen,
24922518
SideEffects: &sideEffectsNone,
24932519
AdmissionReviewVersions: []string{"v1", "v1beta1"},
24942520
// Scope the webhook to just the markers namespace

test/utils/image/manifest.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ const (
204204

205205
func initImageConfigs() map[int]Config {
206206
configs := map[int]Config{}
207-
configs[Agnhost] = Config{e2eRegistry, "agnhost", "2.5"}
207+
configs[Agnhost] = Config{e2eRegistry, "agnhost", "2.6"}
208208
configs[Alpine] = Config{dockerLibraryRegistry, "alpine", "3.7"}
209209
configs[AuthenticatedAlpine] = Config{gcAuthenticatedRegistry, "alpine", "3.7"}
210210
configs[AuthenticatedWindowsNanoServer] = Config{gcAuthenticatedRegistry, "windows-nanoserver", "v1"}

0 commit comments

Comments
 (0)