mirror of
https://github.com/open-cluster-management-io/ocm.git
synced 2026-08-23 22:26:49 +00:00
@@ -21,20 +21,18 @@ import (
|
||||
|
||||
const (
|
||||
autoUpdateAnnotation = "cluster.open-cluster-management.io/autoupdate"
|
||||
defaultManagedClusterSetName = "default"
|
||||
DefaultManagedClusterSetName = "default"
|
||||
)
|
||||
|
||||
var defaultManagedClusterSetSpec = clusterv1beta1.ManagedClusterSetSpec{
|
||||
ClusterSelector: clusterv1beta1.ManagedClusterSelector{
|
||||
SelectorType: clusterv1beta1.LegacyClusterSetLabel,
|
||||
},
|
||||
}
|
||||
|
||||
var defaultManagedClusterSet = &clusterv1beta1.ManagedClusterSet{
|
||||
var DefaultManagedClusterSet = &clusterv1beta1.ManagedClusterSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: defaultManagedClusterSetName,
|
||||
Name: DefaultManagedClusterSetName,
|
||||
},
|
||||
Spec: clusterv1beta1.ManagedClusterSetSpec{
|
||||
ClusterSelector: clusterv1beta1.ManagedClusterSelector{
|
||||
SelectorType: clusterv1beta1.LegacyClusterSetLabel,
|
||||
},
|
||||
},
|
||||
Spec: defaultManagedClusterSetSpec,
|
||||
}
|
||||
|
||||
type defaultManagedClusterSetController struct {
|
||||
@@ -66,7 +64,7 @@ func NewDefaultManagedClusterSetController(
|
||||
return false
|
||||
}
|
||||
// filter clustersets except defaultManagedClusterSet.
|
||||
return defaultManagedClusterSetName != metaObj.GetObjectMeta().GetName()
|
||||
return DefaultManagedClusterSetName != metaObj.GetObjectMeta().GetName()
|
||||
},
|
||||
clusterSetInformer.Informer(),
|
||||
).
|
||||
@@ -79,31 +77,23 @@ func NewDefaultManagedClusterSetController(
|
||||
}
|
||||
|
||||
func (c *defaultManagedClusterSetController) sync(ctx context.Context, syncCtx factory.SyncContext) error {
|
||||
defaultClusterSetName := defaultManagedClusterSetName
|
||||
klog.V(4).Infof("Reconciling DefaultManagedClusterSet")
|
||||
|
||||
defaultClusterSet, err := c.clusterSetLister.Get(defaultClusterSetName)
|
||||
|
||||
// if the defaultClusterSet not found, apply it.
|
||||
if errors.IsNotFound(err) {
|
||||
_, err := c.clusterSetClient.ManagedClusterSets().Create(ctx, defaultManagedClusterSet, metav1.CreateOptions{})
|
||||
if err == nil {
|
||||
c.eventRecorder.Eventf("DefaultManagedClusterSetCreated", "Set the DefaultManagedClusterSet name to %+v. spec to %+v", defaultClusterSetName, defaultManagedClusterSetSpec)
|
||||
defaultClusterSet, err := c.clusterSetLister.Get(DefaultManagedClusterSetName)
|
||||
if err != nil {
|
||||
// if the defaultClusterSet not found, apply it.
|
||||
if errors.IsNotFound(err) {
|
||||
_, err := c.clusterSetClient.ManagedClusterSets().Create(ctx, DefaultManagedClusterSet, metav1.CreateOptions{})
|
||||
if err == nil {
|
||||
c.eventRecorder.Eventf("DefaultManagedClusterSetCreated", "Set the DefaultManagedClusterSet name to %+v. spec to %+v", DefaultManagedClusterSetName, DefaultManagedClusterSet.Spec)
|
||||
}
|
||||
return err
|
||||
}
|
||||
return err
|
||||
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if defaultClusterSet is terminating, add the key to the controller queue with a second-long delay
|
||||
if !defaultClusterSet.DeletionTimestamp.IsZero() {
|
||||
syncCtx.Queue().AddAfter(defaultClusterSetName, 5*time.Second)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := c.syncDefaultClusterSet(ctx, defaultClusterSet); err != nil {
|
||||
return fmt.Errorf("failed to sync DefaultManagedClusterSet %q: %w", defaultClusterSetName, err)
|
||||
return fmt.Errorf("failed to sync DefaultManagedClusterSet %q: %w", DefaultManagedClusterSetName, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -120,8 +110,8 @@ func (c *defaultManagedClusterSetController) syncDefaultClusterSet(ctx context.C
|
||||
}
|
||||
|
||||
// if defaultClusterSet.Spec is changed, rollback the change by update it to the original value.
|
||||
if !equality.Semantic.DeepEqual(defaultClusterSet.Spec, defaultManagedClusterSetSpec) {
|
||||
defaultClusterSet.Spec = defaultManagedClusterSetSpec
|
||||
if !equality.Semantic.DeepEqual(defaultClusterSet.Spec, DefaultManagedClusterSet.Spec) {
|
||||
defaultClusterSet.Spec = DefaultManagedClusterSet.Spec
|
||||
|
||||
_, err := c.clusterSetClient.ManagedClusterSets().Update(ctx, defaultClusterSet, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
|
||||
@@ -31,27 +31,27 @@ func TestSyncDefaultClusterSet(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "sync default cluster set",
|
||||
existingClusterSet: newDefaultManagedClusterSet(defaultManagedClusterSetName, defaultManagedClusterSetSpec, false),
|
||||
existingClusterSet: newDefaultManagedClusterSet(DefaultManagedClusterSetName, DefaultManagedClusterSet.Spec, false),
|
||||
validateActions: func(t *testing.T, actions []clienttesting.Action) {
|
||||
testinghelpers.AssertNoActions(t, actions)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sync edited default cluster set",
|
||||
existingClusterSet: newDefaultManagedClusterSet(defaultManagedClusterSetName, editedDefaultManagedClusterSetSpec, false),
|
||||
existingClusterSet: newDefaultManagedClusterSet(DefaultManagedClusterSetName, editedDefaultManagedClusterSetSpec, false),
|
||||
validateActions: func(t *testing.T, actions []clienttesting.Action) {
|
||||
|
||||
testinghelpers.AssertActions(t, actions, "update")
|
||||
clusterset := actions[0].(clienttesting.UpdateAction).GetObject().(*clusterv1beta1.ManagedClusterSet)
|
||||
// if spec not rollbacked, error
|
||||
if !equality.Semantic.DeepEqual(clusterset.Spec, defaultManagedClusterSetSpec) {
|
||||
if !equality.Semantic.DeepEqual(clusterset.Spec, DefaultManagedClusterSet.Spec) {
|
||||
t.Errorf("Failed to rollback default managed cluster set spec after it is edited")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sync deleting default cluster set",
|
||||
existingClusterSet: newDefaultManagedClusterSet(defaultManagedClusterSetName, defaultManagedClusterSetSpec, true),
|
||||
existingClusterSet: newDefaultManagedClusterSet(DefaultManagedClusterSetName, DefaultManagedClusterSet.Spec, true),
|
||||
validateActions: func(t *testing.T, actions []clienttesting.Action) {
|
||||
testinghelpers.AssertNoActions(t, actions)
|
||||
},
|
||||
@@ -62,14 +62,14 @@ func TestSyncDefaultClusterSet(t *testing.T) {
|
||||
validateActions: func(t *testing.T, actions []clienttesting.Action) {
|
||||
testinghelpers.AssertActions(t, actions, "create")
|
||||
clusterset := actions[0].(clienttesting.CreateAction).GetObject().(*clusterv1beta1.ManagedClusterSet)
|
||||
if clusterset.ObjectMeta.Name != defaultManagedClusterSetName {
|
||||
if clusterset.ObjectMeta.Name != DefaultManagedClusterSetName {
|
||||
t.Errorf("Failed to create default managed cluster set")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sync default cluster set with disabled annotation",
|
||||
existingClusterSet: newDefaultManagedClusterSetWithAnnotation(defaultManagedClusterSetName, autoUpdateAnnotation, "false", defaultManagedClusterSetSpec, false),
|
||||
existingClusterSet: newDefaultManagedClusterSetWithAnnotation(DefaultManagedClusterSetName, autoUpdateAnnotation, "false", DefaultManagedClusterSet.Spec, false),
|
||||
validateActions: func(t *testing.T, actions []clienttesting.Action) {
|
||||
testinghelpers.AssertNoActions(t, actions)
|
||||
},
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
package managedclusterset
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/openshift/library-go/pkg/controller/factory"
|
||||
"github.com/openshift/library-go/pkg/operator/events"
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/klog/v2"
|
||||
clustersetv1beta1 "open-cluster-management.io/api/client/cluster/clientset/versioned/typed/cluster/v1beta1"
|
||||
clusterinformerv1beta1 "open-cluster-management.io/api/client/cluster/informers/externalversions/cluster/v1beta1"
|
||||
clusterlisterv1beta1 "open-cluster-management.io/api/client/cluster/listers/cluster/v1beta1"
|
||||
clusterv1beta1 "open-cluster-management.io/api/cluster/v1beta1"
|
||||
)
|
||||
|
||||
const (
|
||||
GlobalManagedClusterSetName = "global"
|
||||
)
|
||||
|
||||
var GlobalManagedClusterSet = &clusterv1beta1.ManagedClusterSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: GlobalManagedClusterSetName,
|
||||
},
|
||||
Spec: clusterv1beta1.ManagedClusterSetSpec{
|
||||
ClusterSelector: clusterv1beta1.ManagedClusterSelector{
|
||||
SelectorType: clusterv1beta1.LabelSelector,
|
||||
LabelSelector: &metav1.LabelSelector{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type globalManagedClusterSetController struct {
|
||||
clusterSetClient clustersetv1beta1.ClusterV1beta1Interface
|
||||
clusterSetLister clusterlisterv1beta1.ManagedClusterSetLister
|
||||
eventRecorder events.Recorder
|
||||
}
|
||||
|
||||
func NewGlobalManagedClusterSetController(
|
||||
clusterSetClient clustersetv1beta1.ClusterV1beta1Interface,
|
||||
clusterSetInformer clusterinformerv1beta1.ManagedClusterSetInformer,
|
||||
recorder events.Recorder) factory.Controller {
|
||||
|
||||
c := &globalManagedClusterSetController{
|
||||
clusterSetClient: clusterSetClient,
|
||||
clusterSetLister: clusterSetInformer.Lister(),
|
||||
eventRecorder: recorder.WithComponentSuffix("global-managed-cluster-set-controller"),
|
||||
}
|
||||
|
||||
return factory.New().
|
||||
WithFilteredEventsInformersQueueKeyFunc(
|
||||
func(obj runtime.Object) string {
|
||||
accessor, _ := meta.Accessor(obj)
|
||||
return accessor.GetName()
|
||||
},
|
||||
func(obj interface{}) bool {
|
||||
metaObj, ok := obj.(metav1.ObjectMetaAccessor)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
// filter clustersets except globalManagedClusterSet.
|
||||
return GlobalManagedClusterSetName != metaObj.GetObjectMeta().GetName()
|
||||
},
|
||||
clusterSetInformer.Informer(),
|
||||
).
|
||||
WithSync(c.sync).
|
||||
// use ResyncEvery to make sure:
|
||||
// 1. create the global clusterset once controller is launched
|
||||
// 2. the global clusterset be recreated once it is deleted for some reason
|
||||
ResyncEvery(10*time.Second).
|
||||
ToController("GlobalManagedClusterSetController", recorder)
|
||||
}
|
||||
|
||||
func (c *globalManagedClusterSetController) sync(ctx context.Context, syncCtx factory.SyncContext) error {
|
||||
klog.V(4).Infof("Reconciling GlobalManagedClusterSet")
|
||||
globalClusterSet, err := c.clusterSetLister.Get(GlobalManagedClusterSetName)
|
||||
// if the globalClusterSet not found, apply it.
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
_, err := c.clusterSetClient.ManagedClusterSets().Create(ctx, GlobalManagedClusterSet, metav1.CreateOptions{})
|
||||
if err == nil {
|
||||
c.eventRecorder.Eventf("GlobalManagedClusterSetCreated", "Set the GlobalManagedClusterSet name to %+v. spec to %+v", GlobalManagedClusterSetName, GlobalManagedClusterSet.Spec)
|
||||
}
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.applyGlobalClusterSet(ctx, globalClusterSet); err != nil {
|
||||
return fmt.Errorf("failed to sync GlobalManagedClusterSet %q: %w", GlobalManagedClusterSetName, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// applyGlobalClusterSet syncs global cluster set.
|
||||
func (c *globalManagedClusterSetController) applyGlobalClusterSet(ctx context.Context, originalGlobalClusterSet *clusterv1beta1.ManagedClusterSet) error {
|
||||
globalClusterSet := originalGlobalClusterSet.DeepCopy()
|
||||
|
||||
// if the annotation has set to disable, global clusterset controller will not work.
|
||||
if hasAnnotation(globalClusterSet, autoUpdateAnnotation, "false") {
|
||||
klog.V(4).Info("GlobalManagedClusterSetDisabled", "The GlobalManagedClusterSet is disabled by user")
|
||||
return nil
|
||||
}
|
||||
|
||||
// if globalClusterSet.Spec is changed, rollback the change by update it to the original value.
|
||||
if !equality.Semantic.DeepEqual(globalClusterSet.Spec, GlobalManagedClusterSet.Spec) {
|
||||
globalClusterSet.Spec = GlobalManagedClusterSet.Spec
|
||||
|
||||
_, err := c.clusterSetClient.ManagedClusterSets().Update(ctx, globalClusterSet, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update status of ManagedClusterSet %q: %w", globalClusterSet.Name, err)
|
||||
}
|
||||
|
||||
c.eventRecorder.Eventf("GlobalManagedClusterSetSpecRollbacked", "Rollback the GlobalManagedClusterSetSpec to %+v", globalClusterSet.Spec)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package managedclusterset
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/openshift/library-go/pkg/operator/events/eventstesting"
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
clienttesting "k8s.io/client-go/testing"
|
||||
clusterfake "open-cluster-management.io/api/client/cluster/clientset/versioned/fake"
|
||||
clusterinformers "open-cluster-management.io/api/client/cluster/informers/externalversions"
|
||||
clusterv1beta1 "open-cluster-management.io/api/cluster/v1beta1"
|
||||
testinghelpers "open-cluster-management.io/registration/pkg/helpers/testing"
|
||||
)
|
||||
|
||||
func TestSyncGlobalClusterSet(t *testing.T) {
|
||||
|
||||
var editedGlobalManagedClusterSetSpec = clusterv1beta1.ManagedClusterSetSpec{
|
||||
ClusterSelector: clusterv1beta1.ManagedClusterSelector{
|
||||
SelectorType: "non-LegacyClusterSetLabel",
|
||||
},
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
existingClusterSet *clusterv1beta1.ManagedClusterSet
|
||||
validateActions func(t *testing.T, actions []clienttesting.Action)
|
||||
}{
|
||||
{
|
||||
name: "sync global cluster set",
|
||||
existingClusterSet: newGlobalManagedClusterSet(GlobalManagedClusterSetName, GlobalManagedClusterSet.Spec, false),
|
||||
validateActions: func(t *testing.T, actions []clienttesting.Action) {
|
||||
testinghelpers.AssertNoActions(t, actions)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sync edited global cluster set",
|
||||
existingClusterSet: newGlobalManagedClusterSet(GlobalManagedClusterSetName, editedGlobalManagedClusterSetSpec, false),
|
||||
validateActions: func(t *testing.T, actions []clienttesting.Action) {
|
||||
|
||||
testinghelpers.AssertActions(t, actions, "update")
|
||||
clusterset := actions[0].(clienttesting.UpdateAction).GetObject().(*clusterv1beta1.ManagedClusterSet)
|
||||
// if spec not rollbacked, error
|
||||
if !equality.Semantic.DeepEqual(clusterset.Spec, GlobalManagedClusterSet.Spec) {
|
||||
t.Errorf("Failed to rollback global managed cluster set spec after it is edited")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sync deleted global cluster set",
|
||||
// global cluster set should be created if it is deleted.
|
||||
validateActions: func(t *testing.T, actions []clienttesting.Action) {
|
||||
testinghelpers.AssertActions(t, actions, "create")
|
||||
clusterset := actions[0].(clienttesting.CreateAction).GetObject().(*clusterv1beta1.ManagedClusterSet)
|
||||
if clusterset.ObjectMeta.Name != GlobalManagedClusterSetName {
|
||||
t.Errorf("Failed to create global managed cluster set")
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sync global cluster set with disabled annotation",
|
||||
existingClusterSet: newGlobalManagedClusterSetWithAnnotation(GlobalManagedClusterSetName, autoUpdateAnnotation, "false", GlobalManagedClusterSet.Spec, false),
|
||||
validateActions: func(t *testing.T, actions []clienttesting.Action) {
|
||||
testinghelpers.AssertNoActions(t, actions)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
objects := []runtime.Object{}
|
||||
|
||||
if c.existingClusterSet != nil {
|
||||
objects = append(objects, c.existingClusterSet)
|
||||
}
|
||||
|
||||
clusterSetClient := clusterfake.NewSimpleClientset(objects...)
|
||||
informerFactory := clusterinformers.NewSharedInformerFactory(clusterSetClient, 5*time.Minute)
|
||||
|
||||
if c.existingClusterSet != nil {
|
||||
if err := informerFactory.Cluster().V1beta1().ManagedClusterSets().Informer().GetStore().Add(c.existingClusterSet); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
ctrl := globalManagedClusterSetController{
|
||||
clusterSetClient: clusterSetClient.ClusterV1beta1(),
|
||||
clusterSetLister: informerFactory.Cluster().V1beta1().ManagedClusterSets().Lister(),
|
||||
eventRecorder: eventstesting.NewTestingEventRecorder(t),
|
||||
}
|
||||
|
||||
syncErr := ctrl.sync(context.TODO(), testinghelpers.NewFakeSyncContext(t, testinghelpers.TestManagedClusterName))
|
||||
if syncErr != nil {
|
||||
t.Errorf("unexpected err: %v", syncErr)
|
||||
}
|
||||
|
||||
c.validateActions(t, clusterSetClient.Actions())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func newGlobalManagedClusterSet(name string, spec clusterv1beta1.ManagedClusterSetSpec, terminating bool) *clusterv1beta1.ManagedClusterSet {
|
||||
clusterSet := &clusterv1beta1.ManagedClusterSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
},
|
||||
Spec: spec,
|
||||
}
|
||||
if terminating {
|
||||
now := metav1.Now()
|
||||
clusterSet.DeletionTimestamp = &now
|
||||
}
|
||||
|
||||
return clusterSet
|
||||
}
|
||||
|
||||
func newGlobalManagedClusterSetWithAnnotation(name string, k, v string, spec clusterv1beta1.ManagedClusterSetSpec, terminating bool) *clusterv1beta1.ManagedClusterSet {
|
||||
clusterSet := &clusterv1beta1.ManagedClusterSet{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Annotations: map[string]string{
|
||||
k: v,
|
||||
},
|
||||
},
|
||||
Spec: spec,
|
||||
}
|
||||
if terminating {
|
||||
now := metav1.Now()
|
||||
clusterSet.DeletionTimestamp = &now
|
||||
}
|
||||
|
||||
return clusterSet
|
||||
}
|
||||
+7
-1
@@ -141,13 +141,18 @@ func RunControllerManager(ctx context.Context, controllerContext *controllercmd.
|
||||
controllerContext.EventRecorder,
|
||||
)
|
||||
|
||||
var defaultManagedClusterSetController factory.Controller
|
||||
var defaultManagedClusterSetController, globalManagedClusterSetController factory.Controller
|
||||
if features.DefaultHubMutableFeatureGate.Enabled(features.DefaultClusterSet) {
|
||||
defaultManagedClusterSetController = managedclusterset.NewDefaultManagedClusterSetController(
|
||||
clusterClient.ClusterV1beta1(),
|
||||
clusterInformers.Cluster().V1beta1().ManagedClusterSets(),
|
||||
controllerContext.EventRecorder,
|
||||
)
|
||||
globalManagedClusterSetController = managedclusterset.NewGlobalManagedClusterSetController(
|
||||
clusterClient.ClusterV1beta1(),
|
||||
clusterInformers.Cluster().V1beta1().ManagedClusterSets(),
|
||||
controllerContext.EventRecorder,
|
||||
)
|
||||
}
|
||||
|
||||
go clusterInformers.Start(ctx.Done())
|
||||
@@ -167,6 +172,7 @@ func RunControllerManager(ctx context.Context, controllerContext *controllercmd.
|
||||
go addOnFeatureDiscoveryController.Run(ctx, 1)
|
||||
if features.DefaultHubMutableFeatureGate.Enabled(features.DefaultClusterSet) {
|
||||
go defaultManagedClusterSetController.Run(ctx, 1)
|
||||
go globalManagedClusterSetController.Run(ctx, 1)
|
||||
}
|
||||
|
||||
<-ctx.Done()
|
||||
|
||||
@@ -7,31 +7,23 @@ import (
|
||||
"github.com/onsi/ginkgo"
|
||||
"github.com/onsi/gomega"
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
setcontroller "open-cluster-management.io/registration/pkg/hub/managedclusterset"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clusterv1beta1 "open-cluster-management.io/api/cluster/v1beta1"
|
||||
)
|
||||
|
||||
var _ = ginkgo.Describe("DefaultManagedClusterSet", func() {
|
||||
var (
|
||||
defaultClusterSetName = "default"
|
||||
defaultManagedClusterSetSpec = clusterv1beta1.ManagedClusterSetSpec{
|
||||
ClusterSelector: clusterv1beta1.ManagedClusterSelector{
|
||||
SelectorType: clusterv1beta1.LegacyClusterSetLabel,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
ginkgo.It("should create DefaultManagedClusterSet successfully", func() {
|
||||
|
||||
ginkgo.By("check whether DefaultManagedClusterSet is created")
|
||||
gomega.Eventually(func() error {
|
||||
mcs, err := clusterClient.ClusterV1beta1().ManagedClusterSets().Get(context.TODO(), defaultClusterSetName, metav1.GetOptions{})
|
||||
mcs, err := clusterClient.ClusterV1beta1().ManagedClusterSets().Get(context.TODO(), setcontroller.DefaultManagedClusterSetName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if mcs.ObjectMeta.Name == defaultClusterSetName && equality.Semantic.DeepEqual(mcs.Spec, defaultManagedClusterSetSpec) {
|
||||
if mcs.ObjectMeta.Name == setcontroller.DefaultManagedClusterSetName && equality.Semantic.DeepEqual(mcs.Spec, setcontroller.DefaultManagedClusterSet.Spec) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("check not pass!")
|
||||
@@ -42,24 +34,21 @@ var _ = ginkgo.Describe("DefaultManagedClusterSet", func() {
|
||||
ginkgo.It("should recreate DefaultManagedClusterSet successfully after deleted", func() {
|
||||
|
||||
ginkgo.By("delete DefaultManagedClusterSet")
|
||||
err := clusterClient.ClusterV1beta1().ManagedClusterSets().Delete(context.TODO(), defaultClusterSetName, metav1.DeleteOptions{})
|
||||
err := clusterClient.ClusterV1beta1().ManagedClusterSets().Delete(context.TODO(), setcontroller.DefaultManagedClusterSetName, metav1.DeleteOptions{})
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred(), "try to delete DefaultManagedClusterSet error")
|
||||
|
||||
ginkgo.By("check whether DefaultManagedClusterSet is recreated")
|
||||
gomega.Eventually(func() error {
|
||||
mcs, err := clusterClient.ClusterV1beta1().ManagedClusterSets().Get(context.TODO(), defaultClusterSetName, metav1.GetOptions{})
|
||||
mcs, err := clusterClient.ClusterV1beta1().ManagedClusterSets().Get(context.TODO(), setcontroller.DefaultManagedClusterSetName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if mcs.ObjectMeta.Name == defaultClusterSetName && equality.Semantic.DeepEqual(mcs.Spec, defaultManagedClusterSetSpec) {
|
||||
if mcs.ObjectMeta.Name == setcontroller.DefaultManagedClusterSetName && equality.Semantic.DeepEqual(mcs.Spec, setcontroller.DefaultManagedClusterSet.Spec) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("check not pass!")
|
||||
|
||||
}, eventuallyTimeout, eventuallyInterval).ShouldNot(gomega.HaveOccurred())
|
||||
})
|
||||
|
||||
// TODO:
|
||||
// add test case for edit default managedclusterset spec operation
|
||||
})
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package integration_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/onsi/ginkgo"
|
||||
"github.com/onsi/gomega"
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
setcontroller "open-cluster-management.io/registration/pkg/hub/managedclusterset"
|
||||
)
|
||||
|
||||
var _ = ginkgo.Describe("GlobalManagedClusterSet", func() {
|
||||
ginkgo.It("should create GlobalManagedClusterSet successfully", func() {
|
||||
ginkgo.By("check whether GlobalManagedClusterSet is created")
|
||||
gomega.Eventually(func() error {
|
||||
mcs, err := clusterClient.ClusterV1beta1().ManagedClusterSets().Get(context.TODO(), setcontroller.GlobalManagedClusterSetName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if mcs.ObjectMeta.Name == setcontroller.GlobalManagedClusterSetName && reflect.DeepEqual(mcs.Spec, setcontroller.GlobalManagedClusterSet.Spec) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("check not pass!")
|
||||
|
||||
}, eventuallyTimeout, eventuallyInterval).ShouldNot(gomega.HaveOccurred())
|
||||
})
|
||||
|
||||
ginkgo.It("should reconcile GlobalManagedClusterSet successfully if it changed", func() {
|
||||
ginkgo.By("check whether GlobalManagedClusterSet is reconciled after changed")
|
||||
mcs, err := clusterClient.ClusterV1beta1().ManagedClusterSets().Get(context.TODO(), setcontroller.GlobalManagedClusterSetName, metav1.GetOptions{})
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
|
||||
updateMcs := mcs.DeepCopy()
|
||||
updateMcs.Spec.ClusterSelector.LabelSelector = &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
"vendor": "openshift",
|
||||
},
|
||||
}
|
||||
_, err = clusterClient.ClusterV1beta1().ManagedClusterSets().Update(context.TODO(), updateMcs, metav1.UpdateOptions{})
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
|
||||
gomega.Eventually(func() error {
|
||||
mcs, err := clusterClient.ClusterV1beta1().ManagedClusterSets().Get(context.TODO(), setcontroller.GlobalManagedClusterSetName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if mcs.ObjectMeta.Name == setcontroller.GlobalManagedClusterSetName && equality.Semantic.DeepEqual(mcs.Spec, setcontroller.GlobalManagedClusterSet.Spec) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("check not pass!")
|
||||
}, eventuallyTimeout, eventuallyInterval).ShouldNot(gomega.HaveOccurred())
|
||||
})
|
||||
|
||||
ginkgo.It("should not change users labels/annotations in GlobalManagedClusterSet", func() {
|
||||
ginkgo.By("check whether GlobalManagedClusterSet labels/annotations reconciled after changed")
|
||||
mcs, err := clusterClient.ClusterV1beta1().ManagedClusterSets().Get(context.TODO(), setcontroller.GlobalManagedClusterSetName, metav1.GetOptions{})
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
|
||||
updateMcs := mcs.DeepCopy()
|
||||
updateMcs.Annotations = map[string]string{
|
||||
"annotation-test": "a1",
|
||||
}
|
||||
updateMcs.Labels = map[string]string{
|
||||
"label-test": "l1",
|
||||
}
|
||||
updateMcs.Spec.ClusterSelector.LabelSelector = &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
"vendor": "openshift",
|
||||
},
|
||||
}
|
||||
_, err = clusterClient.ClusterV1beta1().ManagedClusterSets().Update(context.TODO(), updateMcs, metav1.UpdateOptions{})
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
|
||||
gomega.Eventually(func() error {
|
||||
mcs, err := clusterClient.ClusterV1beta1().ManagedClusterSets().Get(context.TODO(), setcontroller.GlobalManagedClusterSetName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if equality.Semantic.DeepEqual(mcs.Spec, setcontroller.GlobalManagedClusterSet.Spec) && equality.Semantic.DeepEqual(mcs.Annotations, updateMcs.Annotations) && equality.Semantic.DeepEqual(mcs.Labels, updateMcs.Labels) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("check not pass!")
|
||||
}, eventuallyTimeout, eventuallyInterval).ShouldNot(gomega.HaveOccurred())
|
||||
})
|
||||
|
||||
ginkgo.It("should recreate GlobalManagedClusterSet successfully after deleted", func() {
|
||||
ginkgo.By("delete GlobalManagedClusterSet")
|
||||
err := clusterClient.ClusterV1beta1().ManagedClusterSets().Delete(context.TODO(), setcontroller.GlobalManagedClusterSetName, metav1.DeleteOptions{})
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred(), "try to delete GlobalManagedClusterSet error")
|
||||
|
||||
ginkgo.By("check whether GlobalManagedClusterSet is recreated")
|
||||
gomega.Eventually(func() error {
|
||||
mcs, err := clusterClient.ClusterV1beta1().ManagedClusterSets().Get(context.TODO(), setcontroller.GlobalManagedClusterSetName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if mcs.ObjectMeta.Name == setcontroller.GlobalManagedClusterSetName && equality.Semantic.DeepEqual(mcs.Spec, setcontroller.GlobalManagedClusterSet.Spec) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("check not pass!")
|
||||
|
||||
}, eventuallyTimeout, eventuallyInterval).ShouldNot(gomega.HaveOccurred())
|
||||
})
|
||||
|
||||
})
|
||||
Reference in New Issue
Block a user