From 71a5ba500c59199c28e29e6845bdf7cfe9c7df93 Mon Sep 17 00:00:00 2001 From: Anatolii Bazko Date: Thu, 23 Jun 2022 14:17:00 +0300 Subject: [PATCH] fix: sync ConsoleLink (#1410) * fix: sync ConsoleLink Signed-off-by: Anatolii Bazko --- pkg/common/test/utils.go | 5 +- pkg/deploy/consolelink/consolelink.go | 42 +++++--------- pkg/deploy/consolelink/consolelink_test.go | 66 +++++++++++++++++++++- 3 files changed, 81 insertions(+), 32 deletions(-) diff --git a/pkg/common/test/utils.go b/pkg/common/test/utils.go index f37364fa5..9b3ad8c21 100644 --- a/pkg/common/test/utils.go +++ b/pkg/common/test/utils.go @@ -14,6 +14,7 @@ package test import ( "context" "os" + "strings" "testing" chev2 "github.com/eclipse-che/che-operator/api/v2" @@ -158,7 +159,7 @@ func GetDeployContext(cheCluster *chev2.CheCluster, initObjs []runtime.Object) * Namespace: "eclipse-che", }, Status: chev2.CheClusterStatus{ - CheURL: "che-host", + CheURL: "https://che-host", }, } } @@ -190,6 +191,6 @@ func GetDeployContext(cheCluster *chev2.CheCluster, initObjs []runtime.Object) * DiscoveryClient: fakeDiscovery, }, Proxy: &chetypes.Proxy{}, - CheHost: "che-host", + CheHost: strings.TrimPrefix(cheCluster.Status.CheURL, "https://"), } } diff --git a/pkg/deploy/consolelink/consolelink.go b/pkg/deploy/consolelink/consolelink.go index cc6d859ce..33b651b9f 100644 --- a/pkg/deploy/consolelink/consolelink.go +++ b/pkg/deploy/consolelink/consolelink.go @@ -13,14 +13,14 @@ package consolelink import ( "fmt" - "strings" "github.com/devfile/devworkspace-operator/pkg/infrastructure" "github.com/eclipse-che/che-operator/pkg/common/chetypes" - "github.com/eclipse-che/che-operator/pkg/common/constants" defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" "github.com/eclipse-che/che-operator/pkg/common/utils" "github.com/eclipse-che/che-operator/pkg/deploy" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" consolev1 "github.com/openshift/api/console/v1" "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -33,6 +33,10 @@ const ( ConsoleLinksResourceName = "consolelinks" ) +var consoleLinkDiffOpts = cmp.Options{ + cmpopts.IgnoreFields(consolev1.ConsoleLink{}, "TypeMeta", "ObjectMeta"), +} + type ConsoleLinkReconciler struct { deploy.Reconcilable } @@ -43,11 +47,11 @@ func NewConsoleLinkReconciler() *ConsoleLinkReconciler { func (c *ConsoleLinkReconciler) Reconcile(ctx *chetypes.DeployContext) (reconcile.Result, bool, error) { if !infrastructure.IsOpenShift() || !utils.IsK8SResourceServed(ctx.ClusterAPI.DiscoveryClient, ConsoleLinksResourceName) { - logrus.Debug("Console link won't be created. Consolelinks is not supported by kubernetes cluster.") + logrus.Debug("Console link won't be created. ConsoleLinks is not supported by kubernetes cluster.") return reconcile.Result{}, true, nil } - done, err := c.createConsoleLink(ctx) + done, err := c.syncConsoleLink(ctx) if !done { return reconcile.Result{Requeue: true}, false, err } @@ -63,39 +67,23 @@ func (c *ConsoleLinkReconciler) Finalize(ctx *chetypes.DeployContext) bool { return true } -func (c *ConsoleLinkReconciler) createConsoleLink(ctx *chetypes.DeployContext) (bool, error) { +func (c *ConsoleLinkReconciler) syncConsoleLink(ctx *chetypes.DeployContext) (bool, error) { + if err := deploy.AppendFinalizer(ctx, ConsoleLinkFinalizerName); err != nil { + return false, err + } + consoleLinkSpec := c.getConsoleLinkSpec(ctx) - _, err := deploy.CreateIfNotExists(ctx, consoleLinkSpec) - if err != nil { - return false, err - } - - consoleLink := &consolev1.ConsoleLink{} - exists, err := deploy.Get(ctx, client.ObjectKey{Name: defaults.GetConsoleLinkName()}, consoleLink) - if !exists || err != nil { - return false, err - } - - // consolelink is for this specific instance of Eclipse Che - if strings.Index(consoleLink.Spec.Link.Href, ctx.CheHost) != -1 { - err = deploy.AppendFinalizer(ctx, ConsoleLinkFinalizerName) - return err == nil, err - } - - return true, nil + return deploy.Sync(ctx, consoleLinkSpec, consoleLinkDiffOpts) } func (c *ConsoleLinkReconciler) getConsoleLinkSpec(ctx *chetypes.DeployContext) *consolev1.ConsoleLink { consoleLink := &consolev1.ConsoleLink{ TypeMeta: metav1.TypeMeta{ Kind: "ConsoleLink", - APIVersion: consolev1.SchemeGroupVersion.String(), + APIVersion: consolev1.GroupVersion.String(), }, ObjectMeta: metav1.ObjectMeta{ Name: defaults.GetConsoleLinkName(), - Annotations: map[string]string{ - constants.CheEclipseOrgNamespace: ctx.CheCluster.Namespace, - }, }, Spec: consolev1.ConsoleLinkSpec{ Link: consolev1.Link{ diff --git a/pkg/deploy/consolelink/consolelink_test.go b/pkg/deploy/consolelink/consolelink_test.go index 8968b89e1..4cf148470 100644 --- a/pkg/deploy/consolelink/consolelink_test.go +++ b/pkg/deploy/consolelink/consolelink_test.go @@ -12,12 +12,15 @@ package consolelink import ( + "context" + "fmt" + "github.com/devfile/devworkspace-operator/pkg/infrastructure" chev2 "github.com/eclipse-che/che-operator/api/v2" defaults "github.com/eclipse-che/che-operator/pkg/common/operator-defaults" "github.com/eclipse-che/che-operator/pkg/common/test" "github.com/eclipse-che/che-operator/pkg/common/utils" - console "github.com/openshift/api/console/v1" + consolev1 "github.com/openshift/api/console/v1" "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -54,13 +57,70 @@ func TestReconcileConsoleLink(t *testing.T) { assert.True(t, done) assert.Nil(t, err) - assert.True(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: defaults.GetConsoleLinkName()}, &console.ConsoleLink{})) + consoleLink := &consolev1.ConsoleLink{} + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: defaults.GetConsoleLinkName()}, consoleLink) + assert.Nil(t, err) assert.True(t, utils.Contains(ctx.CheCluster.Finalizers, ConsoleLinkFinalizerName)) + assert.Equal(t, "https://che-host", consoleLink.Spec.Href) // Initialize DeletionTimestamp => checluster is being deleted done = consolelink.Finalize(ctx) assert.True(t, done) - assert.False(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: defaults.GetConsoleLinkName()}, &console.ConsoleLink{})) + assert.False(t, test.IsObjectExists(ctx.ClusterAPI.Client, types.NamespacedName{Name: defaults.GetConsoleLinkName()}, &consolev1.ConsoleLink{})) assert.False(t, utils.Contains(ctx.CheCluster.Finalizers, ConsoleLinkFinalizerName)) } + +func TestReconcileConsoleLinkWhenCheURLChanged(t *testing.T) { + infrastructure.InitializeForTesting(infrastructure.OpenShiftv4) + + cheCluster := &chev2.CheCluster{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "eclipse-che", + Name: "eclipse-che", + }, + Status: chev2.CheClusterStatus{ + CheURL: "https://test-host", + }, + } + + existedConsoleLink := &consolev1.ConsoleLink{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConsoleLink", + APIVersion: consolev1.GroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: defaults.GetConsoleLinkName(), + }, + Spec: consolev1.ConsoleLinkSpec{ + Link: consolev1.Link{ + Href: "https://che-host", + Text: defaults.GetConsoleLinkDisplayName()}, + Location: consolev1.ApplicationMenu, + ApplicationMenu: &consolev1.ApplicationMenuSpec{ + Section: defaults.GetConsoleLinkSection(), + ImageURL: fmt.Sprintf("https://%s%s", "che-host", defaults.GetConsoleLinkImage()), + }, + }, + } + + ctx := test.GetDeployContext(cheCluster, []runtime.Object{existedConsoleLink}) + ctx.ClusterAPI.DiscoveryClient.(*fakeDiscovery.FakeDiscovery).Fake.Resources = []*metav1.APIResourceList{ + { + APIResources: []metav1.APIResource{ + {Name: ConsoleLinksResourceName}, + }, + }, + } + + consoleLinkReconciler := NewConsoleLinkReconciler() + _, _, err := consoleLinkReconciler.Reconcile(ctx) + assert.Nil(t, err) + + consoleLink := &consolev1.ConsoleLink{} + err = ctx.ClusterAPI.Client.Get(context.TODO(), types.NamespacedName{Name: defaults.GetConsoleLinkName()}, consoleLink) + assert.Nil(t, err) + assert.True(t, utils.Contains(ctx.CheCluster.Finalizers, ConsoleLinkFinalizerName)) + assert.Equal(t, "https://test-host", consoleLink.Spec.Href) + assert.Equal(t, fmt.Sprintf("https://test-host%s", defaults.GetConsoleLinkImage()), consoleLink.Spec.ApplicationMenu.ImageURL) +}