Skip to content

Commit

Permalink
ClusterResourceSet cache full secret objects to get type info in pred…
Browse files Browse the repository at this point in the history
…icates
  • Loading branch information
Sedef committed Jun 4, 2021
1 parent 61e63e0 commit c959331
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 3 deletions.
1 change: 0 additions & 1 deletion exp/addons/controllers/clusterresourceset_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ func (r *ClusterResourceSetReconciler) SetupWithManager(ctx context.Context, mgr
Watches(
&source.Kind{Type: &corev1.Secret{}},
handler.EnqueueRequestsFromMapFunc(r.resourceToClusterResourceSet),
builder.OnlyMetadata,
builder.WithPredicates(
resourcepredicates.AddonsSecretCreate(ctrl.LoggerFrom(ctx)),
),
Expand Down
108 changes: 106 additions & 2 deletions exp/addons/controllers/clusterresourceset_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import (
)

const (
timeout = time.Second * 20
timeout = time.Second * 5
defaultNamespaceName = "default"
)

Expand Down Expand Up @@ -255,7 +255,7 @@ metadata:
}, timeout).Should(BeTrue())
})

t.Run("Should reconcile a ClusterResourceSet when a resource is created that is part of ClusterResourceSet resources", func(t *testing.T) {
t.Run("Should reconcile a ClusterResourceSet when a ConfigMap resource is created that is part of ClusterResourceSet resources", func(t *testing.T) {
g := NewWithT(t)
setup(t, g)
defer teardown(t, g)
Expand Down Expand Up @@ -306,6 +306,10 @@ metadata:
return false
}, timeout).Should(BeTrue())

// Must sleep here to make sure resource is created after the previous reconcile.
// If the resource is created in between, predicates are not used as intended in this test.
time.Sleep(2 * time.Second)

newConfigmap := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: newCMName,
Expand Down Expand Up @@ -350,6 +354,106 @@ metadata:
}, timeout).Should(BeTrue())
})

t.Run("Should reconcile a ClusterResourceSet when a Secret resource is created that is part of ClusterResourceSet resources", func(t *testing.T) {
g := NewWithT(t)
setup(t, g)
defer teardown(t, g)

newSecretName := fmt.Sprintf("test-secret-%s", util.RandomString(6))

crsInstance := &addonsv1.ClusterResourceSet{
ObjectMeta: metav1.ObjectMeta{
Name: clusterResourceSetName,
Namespace: defaultNamespaceName,
},
Spec: addonsv1.ClusterResourceSetSpec{
ClusterSelector: metav1.LabelSelector{
MatchLabels: labels,
},
Resources: []addonsv1.ResourceRef{{Name: newSecretName, Kind: "Secret"}},
},
}
// Create the ClusterResourceSet.
g.Expect(env.Create(ctx, crsInstance)).To(Succeed())

testCluster.SetLabels(labels)
g.Expect(env.Update(ctx, testCluster)).To(Succeed())

// Must sleep here to make sure resource is created after the previous reconcile.
// If the resource is created in between, predicates are not used as intended in this test.
time.Sleep(2 * time.Second)

t.Log("Verifying ClusterResourceSetBinding is created with cluster owner reference")
// Wait until ClusterResourceSetBinding is created for the Cluster
clusterResourceSetBindingKey := client.ObjectKey{
Namespace: testCluster.Namespace,
Name: testCluster.Name,
}
g.Eventually(func() bool {
binding := &addonsv1.ClusterResourceSetBinding{}

err := env.Get(ctx, clusterResourceSetBindingKey, binding)
return err == nil
}, timeout).Should(BeTrue())

// Initially Secret is missing, so no resources in the binding.
g.Eventually(func() bool {
binding := &addonsv1.ClusterResourceSetBinding{}

err := env.Get(ctx, clusterResourceSetBindingKey, binding)
if err == nil {
if len(binding.Spec.Bindings) > 0 && len(binding.Spec.Bindings[0].Resources) == 0 {
return true
}
}
return false
}, timeout).Should(BeTrue())

newSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: newSecretName,
Namespace: defaultNamespaceName,
},
Type: addonsv1.ClusterResourceSetSecretType,
Data: map[string][]byte{},
}
g.Expect(env.Create(ctx, newSecret)).To(Succeed())
defer func() {
g.Expect(env.Delete(ctx, newSecret)).To(Succeed())
}()

cmKey := client.ObjectKey{
Namespace: defaultNamespaceName,
Name: newSecretName,
}
g.Eventually(func() bool {
m := &corev1.Secret{}
err := env.Get(ctx, cmKey, m)
return err == nil
}, timeout).Should(BeTrue())

// When the Secret resource is created, CRS should get reconciled immediately.
g.Eventually(func() error {
binding := &addonsv1.ClusterResourceSetBinding{}
if err := env.Get(ctx, clusterResourceSetBindingKey, binding); err != nil {
return err
}
if len(binding.Spec.Bindings[0].Resources) > 0 && binding.Spec.Bindings[0].Resources[0].Name == newSecretName {
return nil
}
return errors.Errorf("ClusterResourceSet binding does not have any resources matching %q: %v", newSecretName, binding.Spec.Bindings)
}, timeout).Should(Succeed())

t.Log("Verifying ClusterResourceSetBinding is deleted when its cluster owner reference is deleted")
g.Expect(env.Delete(ctx, testCluster)).To(Succeed())

g.Eventually(func() bool {
binding := &addonsv1.ClusterResourceSetBinding{}
err := env.Get(ctx, clusterResourceSetBindingKey, binding)
return apierrors.IsNotFound(err)
}, timeout).Should(BeTrue())
})

t.Run("Should delete ClusterResourceSet from the bindings list when ClusterResourceSet is deleted", func(t *testing.T) {
g := NewWithT(t)
setup(t, g)
Expand Down

0 comments on commit c959331

Please sign in to comment.