Skip to content

Commit

Permalink
[BOP-1488] Don't remove non-BOP resources (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
byDimasik authored Nov 15, 2024
1 parent eeced5d commit 7de6986
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 14 deletions.
19 changes: 11 additions & 8 deletions controllers/blueprint_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/selection"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"

blueprintv1alpha1 "github.com/mirantiscontainers/blueprint-operator/api/v1alpha1"
"github.com/mirantiscontainers/blueprint-operator/pkg/consts"
"github.com/mirantiscontainers/blueprint-operator/pkg/utils"

blueprintv1alpha1 "github.com/mirantiscontainers/blueprint-operator/api/v1alpha1"
)

// managedByBOPSelector only selects objects with the label indicating that the object is managed by blueprint operator
var managedByBOPSelector = utils.MustLabelSelector(consts.ManagedByLabel, selection.Equals, []string{consts.ManagedByValue})

// BlueprintReconciler reconciles a Blueprint object
type BlueprintReconciler struct {
client.Client
Expand Down Expand Up @@ -242,7 +245,7 @@ func issuerObject(issuer blueprintv1alpha1.Issuer) client.Object {
Name: issuer.Name,
Namespace: issuer.Namespace,
Labels: map[string]string{
"app.kubernetes.io/managed-by": "blueprint-operator",
consts.ManagedByLabel: consts.ManagedByValue,
},
},
Spec: issuer.Spec,
Expand All @@ -258,7 +261,7 @@ func clusterIssuerObject(issuer blueprintv1alpha1.ClusterIssuer) client.Object {
ObjectMeta: metav1.ObjectMeta{
Name: issuer.Name,
Labels: map[string]string{
"app.kubernetes.io/managed-by": "blueprint-operator",
consts.ManagedByLabel: consts.ManagedByValue,
},
},
Spec: issuer.Spec,
Expand All @@ -275,7 +278,7 @@ func certificateObject(certificate blueprintv1alpha1.Certificate) client.Object
Name: certificate.Name,
Namespace: certificate.Namespace,
Labels: map[string]string{
"app.kubernetes.io/managed-by": "blueprint-operator",
consts.ManagedByLabel: consts.ManagedByValue,
},
},
Spec: certificate.Spec,
Expand All @@ -284,7 +287,7 @@ func certificateObject(certificate blueprintv1alpha1.Certificate) client.Object

func listIssuers(ctx context.Context, apiClient client.Client) ([]client.Object, error) {
issuerList := &certmanager.IssuerList{}
if err := apiClient.List(ctx, issuerList); err != nil {
if err := apiClient.List(ctx, issuerList, managedByBOPSelector); err != nil {
return nil, err
}

Expand All @@ -293,7 +296,7 @@ func listIssuers(ctx context.Context, apiClient client.Client) ([]client.Object,

func listClusterIssuers(ctx context.Context, apiClient client.Client) ([]client.Object, error) {
clusterIssuerList := &certmanager.ClusterIssuerList{}
if err := apiClient.List(ctx, clusterIssuerList); err != nil {
if err := apiClient.List(ctx, clusterIssuerList, managedByBOPSelector); err != nil {
return nil, err
}

Expand All @@ -302,7 +305,7 @@ func listClusterIssuers(ctx context.Context, apiClient client.Client) ([]client.

func listCertificates(ctx context.Context, apiClient client.Client) ([]client.Object, error) {
certificateList := &certmanager.CertificateList{}
if err := apiClient.List(ctx, certificateList); err != nil {
if err := apiClient.List(ctx, certificateList, managedByBOPSelector); err != nil {
return nil, err
}

Expand Down
86 changes: 86 additions & 0 deletions controllers/blueprint_controller_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package controllers

import (
"context"

v1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client/fake"

"github.com/mirantiscontainers/blueprint-operator/api/v1alpha1"
"github.com/mirantiscontainers/blueprint-operator/pkg/consts"
Expand Down Expand Up @@ -125,3 +129,85 @@ var _ = Describe("Blueprint controller", Ordered, Serial, func() {
})
})
})

var _ = Describe("Object operations", func() {
Context("issuers", func() {
It("only lists BOP managed issuers", func(ctx context.Context) {
fakeClient := fake.NewClientBuilder().WithObjects(
&v1.Issuer{ObjectMeta: metav1.ObjectMeta{
Name: "issuer1",
Namespace: "ns1",
Labels: map[string]string{consts.ManagedByLabel: consts.ManagedByValue},
}},
&v1.Issuer{ObjectMeta: metav1.ObjectMeta{
Name: "issuer2",
Namespace: "ns2",
Labels: nil,
}},
).Build()

objs, err := listIssuers(ctx, fakeClient)
Expect(err).To(BeNil())

Expect(objs).To(HaveLen(1))
Expect(objs[0].GetName()).To(Equal("issuer1"))
})

It("creates issuer with BOP managed label", func(ctx context.Context) {
issuer := issuerObject(v1alpha1.Issuer{Name: "issuer1", Namespace: "ns1"})
Expect(issuer.GetLabels()[consts.ManagedByLabel]).To(Equal(consts.ManagedByValue))
})
})

Context("cluster issuers", func() {
It("only lists BOP managed cluster issuers", func(ctx context.Context) {
fakeClient := fake.NewClientBuilder().WithObjects(
&v1.ClusterIssuer{ObjectMeta: metav1.ObjectMeta{
Name: "clusterissuer1",
Labels: map[string]string{consts.ManagedByLabel: consts.ManagedByValue},
}},
&v1.ClusterIssuer{ObjectMeta: metav1.ObjectMeta{
Name: "clusterissuer2",
Labels: nil,
}},
).Build()

objs, err := listClusterIssuers(ctx, fakeClient)
Expect(err).To(BeNil())

Expect(objs).To(HaveLen(1))
Expect(objs[0].GetName()).To(Equal("clusterissuer1"))
})

It("creates cluster issuer with BOP managed label", func(ctx context.Context) {
issuer := clusterIssuerObject(v1alpha1.ClusterIssuer{Name: "clusterissuer1"})
Expect(issuer.GetLabels()[consts.ManagedByLabel]).To(Equal(consts.ManagedByValue))
})
})

Context("certificates", func() {
It("only lists BOP managed certificates", func(ctx context.Context) {
fakeClient := fake.NewClientBuilder().WithObjects(
&v1.Certificate{ObjectMeta: metav1.ObjectMeta{
Name: "certificate1",
Labels: map[string]string{consts.ManagedByLabel: consts.ManagedByValue},
}},
&v1.Certificate{ObjectMeta: metav1.ObjectMeta{
Name: "certificate2",
Labels: nil,
}},
).Build()

objs, err := listCertificates(ctx, fakeClient)
Expect(err).To(BeNil())

Expect(objs).To(HaveLen(1))
Expect(objs[0].GetName()).To(Equal("certificate1"))
})

It("creates certificate with BOP managed label", func(ctx context.Context) {
issuer := certificateObject(v1alpha1.Certificate{Name: "certificate1"})
Expect(issuer.GetLabels()[consts.ManagedByLabel]).To(Equal(consts.ManagedByValue))
})
})
})
7 changes: 5 additions & 2 deletions controllers/objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package controllers
import (
"context"
"fmt"
"slices"

"github.com/go-logr/logr"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/mirantiscontainers/blueprint-operator/pkg/consts"
"github.com/mirantiscontainers/blueprint-operator/pkg/utils"
)

Expand Down Expand Up @@ -48,8 +50,9 @@ func deleteObjects(ctx context.Context, logger logr.Logger, apiClient client.Cli
// Only delete the resources(cert/issuer) that are managed by BOP.
// This check can be removed once we add the label in all
// the objects created by BOP (https://mirantis.jira.com/browse/BOP-919).
if o.GetObjectKind().GroupVersionKind().Kind == "Certificate" || o.GetObjectKind().GroupVersionKind().Kind == "Issuer" {
if o.GetLabels()["app.kubernetes.io/managed-by"] != "blueprint-operator" {
kind := o.GetObjectKind().GroupVersionKind().Kind
if slices.Contains([]string{"Certificate", "Issuer", "ClusterIssuer"}, kind) {
if o.GetLabels()[consts.ManagedByLabel] != consts.ManagedByValue {
logger.Info("Skipping deletion of ", "Kind", o.GetObjectKind().GroupVersionKind().Kind)
continue
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/consts/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,10 @@ const (

// BlueprintContainerName is the name of the blueprint operator container
BlueprintContainerName = "manager"

// ManagedByLabel is the label used to identify resources managed by the blueprint operator
ManagedByLabel = "app.kubernetes.io/managed-by"

// ManagedByValue is the label value used to identify resources managed by the blueprint operator
ManagedByValue = "blueprint-operator"
)
20 changes: 20 additions & 0 deletions pkg/utils/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package utils

import (
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
"sigs.k8s.io/controller-runtime/pkg/client"
)

// MustLabelSelector creates a new label selector with the given key, operator, and values
// panics if any of the values are invalid
func MustLabelSelector(key string, operator selection.Operator, values []string) client.MatchingLabelsSelector {
req, err := labels.NewRequirement(key, operator, values)
if err != nil {
panic("panic creating label selector requirement: " + err.Error())
}

selector := labels.NewSelector().Add(*req)

return client.MatchingLabelsSelector{Selector: selector}
}
8 changes: 4 additions & 4 deletions test/e2e/install_certs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ func TestInstallCerts(t *testing.T) {
Name: "test-issuer-1",
Namespace: "test-issuer-ns-1",
Labels: map[string]string{
"app.kubernetes.io/managed-by": "blueprint-operator",
consts.ManagedByLabel: consts.ManagedByValue,
},
})
i2 := newIssuer(metav1.ObjectMeta{
Name: "test-issuer-2",
Namespace: "test-issuer-ns-1",
Labels: map[string]string{
"app.kubernetes.io/managed-by": "blueprint-operator",
consts.ManagedByLabel: consts.ManagedByValue,
},
})

Expand All @@ -41,7 +41,7 @@ func TestInstallCerts(t *testing.T) {
Name: "test-cert-1",
Namespace: "test-issuer-ns-1",
Labels: map[string]string{
"app.kubernetes.io/managed-by": "blueprint-operator",
consts.ManagedByLabel: consts.ManagedByValue,
},
})
cert1Specs := certmanager.CertificateSpec{
Expand All @@ -57,7 +57,7 @@ func TestInstallCerts(t *testing.T) {
Name: "test-cert-2",
Namespace: "test-cert-ns-1",
Labels: map[string]string{
"app.kubernetes.io/managed-by": "blueprint-operator",
consts.ManagedByLabel: consts.ManagedByValue,
},
})
cert2Specs := certmanager.CertificateSpec{
Expand Down

0 comments on commit 7de6986

Please sign in to comment.