Skip to content

Commit

Permalink
fix: add ownerrefs to bundle objects; add e2e test for bundle object gc
Browse files Browse the repository at this point in the history
  • Loading branch information
exdx committed May 14, 2020
1 parent 34d6563 commit 362fcff
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 2 deletions.
25 changes: 25 additions & 0 deletions pkg/controller/operators/catalog/operator.go
Expand Up @@ -1509,6 +1509,23 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
if err != nil {
return errorwrap.Wrapf(err, "error parsing step manifest: %s", step.Resource.Name)
}

// add ownerrefs on the secret that point to the CSV in the bundle
if step.Resolving != "" {
owner := &v1alpha1.ClusterServiceVersion{}
owner.SetNamespace(plan.GetNamespace())
owner.SetName(step.Resolving)
ownerutil.AddNonBlockingOwner(&s, owner)
}

// Update UIDs on all CSV OwnerReferences
updated, err := o.getUpdatedOwnerReferences(s.OwnerReferences, plan.Namespace)
if err != nil {
return errorwrap.Wrapf(err, "error generating ownerrefs for secret %s", s.GetName())
}
s.SetOwnerReferences(updated)
s.SetNamespace(namespace)

status, err := ensurer.EnsureBundleSecret(plan.Namespace, &s)
if err != nil {
return err
Expand Down Expand Up @@ -1653,6 +1670,14 @@ func (o *Operator) ExecutePlan(plan *v1alpha1.InstallPlan) error {
return errorwrap.Wrapf(err, "error parsing step manifest: %s", step.Resource.Name)
}

// add ownerrefs on the configmap that point to the CSV in the bundle
if step.Resolving != "" {
owner := &v1alpha1.ClusterServiceVersion{}
owner.SetNamespace(plan.GetNamespace())
owner.SetName(step.Resolving)
ownerutil.AddNonBlockingOwner(&cfg, owner)
}

// Update UIDs on all CSV OwnerReferences
updated, err := o.getUpdatedOwnerReferences(cfg.OwnerReferences, plan.Namespace)
if err != nil {
Expand Down
12 changes: 12 additions & 0 deletions pkg/lib/ownerutil/util.go
Expand Up @@ -314,6 +314,18 @@ func InferGroupVersionKind(obj runtime.Object) error {
Version: "v1",
Kind: "ServiceAccount",
})
case *corev1.ConfigMap:
objectKind.SetGroupVersionKind(schema.GroupVersionKind{
Group: "",
Version: "v1",
Kind: "ConfigMap",
})
case *corev1.Secret:
objectKind.SetGroupVersionKind(schema.GroupVersionKind{
Group: "",
Version: "v1",
Kind: "Secret",
})
case *rbac.ClusterRole:
objectKind.SetGroupVersionKind(schema.GroupVersionKind{
Group: "rbac.authorization.k8s.io",
Expand Down
101 changes: 99 additions & 2 deletions test/e2e/gc_e2e_test.go
Expand Up @@ -3,11 +3,11 @@ package e2e
import (
"context"
"fmt"
"github.com/operator-framework/api/pkg/operators/v1alpha1"

"github.com/blang/semver"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/operator-framework/operator-lifecycle-manager/test/e2e/dsl"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
Expand All @@ -16,11 +16,11 @@ import (
"k8s.io/apimachinery/pkg/util/rand"
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"

"github.com/operator-framework/api/pkg/operators/v1alpha1"
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
"github.com/operator-framework/operator-lifecycle-manager/test/e2e/ctx"
. "github.com/operator-framework/operator-lifecycle-manager/test/e2e/dsl"
)

var _ = Describe("Garbage collection for dependent resources", func() {
Expand Down Expand Up @@ -284,4 +284,101 @@ var _ = Describe("Garbage collection for dependent resources", func() {

})

Context("When installing a bundle with configmap and secret objects these objects should be deleted when the CSV is deleted", func() {
const (
sourceName = "test-catalog"
imageName = "quay.io/olmtest/single-bundle-index:objects"
packageName = "busybox"
channelName = "alpha"
subName = "test-subscription"
csvName = "busybox.v2.0.0"
secretName = "mysecret"
configmapName = "special-config"
)

var (
source *v1alpha1.CatalogSource
err error
)

BeforeEach(func() {
// create catalog source
source = &v1alpha1.CatalogSource{
TypeMeta: metav1.TypeMeta{
Kind: v1alpha1.CatalogSourceKind,
APIVersion: v1alpha1.CatalogSourceCRDAPIVersion,
},
ObjectMeta: metav1.ObjectMeta{
Name: sourceName,
Namespace: testNamespace,
Labels: map[string]string{"olm.catalogSource": sourceName},
},
Spec: v1alpha1.CatalogSourceSpec{
SourceType: v1alpha1.SourceTypeGrpc,
Image: imageName,
},
}

source, err = operatorClient.OperatorsV1alpha1().CatalogSources(source.GetNamespace()).Create(context.TODO(), source, metav1.CreateOptions{})
Expect(err).ToNot(HaveOccurred(), "could not create catalog source")

// Create a Subscription for package
_ = createSubscriptionForCatalog(operatorClient, source.GetNamespace(), subName, source.GetName(), packageName, channelName, "", v1alpha1.ApprovalAutomatic)

// Wait for the Subscription to succeed
Eventually(func() error {
_, err = fetchSubscription(operatorClient, testNamespace, subName, subscriptionStateAtLatestChecker)
return err
}).Should(BeNil())

// confirm extra bundle objects (secret and configmap) are installed
Eventually(func() bool {
_, err := kubeClient.GetSecret(testNamespace, secretName)
return k8serrors.IsNotFound(err)
}).Should(BeFalse())

Eventually(func() bool {
_, err := kubeClient.GetConfigMap(testNamespace, configmapName)
return k8serrors.IsNotFound(err)
}).Should(BeFalse())
})

When("CSV is deleted", func() {
BeforeEach(func() {
// Delete subscription first
err = operatorClient.OperatorsV1alpha1().Subscriptions(testNamespace).Delete(context.TODO(), subName, metav1.DeleteOptions{})
Expect(err).To(BeNil())

// wait for deletion
Eventually(func() bool {
_, err := operatorClient.OperatorsV1alpha1().Subscriptions(testNamespace).Get(context.TODO(), subName, metav1.GetOptions{})
return k8serrors.IsNotFound(err)
}).Should(BeTrue())

// Delete CSV
err = operatorClient.OperatorsV1alpha1().ClusterServiceVersions(testNamespace).Delete(context.TODO(), csvName, metav1.DeleteOptions{})
Expect(err).To(BeNil())

// wait for deletion
Eventually(func() bool {
_, err := operatorClient.OperatorsV1alpha1().ClusterServiceVersions(testNamespace).Get(context.TODO(), csvName, metav1.GetOptions{})
return k8serrors.IsNotFound(err)
}).Should(BeTrue())
})

It("should delete the associated configmap and secret - they are not found in the CSV namespace", func() {
// confirm extra bundle objects (secret and configmap) are no longer installed on the cluster
Eventually(func() bool {
_, err := kubeClient.GetSecret(testNamespace, secretName)
return k8serrors.IsNotFound(err)
}).Should(BeTrue())

Eventually(func() bool {
_, err := kubeClient.GetConfigMap(testNamespace, configmapName)
return k8serrors.IsNotFound(err)
}).Should(BeTrue())
ctx.Ctx().Logf("dependent successfully garbage collected after csv owner was deleted")
})
})
})
})

0 comments on commit 362fcff

Please sign in to comment.