Skip to content

Commit fa35d43

Browse files
committed
add tests
1 parent 5695b27 commit fa35d43

2 files changed

Lines changed: 165 additions & 11 deletions

File tree

kcp/README.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,13 @@ kubectl ws create consumer --enter
9999
10. Bind the thing:
100100

101101
```bash
102-
./bin/kubectl-bind http://127.0.0.1:8080/clusters/36note1hch913ryv/exports --dry-run -o yaml > apiserviceexport.yaml
102+
./bin/kubectl-bind http://127.0.0.1:8080/clusters/12jj50d1t39g65d6/exports --dry-run -o yaml > apiserviceexport.yaml
103103

104104
# Extract secret for binding process. Note that secret name is not the same as output from command above. Check secret
105105
# name by running `kubectl get secret -n kube-bind`
106-
kubectl get secret kubeconfig-bpmvf -n kube-bind -o jsonpath='{.data.kubeconfig}' | base64 -d > remote.kubeconfig
106+
kubectl get secret kubeconfig-shj8k -n kube-bind -o jsonpath='{.data.kubeconfig}' | base64 -d > remote.kubeconfig
107107

108-
./bin/kubectl-bind apiservice --remote-kubeconfig remote.kubeconfig -f kcp/deploy/examples/apiserviceexport.yaml --skip-konnector --remote-namespace kube-bind-qsps8
108+
./bin/kubectl-bind apiservice --remote-kubeconfig remote.kubeconfig -f kcp/deploy/examples/apiserviceexport.yaml --skip-konnector --remote-namespace kube-bind-lxj5k
109109

110110
export KUBECONFIG=.kcp/consumer.kubeconfig
111111
go run ./cmd/konnector/ --lease-namespace default
@@ -126,9 +126,11 @@ export KUBECONFIG=.kcp/debug.kubeconfig
126126
k ws use :root:kube-bind
127127

128128
k -s "$(kubectl get apiexportendpointslice kube-bind.io -o jsonpath="{.status.endpoints[0].url}")/clusters/*" api-resources
129-
k -s "$(kubectl get apiexportendpointslice kube-bind.io -o jsonpath="{.status.endpoints[0].url}")/clusters/*" get crd
129+
k -s "$(kubectl get apiexportendpointslice kube-bind.io -o §®jsonpath="{.status.endpoints[0].url}")/clusters/*" get crd
130130

131131
# some claimed objects
132-
kubectl create cm provider -n kube-bind-qsps8-default
133-
kubectl label cm provider app=wildwest -n kube-bind-qsps8-default
134-
```
132+
kubectl create cm provider -n kube-bind-lxj5k-default
133+
kubectl label cm provider app=wildwest -n kube-bind-lxj5k-default
134+
135+
kubectl create cm consumer -n default
136+
kubectl label cm consumer app=wildwest -n default

test/e2e/bind/happy-case_test.go

Lines changed: 156 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ package bind
1818

