Skip to content

Commit b0be1ae

Browse files
committed
e2e: added checks for logicalcluster annotation for in-review objs in admission webhooks
On-behalf-of: @SAP robert.vasek@sap.com Signed-off-by: Robert Vasek <robert.vasek@clyso.com>
1 parent 8a0d242 commit b0be1ae

File tree

2 files changed

+29
-20
lines changed

2 files changed

+29
-20
lines changed

test/e2e/apibinding/apibinding_webhook_test.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"fmt"
2323
gohttp "net/http"
2424
"path/filepath"
25+
"sync/atomic"
2526
"testing"
2627
"time"
2728

@@ -65,7 +66,7 @@ func TestAPIBindingMutatingWebhook(t *testing.T) {
6566

6667
orgPath, _ := framework.NewOrganizationFixture(t, server) //nolint:staticcheck // TODO: switch to NewWorkspaceFixture.
6768
sourcePath, _ := kcptesting.NewWorkspaceFixture(t, server, orgPath)
68-
targetPath, _ := kcptesting.NewWorkspaceFixture(t, server, orgPath)
69+
targetPath, targetWS := kcptesting.NewWorkspaceFixture(t, server, orgPath)
6970

7071
cfg := server.BaseConfig(t)
7172

@@ -141,10 +142,12 @@ func TestAPIBindingMutatingWebhook(t *testing.T) {
141142
deserializer := codecs.UniversalDeserializer()
142143

143144
t.Logf("Create test server and create mutating webhook for cowboys in both source and target cluster")
145+
var clusterInReviewObject atomic.Value
144146
testWebhooks := map[logicalcluster.Path]*webhookserver.AdmissionWebhookServer{}
145147
for _, cluster := range []logicalcluster.Path{sourcePath, targetPath} {
146148
testWebhooks[cluster] = &webhookserver.AdmissionWebhookServer{
147-
ResponseFn: func(review *admissionv1.AdmissionReview) (*admissionv1.AdmissionResponse, error) {
149+
ResponseFn: func(obj runtime.Object, review *admissionv1.AdmissionReview) (*admissionv1.AdmissionResponse, error) {
150+
clusterInReviewObject.Store(logicalcluster.From(obj.(*v1alpha1.Cowboy)).String())
148151
return &admissionv1.AdmissionResponse{Allowed: true}, nil
149152
},
150153
ObjectGVK: schema.GroupVersionKind{
@@ -208,6 +211,9 @@ func TestAPIBindingMutatingWebhook(t *testing.T) {
208211

209212
t.Logf("Check that the in-workspace webhook was NOT called")
210213
require.Zero(t, testWebhooks[targetPath].Calls(), "in-workspace webhook should not have been called")
214+
215+
t.Logf("Check that the logicalcluster annotation on the object that triggered webhook is matching the target cluster")
216+
require.Equal(t, targetWS.Spec.Cluster, clusterInReviewObject.Load(), "expected that the object passed to the webhook has correct kcp.io/cluster annotation set")
211217
}
212218

213219
func TestAPIBindingValidatingWebhook(t *testing.T) {
@@ -221,7 +227,7 @@ func TestAPIBindingValidatingWebhook(t *testing.T) {
221227

222228
orgPath, _ := framework.NewOrganizationFixture(t, server) //nolint:staticcheck // TODO: switch to NewWorkspaceFixture.
223229
sourcePath, _ := kcptesting.NewWorkspaceFixture(t, server, orgPath)
224-
targetPath, _ := kcptesting.NewWorkspaceFixture(t, server, orgPath)
230+
targetPath, targetWS := kcptesting.NewWorkspaceFixture(t, server, orgPath)
225231

226232
cfg := server.BaseConfig(t)
227233

@@ -298,9 +304,11 @@ func TestAPIBindingValidatingWebhook(t *testing.T) {
298304

299305
t.Logf("Create test server and create validating webhook for cowboys in both source and target cluster")
300306
testWebhooks := map[logicalcluster.Path]*webhookserver.AdmissionWebhookServer{}
307+
var clusterInReviewObject atomic.Value
301308
for _, cluster := range []logicalcluster.Path{sourcePath, targetPath} {
302309
testWebhooks[cluster] = &webhookserver.AdmissionWebhookServer{
303-
ResponseFn: func(review *admissionv1.AdmissionReview) (*admissionv1.AdmissionResponse, error) {
310+
ResponseFn: func(obj runtime.Object, review *admissionv1.AdmissionReview) (*admissionv1.AdmissionResponse, error) {
311+
clusterInReviewObject.Store(logicalcluster.From(obj.(*v1alpha1.Cowboy)).String())
304312
return &admissionv1.AdmissionResponse{Allowed: true}, nil
305313
},
306314
ObjectGVK: schema.GroupVersionKind{
@@ -376,4 +384,7 @@ func TestAPIBindingValidatingWebhook(t *testing.T) {
376384

377385
t.Logf("Check that the in-workspace webhook was NOT called")
378386
require.Zero(t, testWebhooks[targetPath].Calls(), "in-workspace webhook should not have been called")
387+
388+
t.Logf("Check that the logicalcluster annotation on the object that triggered webhook is matching the target cluster")
389+
require.Equal(t, targetWS.Spec.Cluster, clusterInReviewObject.Load(), "expected that the object passed to the webhook has correct kcp.io/cluster annotation set")
379390
}

test/e2e/conformance/webhook_test.go

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package conformance
1818

1919
import (
2020
"context"
21-
"encoding/json"
2221
"path/filepath"
2322
"sync/atomic"
2423
"testing"
@@ -30,7 +29,6 @@ import (
3029
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
3130
"k8s.io/apimachinery/pkg/api/errors"
3231
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
33-
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3432
"k8s.io/apimachinery/pkg/runtime"
3533
"k8s.io/apimachinery/pkg/runtime/schema"
3634
"k8s.io/apimachinery/pkg/runtime/serializer"
@@ -75,12 +73,8 @@ func TestMutatingWebhookInWorkspace(t *testing.T) {
7573

7674
var clusterInReviewObject atomic.Value
7775
testWebhook := webhookserver.AdmissionWebhookServer{
78-
ResponseFn: func(review *v1.AdmissionReview) (*v1.AdmissionResponse, error) {
79-
var u unstructured.Unstructured
80-
if err := json.Unmarshal(review.Request.Object.Raw, &u.Object); err != nil {
81-
return nil, err
82-
}
83-
clusterInReviewObject.Store(logicalcluster.From(&u).String())
76+
ResponseFn: func(obj runtime.Object, review *v1.AdmissionReview) (*v1.AdmissionResponse, error) {
77+
clusterInReviewObject.Store(logicalcluster.From(obj.(*v1alpha1.Cowboy)).String())
8478
return &v1.AdmissionResponse{Allowed: true}, nil
8579
},
8680
ObjectGVK: schema.GroupVersionKind{
@@ -197,8 +191,10 @@ func TestValidatingWebhookInWorkspace(t *testing.T) {
197191
codecs := serializer.NewCodecFactory(scheme)
198192
deserializer := codecs.UniversalDeserializer()
199193

194+
var clusterInReviewObject atomic.Value
200195
testWebhook := webhookserver.AdmissionWebhookServer{
201-
ResponseFn: func(review *v1.AdmissionReview) (*v1.AdmissionResponse, error) {
196+
ResponseFn: func(obj runtime.Object, review *v1.AdmissionReview) (*v1.AdmissionResponse, error) {
197+
clusterInReviewObject.Store(logicalcluster.From(obj.(*v1alpha1.Cowboy)).String())
202198
return &v1.AdmissionResponse{Allowed: true}, nil
203199
},
204200
ObjectGVK: schema.GroupVersionKind{
@@ -215,9 +211,10 @@ func TestValidatingWebhookInWorkspace(t *testing.T) {
215211
testWebhook.StartTLS(t, filepath.Join(dirPath, "apiserver.crt"), filepath.Join(dirPath, "apiserver.key"), port)
216212

217213
orgPath, _ := framework.NewOrganizationFixture(t, server) //nolint:staticcheck // TODO: switch to NewWorkspaceFixture.
218-
ws1, _ := kcptesting.NewWorkspaceFixture(t, server, orgPath)
219-
ws2, _ := kcptesting.NewWorkspaceFixture(t, server, orgPath)
220-
workspaces := []logicalcluster.Path{ws1, ws2}
214+
ws1Path, ws1 := kcptesting.NewWorkspaceFixture(t, server, orgPath)
215+
ws2Path, ws2 := kcptesting.NewWorkspaceFixture(t, server, orgPath)
216+
paths := []logicalcluster.Path{ws1Path, ws2Path}
217+
workspaces := []*tenancyv1alpha1.Workspace{ws1, ws2}
221218

222219
kubeClusterClient, err := kcpkubernetesclientset.NewForConfig(cfg)
223220
require.NoError(t, err, "failed to construct client for server")
@@ -227,7 +224,7 @@ func TestValidatingWebhookInWorkspace(t *testing.T) {
227224
require.NoError(t, err, "failed to construct apiextensions client for server")
228225

229226
t.Logf("Install the Cowboy resources into logical clusters")
230-
for _, wsPath := range workspaces {
227+
for _, wsPath := range paths {
231228
t.Logf("Bootstrapping Workspace CRDs in logical cluster %s", wsPath)
232229
crdClient := apiExtensionsClients.ApiextensionsV1().CustomResourceDefinitions()
233230
wildwest.Create(t, wsPath, crdClient, metav1.GroupResource{Group: "wildwest.dev", Resource: "cowboys"})
@@ -259,7 +256,7 @@ func TestValidatingWebhookInWorkspace(t *testing.T) {
259256
AdmissionReviewVersions: []string{"v1"},
260257
}},
261258
}
262-
_, err = kubeClusterClient.Cluster(workspaces[0]).AdmissionregistrationV1().ValidatingWebhookConfigurations().Create(ctx, webhook, metav1.CreateOptions{})
259+
_, err = kubeClusterClient.Cluster(paths[0]).AdmissionregistrationV1().ValidatingWebhookConfigurations().Create(ctx, webhook, metav1.CreateOptions{})
263260
require.NoError(t, err, "failed to add validating webhook configurations")
264261

265262
cowboy := v1alpha1.Cowboy{
@@ -271,16 +268,17 @@ func TestValidatingWebhookInWorkspace(t *testing.T) {
271268

272269
t.Logf("Creating cowboy resource in first logical cluster")
273270
require.Eventually(t, func() bool {
274-
_, err = cowbyClusterClient.Cluster(workspaces[0]).WildwestV1alpha1().Cowboys("default").Create(ctx, &cowboy, metav1.CreateOptions{})
271+
_, err = cowbyClusterClient.Cluster(paths[0]).WildwestV1alpha1().Cowboys("default").Create(ctx, &cowboy, metav1.CreateOptions{})
275272
if err != nil && !errors.IsAlreadyExists(err) {
276273
return false
277274
}
278275
return testWebhook.Calls() == 1
279276
}, wait.ForeverTestTimeout, 100*time.Millisecond)
277+
require.Equal(t, workspaces[0].Spec.Cluster, clusterInReviewObject.Load(), "expected that the object passed to the webhook has the kcp.io/cluster annotation set")
280278

281279
// Avoid race condition here by making sure that CRD is served after installing the types into logical clusters
282280
t.Logf("Creating cowboy resource in second logical cluster")
283-
_, err = cowbyClusterClient.Cluster(workspaces[1]).WildwestV1alpha1().Cowboys("default").Create(ctx, &cowboy, metav1.CreateOptions{})
281+
_, err = cowbyClusterClient.Cluster(paths[1]).WildwestV1alpha1().Cowboys("default").Create(ctx, &cowboy, metav1.CreateOptions{})
284282
require.NoError(t, err, "failed to create cowboy resource in second logical cluster")
285283
require.Equal(t, 1, testWebhook.Calls(), "expected that the webhook is not called for logical cluster where webhook is not installed")
286284
}

0 commit comments

Comments
 (0)