@@ -18,13 +18,15 @@ package bind
1818
1919import (
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 (
4446func 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
5052func 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 := `
8494apiVersion: mangodb.com/v1alpha1
8595kind: 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