1919
import (
2020
"context"
21+
"encoding/json"
2122
"fmt"
2223
"strings"
2324
"testing"
2425
"time"
2526

2627
"github.com/stretchr/testify/require"
2728
"gopkg.in/headzoo/surf.v1"
29+
corev1 "k8s.io/api/core/v1"
2830
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
2931
"k8s.io/apimachinery/pkg/api/errors"
3032
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -44,18 +46,23 @@ import (
4446
func TestClusterScoped(t *testing.T) {
4547
t.Parallel()
4648
// cluster scoped resource, with cluster scoped informers
47-
testHappyCase(t, apiextensionsv1.ClusterScoped, kubebindv1alpha2.ClusterScope)
49+
testHappyCase(t, apiextensionsv1.ClusterScoped, kubebindv1alpha2.ClusterScope, false)
4850
}
4951

5052
func TestNamespacedScoped(t *testing.T) {
5153
t.Parallel()
5254
// namespaced resource, with namespace scoped informers
53-
testHappyCase(t, apiextensionsv1.NamespaceScoped, kubebindv1alpha2.NamespacedScope)
55+
testHappyCase(t, apiextensionsv1.NamespaceScoped, kubebindv1alpha2.NamespacedScope, false)
5456
// namespaced resource, but with cluster scoped informers
55-
testHappyCase(t, apiextensionsv1.NamespaceScoped, kubebindv1alpha2.ClusterScope)
57+
testHappyCase(t, apiextensionsv1.NamespaceScoped, kubebindv1alpha2.ClusterScope, true)
5658
}
5759

58-
func testHappyCase(t *testing.T, resourceScope apiextensionsv1.ResourceScope, informerScope kubebindv1alpha2.InformerScope) {
60+
func testHappyCase(
61+
t *testing.T,
62+
resourceScope apiextensionsv1.ResourceScope,
63+
informerScope kubebindv1alpha2.InformerScope,
64+
withPermissionClaims bool,
65+
) {
5966
ctx, cancel := context.WithCancel(context.Background())
6067
t.Cleanup(cancel)
6168

@@ -80,6 +87,9 @@ func testHappyCase(t *testing.T, resourceScope apiextensionsv1.ResourceScope, in
8087
consumerClient := framework.DynamicClient(t, consumerConfig).Resource(serviceGVR)
8188
providerClient := framework.DynamicClient(t, providerConfig).Resource(serviceGVR)
8289

90+
consumerCoreClient := framework.KubeClient(t, consumerConfig).CoreV1()
91+
providerCoreClient := framework.KubeClient(t, providerConfig).CoreV1()
92+
8393
mangodbInstance := `
8494
apiVersion: mangodb.com/v1alpha1
8595
kind: MangoDB
@@ -125,6 +135,45 @@ spec:
125135
framework.Bind(t, iostreams, authURLCh, invocations, fmt.Sprintf("http://%s/exports", addr.String()), "--kubeconfig", consumerKubeconfig, "--skip-konnector")
126136
inv := <-invocations
127137
requireEqualSlicePattern(t, []string{"apiservice", "--remote-kubeconfig-namespace", "*", "--remote-kubeconfig-name", "*", "-f", "-", "--kubeconfig=" + consumerKubeconfig, "--skip-konnector=true", "--no-banner"}, inv.Args)
138+
139+
// If we are in permissions claims mode - add configmaps & secrets
140+
if withPermissionClaims {
141+
var request kubebindv1alpha2.APIServiceExportRequest
142+
err := json.Unmarshal(inv.Stdin, &request)
143+
require.NoError(t, err)
144+
request.Spec.PermissionClaims = []kubebindv1alpha2.PermissionClaim{
145+
{
146+
GroupResource: kubebindv1alpha2.GroupResource{
147+
Group: "",
148+
Resource: "configmaps",
149+
},
150+
Selector: kubebindv1alpha2.Selector{
151+
LabelSelector: &metav1.LabelSelector{
152+
MatchLabels: map[string]string{
153+
"app": "configmaps",
154+
},
155+
},
156+
},
157+
},
158+
{
159+
GroupResource: kubebindv1alpha2.GroupResource{
160+
Group: "",
161+
Resource: "secrets",
162+
},
163+
Selector: kubebindv1alpha2.Selector{
164+
LabelSelector: &metav1.LabelSelector{
165+
MatchLabels: map[string]string{
166+
"app": "secrets",
167+
},
168+
},
169+
},
170+
},
171+
}
172+
payload, err := json.Marshal(request)
173+
require.NoError(t, err)
174+
inv.Stdin = payload
175+
}
176+
128177
framework.BindAPIService(t, inv.Stdin, "", inv.Args...)
129178

130179
t.Logf("Waiting for %s CRD to be created on consumer side", serviceGVR.Resource)
@@ -166,6 +215,109 @@ spec:
166215
}
167216
},
168217
},
218+
{
219+
name: "create secrets and configmaps if permission claims enabled",
220+
step: func(t *testing.T) {
221+
if !withPermissionClaims {
222+
t.Skip("Skipping permission claims test when permission claims are disabled")
223+
return
224+
}
225+
226+
t.Logf("Creating configmap on consumer side")
227+
configMapData := map[string]string{
228+
"config.yaml": "test: value",
229+
}
230+
configMap := &corev1.ConfigMap{
231+
ObjectMeta: metav1.ObjectMeta{
232+
Name: "test-configmap",
233+
Namespace: downstreamNs,
234+
Labels: map[string]string{
235+
"app": "configmaps",
236+
},
237+
},
238+
Data: configMapData,
239+
}
240+
_, err := consumerCoreClient.ConfigMaps(downstreamNs).Create(ctx, configMap, metav1.CreateOptions{})
241+
require.NoError(t, err)
242+
243+
t.Logf("Creating secret on consumer side")
244+
secretData := map[string][]byte{
245+
"password": []byte("secret-password"),
246+
}
247+
secret := &corev1.Secret{
248+
ObjectMeta: metav1.ObjectMeta{
249+
Name: "test-secret",
250+
Namespace: downstreamNs,
251+
Labels: map[string]string{
252+
"app": "secrets",
253+
},
254+
},
255+
Data: secretData,
256+
}
257+
_, err = consumerCoreClient.Secrets(downstreamNs).Create(ctx, secret, metav1.CreateOptions{})
258+
require.NoError(t, err)
259+
},
260+
},
261+
{
262+
name: "verify secrets and configmaps are synced to provider",
263+
step: func(t *testing.T) {
264+
if !withPermissionClaims {
265+
t.Skip("Skipping permission claims test when permission claims are disabled")
266+
return
267+
}
268+
269+
t.Logf("Waiting for configmap to be synced to provider side")
270+
require.Eventually(t, func() bool {
271+
_, err := providerCoreClient.ConfigMaps(upstreamNS).Get(ctx, "test-configmap", metav1.GetOptions{})
272+
return err == nil
273+
}, wait.ForeverTestTimeout, time.Millisecond*100, "waiting for configmap to be synced to provider side")
274+
275+
t.Logf("Waiting for secret to be synced to provider side")
276+
require.Eventually(t, func() bool {
277+
_, err := providerCoreClient.Secrets(upstreamNS).Get(ctx, "test-secret", metav1.GetOptions{})
278+
return err == nil
279+
}, wait.ForeverTestTimeout, time.Millisecond*100, "waiting for secret to be synced to provider side")
280+
281+
t.Logf("Verifying configmap data is correct")
282+
providerConfigMap, err := providerCoreClient.ConfigMaps(upstreamNS).Get(ctx, "test-configmap", metav1.GetOptions{})
283+
require.NoError(t, err)
284+
require.Equal(t, "test: value", providerConfigMap.Data["config.yaml"])
285+
286+
t.Logf("Verifying secret data is correct")
287+
providerSecret, err := providerCoreClient.Secrets(upstreamNS).Get(ctx, "test-secret", metav1.GetOptions{})
288+
require.NoError(t, err)
289+
require.Equal(t, []byte("secret-password"), providerSecret.Data["password"])
290+
},
291+
},
292+
{
293+
name: "verify secrets and configmaps are deleted when removed from consumer",
294+
step: func(t *testing.T) {
295+
if !withPermissionClaims {
296+
t.Skip("Skipping permission claims test when permission claims are disabled")
297+
return
298+
}
299+
300+
t.Logf("Deleting configmap from consumer side")
301+
err := consumerCoreClient.ConfigMaps(downstreamNs).Delete(ctx, "test-configmap", metav1.DeleteOptions{})
302+
require.NoError(t, err)
303+
304+
t.Logf("Deleting secret from consumer side")
305+
err = consumerCoreClient.Secrets(downstreamNs).Delete(ctx, "test-secret", metav1.DeleteOptions{})
306+
require.NoError(t, err)
307+
308+
t.Logf("Waiting for configmap to be deleted from provider side")
309+
require.Eventually(t, func() bool {
310+
_, err := providerCoreClient.ConfigMaps(upstreamNS).Get(ctx, "test-configmap", metav1.GetOptions{})
311+
return errors.IsNotFound(err)
312+
}, wait.ForeverTestTimeout, time.Millisecond*100, "waiting for configmap to be deleted from provider side")
313+
314+
t.Logf("Waiting for secret to be deleted from provider side")
315+
require.Eventually(t, func() bool {
316+
_, err := providerCoreClient.Secrets(upstreamNS).Get(ctx, "test-secret", metav1.GetOptions{})
317+
return errors.IsNotFound(err)
318+
}, wait.ForeverTestTimeout, time.Millisecond*100, "waiting for secret to be deleted from provider side")
319+
},
320+
},
169321
{
170322
name: "instance deleted upstream is recreated",
171323
step: func(t *testing.T) {

0 commit comments

Comments
 (0)