Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ACM-10652] Added previously auto imported annotation to detached discoveredcluster #238

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 31 additions & 22 deletions controllers/discoveredcluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ package controllers

import (
"context"
"fmt"

"github.com/pkg/errors"
discovery "github.com/stolostron/discovery/api/v1"
utils "github.com/stolostron/discovery/util"
recon "github.com/stolostron/discovery/util/reconciler"
agentv1 "github.com/stolostron/klusterlet-addon-controller/pkg/apis/agent/v1"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -93,34 +95,41 @@ func (r *DiscoveredClusterReconciler) Reconcile(ctx context.Context, req ctrl.Re
are available. Otherwise, we will ignore that cluster.
*/
if !dc.Spec.IsManagedCluster && dc.Spec.ImportAsManagedCluster {
if res, err := r.EnsureNamespaceForDiscoveredCluster(ctx, *dc); err != nil {
logf.Error(err, "failed to ensure namespace for DiscoveredCluster", "Name", dc.Spec.DisplayName)
return res, err
}

if res, err := r.EnsureManagedCluster(ctx, *dc); err != nil {
logf.Error(err, "failed to ensure ManagedCluster created", "Name", dc.Spec.DisplayName)
return res, err
}

// Ensure that the KlusterletAddOnConfig CRD exists. In standalone MCE mode, the CRD is not deployed.
crdName := "klusterletaddonconfigs.agent.open-cluster-management.io"
if !utils.IsAnnotationTrue(dc, utils.AnnotationPreviouslyAutoImported) {
if res, err := r.EnsureNamespaceForDiscoveredCluster(ctx, *dc); err != nil {
logf.Error(err, "failed to ensure namespace for DiscoveredCluster", "Name", dc.Spec.DisplayName)
return res, err
}

if res, err := r.EnsureCRDExist(ctx, crdName); err != nil {
if !apierrors.IsNotFound(err) {
logf.Error(err, "failed to ensure custom resource definition exist", "Name", crdName)
if res, err := r.EnsureManagedCluster(ctx, *dc); err != nil {
logf.Error(err, "failed to ensure ManagedCluster created", "Name", dc.Spec.DisplayName)
return res, err
}
} else {
if res, err := r.EnsureKlusterletAddonConfig(ctx, *dc); err != nil {
logf.Error(err, "failed to ensure KlusterletAddonConfig created", "Name", dc.Spec.DisplayName)

// Ensure that the KlusterletAddOnConfig CRD exists. In standalone MCE mode, the CRD is not deployed.
crdName := "klusterletaddonconfigs.agent.open-cluster-management.io"

if res, err := r.EnsureCRDExist(ctx, crdName); err != nil {
if !apierrors.IsNotFound(err) {
logf.Error(err, "failed to ensure custom resource definition exist", "Name", crdName)
return res, err
}
} else {
if res, err := r.EnsureKlusterletAddonConfig(ctx, *dc); err != nil {
logf.Error(err, "failed to ensure KlusterletAddonConfig created", "Name", dc.Spec.DisplayName)
return res, err
}
}

if res, err := r.EnsureAutoImportSecret(ctx, *dc, *config); err != nil {
logf.Error(err, "failed to ensure auto import Secret created", "Name", dc.Spec.DisplayName)
return res, err
}
}

if res, err := r.EnsureAutoImportSecret(ctx, *dc, *config); err != nil {
logf.Error(err, "failed to ensure auto import Secret created", "Name", dc.Spec.DisplayName)
return res, err
} else {
logf.Info(
fmt.Sprintf("Skipped automatic import for DiscoveredCluster due to existing '%v' annotation",
utils.AnnotationPreviouslyAutoImported), "Name", dc.Spec.DisplayName)
}
}

Expand Down
33 changes: 26 additions & 7 deletions controllers/managedcluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ package controllers

import (
"context"
"fmt"

"github.com/go-logr/logr"
"github.com/pkg/errors"
discovery "github.com/stolostron/discovery/api/v1"
utils "github.com/stolostron/discovery/util"
recon "github.com/stolostron/discovery/util/reconciler"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -82,6 +84,20 @@ func (r *ManagedClusterReconciler) Reconcile(ctx context.Context, req ctrl.Reque

if dc.GetName() == req.Name || dc.Spec.DisplayName == req.Name {
modifiedDC := dc.DeepCopy()

/*
Set annotation to true on DiscoveredCluster resource to prevent automatic import.
The user will need to manually remove the annotation if they want the cluster to be reimported
automatically.
*/
if modifiedDC.Spec.ImportAsManagedCluster {
modifiedDC.SetAnnotations(map[string]string{
utils.AnnotationPreviouslyAutoImported: "true",
})

logf.Info(fmt.Sprintf("Added '%v' annotation to DiscoveredCluster",
utils.AnnotationPreviouslyAutoImported), "Name", dc.GetName())
}
modifiedDC.Spec.ImportAsManagedCluster = false

if err := r.Patch(ctx, modifiedDC, client.MergeFrom(dc)); err != nil {
Expand Down Expand Up @@ -127,11 +143,12 @@ func (r *ManagedClusterReconciler) SetupWithManager(mgr ctrl.Manager) error {
return nil
}

// updateManagedLabels adds managed labels to discovered clusters that need them and removes the labels if the discoveredclusters
// have the label but should not, based on the list of managedclusters.
func (r *ManagedClusterReconciler) updateManagedLabels(ctx context.Context, managedClusters *metav1.PartialObjectMetadataList, discoveredClusters *discovery.DiscoveredClusterList) error {
log, _ := logr.FromContext(ctx)

/*
updateManagedLabels adds managed labels to discovered clusters that need them and removes the labels if the
discoveredclusters have the label but should not, based on the list of managedclusters.
*/
func (r *ManagedClusterReconciler) updateManagedLabels(ctx context.Context,
managedClusters *metav1.PartialObjectMetadataList, discoveredClusters *discovery.DiscoveredClusterList) error {
isManaged := map[string]bool{}
for _, m := range managedClusters.Items {
if id := getClusterID(m); id != "" {
Expand All @@ -149,7 +166,8 @@ func (r *ManagedClusterReconciler) updateManagedLabels(ctx context.Context, mana
if err := r.Update(ctx, &dc); err != nil {
return errors.Wrapf(err, "error setting managed status `%s`", dc.Name)
}
log.Info("Updated cluster, adding managed status", "discoveredcluster", dc.Name, "discoveredcluster namespace", dc.Namespace)
logf.Info("Updated cluster, adding managed status", "discoveredcluster", dc.Name,
"discoveredcluster namespace", dc.Namespace)
}

} else {
Expand All @@ -158,7 +176,8 @@ func (r *ManagedClusterReconciler) updateManagedLabels(ctx context.Context, mana
if err := r.Update(ctx, &dc); err != nil {
return errors.Wrapf(err, "error unsetting managed status `%s`", dc.Name)
}
log.Info("Updated cluster, removing managed status", "discoveredcluster", dc.Name, "discoveredcluster namespace", dc.Namespace)
logf.Info("Updated cluster, removing managed status", "discoveredcluster", dc.Name,
"discoveredcluster namespace", dc.Namespace)
}
}
}
Expand Down
31 changes: 31 additions & 0 deletions util/annotations.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) 2020 Red Hat, Inc.
// Copyright Contributors to the Open Cluster Management project

package utils

import (
"strings"

discovery "github.com/stolostron/discovery/api/v1"
)

var (
/*
AnnotationPreviouslyAutoImported is an annotation used to indicate that a discovered cluster was previously
imported automatically.
*/
AnnotationPreviouslyAutoImported = "discovery.open-cluster-management.io/previously-auto-imported"
)

/*
IsAnnotationTrue checks if a specific annotation key in the given instance is set to "true".
*/
func IsAnnotationTrue(instance *discovery.DiscoveredCluster, annotationKey string) bool {
a := instance.GetAnnotations()
if a == nil {
return false
}

value := strings.EqualFold(a[annotationKey], "true")
return value
}
54 changes: 54 additions & 0 deletions util/annotations_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) 2020 Red Hat, Inc.
// Copyright Contributors to the Open Cluster Management project

package utils

import (
"testing"

discovery "github.com/stolostron/discovery/api/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func Test_IsAnnotationTrue(t *testing.T) {
tests := []struct {
name string
dc *discovery.DiscoveredCluster
want bool
}{
{
name: "should return annotation being true",
dc: &discovery.DiscoveredCluster{
ObjectMeta: v1.ObjectMeta{
Name: "foo",
Namespace: "bar",
Annotations: map[string]string{
AnnotationPreviouslyAutoImported: "true",
},
},
},
want: true,
},
{
name: "should return annotation being false",
dc: &discovery.DiscoveredCluster{
ObjectMeta: v1.ObjectMeta{
Name: "foo",
Namespace: "bar",
Annotations: map[string]string{
AnnotationPreviouslyAutoImported: "false",
},
},
},
want: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := IsAnnotationTrue(tt.dc, AnnotationPreviouslyAutoImported); got != tt.want {
t.Errorf("IsAnnotationTrue(tt.dc, AnnotationPreviouslyAutoImported) = %v, want %v", got, tt.want)
}
})
}
}
Loading