From be53836f523f127a4c77ffd980261c876916ac87 Mon Sep 17 00:00:00 2001 From: LiZhenCheng9527 Date: Fri, 23 Feb 2024 16:01:08 +0800 Subject: [PATCH 1/4] Optimised fleet update function of e2e test Signed-off-by: LiZhenCheng9527 --- e2e/fleet_attachedcluster_test.go | 2 +- e2e/resources/attachedcluster.go | 40 +++++++++++++++---------------- e2e/resources/fleet.go | 33 +++++++++++++------------ e2e/resources/secret.go | 34 ++++++++++++++------------ e2e/resources/util.go | 39 ++++++++++++++++++++++++++++++ e2e/suite_test.go | 4 ++-- go.mod | 2 +- 7 files changed, 99 insertions(+), 55 deletions(-) create mode 100644 e2e/resources/util.go diff --git a/e2e/fleet_attachedcluster_test.go b/e2e/fleet_attachedcluster_test.go index 4d06c223..5bb6cd69 100644 --- a/e2e/fleet_attachedcluster_test.go +++ b/e2e/fleet_attachedcluster_test.go @@ -59,7 +59,7 @@ var _ = ginkgo.Describe("[AttachedClusters] AttachedClusters testing", func() { ginkgo.It("Create Fleet", func() { // create fleet and checkout fleet status - fleetCreateErr := resources.CreateFleet(kuratorClient, fleet) + fleetCreateErr := resources.CreateOrUpdateFleet(kuratorClient, fleet) gomega.Expect(fleetCreateErr).ShouldNot(gomega.HaveOccurred()) resources.WaitFleetFitWith(kuratorClient, namespace, fleetname, func(fleet *fleetv1a1.Fleet) bool { return fleet.Status.Phase == fleetv1a1.ReadyPhase diff --git a/e2e/resources/attachedcluster.go b/e2e/resources/attachedcluster.go index 3a02eeda..ef183648 100644 --- a/e2e/resources/attachedcluster.go +++ b/e2e/resources/attachedcluster.go @@ -22,6 +22,7 @@ import ( "github.com/onsi/gomega" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" clusterv1a1 "kurator.dev/kurator/pkg/apis/cluster/v1alpha1" kurator "kurator.dev/kurator/pkg/client-go/generated/clientset/versioned" @@ -44,33 +45,30 @@ func NewAttachedCluster(namespace string, name string, config clusterv1a1.Secret } // CreateAttachedCluster create AttachedCluster. -func CreateAttachedCluster(client kurator.Interface, attachedCluster *clusterv1a1.AttachedCluster) error { - _, err := client.ClusterV1alpha1().AttachedClusters(attachedCluster.Namespace).Create(context.TODO(), attachedCluster, metav1.CreateOptions{}) - if err != nil { - if apierrors.IsAlreadyExists(err) { - return UpdateAttachedCluster(client, attachedCluster) +func CreateOrUpdateAttachedCluster(client kurator.Interface, attachedCluster *clusterv1a1.AttachedCluster) error { + _, createErr := client.ClusterV1alpha1().AttachedClusters(attachedCluster.GetNamespace()).Create(context.TODO(), attachedCluster, metav1.CreateOptions{}) + if createErr != nil { + if apierrors.IsAlreadyExists(createErr) { + originalAttachedCluster, getErr := client.ClusterV1alpha1().AttachedClusters(attachedCluster.GetNamespace()).Get(context.TODO(), attachedCluster.GetName(), metav1.GetOptions{}) + if getErr != nil { + return getErr + } + attachedCluster.ResourceVersion = originalAttachedCluster.ResourceVersion + attachedClusterPatchData, createPatchErr := CreatePatchData(originalAttachedCluster, attachedCluster) + if createPatchErr != nil { + return createPatchErr + } + _, patchErr := client.ClusterV1alpha1().AttachedClusters(attachedCluster.GetNamespace()).Patch(context.TODO(), attachedCluster.GetName(), types.MergePatchType, attachedClusterPatchData, metav1.PatchOptions{}) + if patchErr != nil { + return patchErr + } } else { - return err + return createErr } } return nil } -// UpdateAttachedCluster update AttachedCluster -func UpdateAttachedCluster(client kurator.Interface, attachedCluster *clusterv1a1.AttachedCluster) error { - attachedClusterPresentOnCluster, attacattachedClusterGetErr := client.ClusterV1alpha1().AttachedClusters(attachedCluster.Namespace).Get(context.TODO(), attachedCluster.Name, metav1.GetOptions{}) - if attacattachedClusterGetErr != nil { - return attacattachedClusterGetErr - } - DCattachedcluster := attachedClusterPresentOnCluster.DeepCopy() - DCattachedcluster.Spec = attachedCluster.Spec - _, err := client.ClusterV1alpha1().AttachedClusters(DCattachedcluster.Namespace).Update(context.TODO(), DCattachedcluster, metav1.UpdateOptions{}) - if err != nil { - return err - } - return nil -} - func RemoveAttachedCluster(client kurator.Interface, namespace, name string) error { err := client.ClusterV1alpha1().AttachedClusters(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{}) if err != nil { diff --git a/e2e/resources/fleet.go b/e2e/resources/fleet.go index 85cbbee2..13b29703 100644 --- a/e2e/resources/fleet.go +++ b/e2e/resources/fleet.go @@ -23,6 +23,7 @@ import ( corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" fleetv1a1 "kurator.dev/kurator/pkg/apis/fleet/v1alpha1" kurator "kurator.dev/kurator/pkg/client-go/generated/clientset/versioned" @@ -46,27 +47,29 @@ func NewFleet(namespace string, name string, clusters []*corev1.ObjectReference) } // CreateAttachedCluster create AttachedCluster. -func CreateFleet(client kurator.Interface, fleet *fleetv1a1.Fleet) error { - _, err := client.FleetV1alpha1().Fleets(fleet.Namespace).Create(context.TODO(), fleet, metav1.CreateOptions{}) - if err != nil { - if apierrors.IsAlreadyExists(err) { - return UpdateFleet(client, fleet) +func CreateOrUpdateFleet(client kurator.Interface, fleet *fleetv1a1.Fleet) error { + _, createErr := client.FleetV1alpha1().Fleets(fleet.GetNamespace()).Create(context.TODO(), fleet, metav1.CreateOptions{}) + if createErr != nil { + if apierrors.IsAlreadyExists(createErr) { + originalFleet, getErr := client.FleetV1alpha1().Fleets(fleet.GetNamespace()).Get(context.TODO(), fleet.GetName(), metav1.GetOptions{}) + if getErr != nil { + return getErr + } + fleet.ResourceVersion = originalFleet.ResourceVersion + fleetPatchData, createPatchErr := CreatePatchData(originalFleet, fleet) + if createPatchErr != nil { + return createPatchErr + } + if _, patchErr := client.FleetV1alpha1().Fleets(fleet.GetNamespace()).Patch(context.TODO(), fleet.GetName(), types.MergePatchType, fleetPatchData, metav1.PatchOptions{}); patchErr != nil { + return patchErr + } } else { - return err + return createErr } } return nil } -// UpdateAttachedCluster update AttachedCluster -func UpdateFleet(client kurator.Interface, fleet *fleetv1a1.Fleet) error { - _, err := client.FleetV1alpha1().Fleets(fleet.Namespace).Update(context.TODO(), fleet, metav1.UpdateOptions{}) - if err != nil { - return err - } - return nil -} - func RemoveFleet(client kurator.Interface, namespace, name string) error { err := client.FleetV1alpha1().Fleets(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{}) if err != nil { diff --git a/e2e/resources/secret.go b/e2e/resources/secret.go index 78a69ee5..113d5e38 100644 --- a/e2e/resources/secret.go +++ b/e2e/resources/secret.go @@ -22,6 +22,7 @@ import ( corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" ) @@ -41,27 +42,30 @@ func NewSecret(namespace string, name string, data map[string][]byte) *corev1.Se } // CreateSecret create Secret. -func CreateSecret(client kubernetes.Interface, secret *corev1.Secret) error { - _, err := client.CoreV1().Secrets(secret.Namespace).Create(context.TODO(), secret, metav1.CreateOptions{}) - if err != nil { - if apierrors.IsAlreadyExists(err) { - return UpdateSecret(client, secret) +func CreateOrUpdateSecret(client kubernetes.Interface, secret *corev1.Secret) error { + _, createErr := client.CoreV1().Secrets(secret.GetNamespace()).Create(context.TODO(), secret, metav1.CreateOptions{}) + if createErr != nil { + if apierrors.IsAlreadyExists(createErr) { + originalSecret, getErr := client.CoreV1().Secrets(secret.GetNamespace()).Get(context.TODO(), secret.GetName(), metav1.GetOptions{}) + if getErr != nil { + return getErr + } + secret.ResourceVersion = originalSecret.ResourceVersion + secretPatchData, createPatchErr := CreatePatchData(originalSecret, secret) + if createPatchErr != nil { + return createPatchErr + } + _, patchErr := client.CoreV1().Secrets(secret.GetNamespace()).Patch(context.TODO(), secret.GetName(), types.StrategicMergePatchType, secretPatchData, metav1.PatchOptions{}) + if patchErr != nil { + return patchErr + } } else { - return err + return createErr } } return nil } -// UpdateSecret update Secret -func UpdateSecret(client kubernetes.Interface, secret *corev1.Secret) error { - _, err := client.CoreV1().Secrets(secret.Namespace).Update(context.TODO(), secret, metav1.UpdateOptions{}) - if err != nil { - return err - } - return nil -} - func RemoveSecret(client kubernetes.Interface, namespace, name string) error { err := client.CoreV1().Secrets(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{}) if err != nil { diff --git a/e2e/resources/util.go b/e2e/resources/util.go new file mode 100644 index 00000000..cf1a322b --- /dev/null +++ b/e2e/resources/util.go @@ -0,0 +1,39 @@ +/* +Copyright Kurator Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resources + +import ( + "encoding/json" + + jsonpatch "github.com/evanphx/json-patch" +) + +func CreatePatchData(originalAttachedCluster, modifiedAttachedCluster interface{}) ([]byte, error) { + originalData, originalErr := json.Marshal(originalAttachedCluster) + if originalErr != nil { + return nil, originalErr + } + modifiedData, modifiedErr := json.Marshal(modifiedAttachedCluster) + if modifiedErr != nil { + return nil, modifiedErr + } + patchData, createErr := jsonpatch.CreateMergePatch(originalData, modifiedData) + if createErr != nil { + return nil, createErr + } + return patchData, nil +} diff --git a/e2e/suite_test.go b/e2e/suite_test.go index a1644087..6619e8bb 100644 --- a/e2e/suite_test.go +++ b/e2e/suite_test.go @@ -92,10 +92,10 @@ var _ = ginkgo.SynchronizedBeforeSuite(func() []byte { } attachedcluster = resources.NewAttachedCluster(namespace, memberClusterName, secretKeyRef) - secretCreateErr := resources.CreateSecret(kubeClient, secret) + secretCreateErr := resources.CreateOrUpdateSecret(kubeClient, secret) gomega.Expect(secretCreateErr).ShouldNot(gomega.HaveOccurred()) - attachedCreateErr := resources.CreateAttachedCluster(kuratorClient, attachedcluster) + attachedCreateErr := resources.CreateOrUpdateAttachedCluster(kuratorClient, attachedcluster) gomega.Expect(attachedCreateErr).ShouldNot(gomega.HaveOccurred()) resources.WaitAttachedClusterFitWith(kuratorClient, namespace, memberClusterName, func(attachedCluster *clusterv1a1.AttachedCluster) bool { return attachedCluster.Status.Ready diff --git a/go.mod b/go.mod index 726227de..722dac7a 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/awslabs/goformation/v4 v4.19.5 github.com/cert-manager/cert-manager v1.10.0 github.com/coreos/go-semver v0.3.0 + github.com/evanphx/json-patch v5.6.0+incompatible github.com/fluxcd/flagger v1.34.0 github.com/fluxcd/helm-controller/api v0.32.2 github.com/fluxcd/kustomize-controller/api v1.0.0-rc.1 @@ -117,7 +118,6 @@ require ( github.com/emicklei/go-restful/v3 v3.10.2 // indirect github.com/envoyproxy/go-control-plane v0.11.1 // indirect github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect - github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/fatih/camelcase v1.0.0 // indirect From 80aabd102bb09c242f62a614eb41bc35c4bf2c1f Mon Sep 17 00:00:00 2001 From: LiZhenCheng9527 Date: Fri, 23 Feb 2024 16:27:26 +0800 Subject: [PATCH 2/4] fix comments Signed-off-by: LiZhenCheng9527 --- e2e/resources/attachedcluster.go | 2 +- e2e/resources/fleet.go | 2 +- e2e/resources/secret.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e/resources/attachedcluster.go b/e2e/resources/attachedcluster.go index ef183648..6b64cdb1 100644 --- a/e2e/resources/attachedcluster.go +++ b/e2e/resources/attachedcluster.go @@ -44,7 +44,7 @@ func NewAttachedCluster(namespace string, name string, config clusterv1a1.Secret } } -// CreateAttachedCluster create AttachedCluster. +// CreateAttachedCluster create or update AttachedCluster. func CreateOrUpdateAttachedCluster(client kurator.Interface, attachedCluster *clusterv1a1.AttachedCluster) error { _, createErr := client.ClusterV1alpha1().AttachedClusters(attachedCluster.GetNamespace()).Create(context.TODO(), attachedCluster, metav1.CreateOptions{}) if createErr != nil { diff --git a/e2e/resources/fleet.go b/e2e/resources/fleet.go index 13b29703..60fc367b 100644 --- a/e2e/resources/fleet.go +++ b/e2e/resources/fleet.go @@ -46,7 +46,7 @@ func NewFleet(namespace string, name string, clusters []*corev1.ObjectReference) } } -// CreateAttachedCluster create AttachedCluster. +// CreateAttachedCluster create or update Fleet. func CreateOrUpdateFleet(client kurator.Interface, fleet *fleetv1a1.Fleet) error { _, createErr := client.FleetV1alpha1().Fleets(fleet.GetNamespace()).Create(context.TODO(), fleet, metav1.CreateOptions{}) if createErr != nil { diff --git a/e2e/resources/secret.go b/e2e/resources/secret.go index 113d5e38..221427b5 100644 --- a/e2e/resources/secret.go +++ b/e2e/resources/secret.go @@ -41,7 +41,7 @@ func NewSecret(namespace string, name string, data map[string][]byte) *corev1.Se } } -// CreateSecret create Secret. +// CreateSecret create or update Secret. func CreateOrUpdateSecret(client kubernetes.Interface, secret *corev1.Secret) error { _, createErr := client.CoreV1().Secrets(secret.GetNamespace()).Create(context.TODO(), secret, metav1.CreateOptions{}) if createErr != nil { From 5de970359b3793a64a5cdb81dfe6f11372571a76 Mon Sep 17 00:00:00 2001 From: LiZhenCheng9527 Date: Fri, 23 Feb 2024 16:57:49 +0800 Subject: [PATCH 3/4] optimised install kurator strip Signed-off-by: LiZhenCheng9527 --- hack/e2e-test/install-kurator.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hack/e2e-test/install-kurator.sh b/hack/e2e-test/install-kurator.sh index fbc8ebcb..7b06cce1 100755 --- a/hack/e2e-test/install-kurator.sh +++ b/hack/e2e-test/install-kurator.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash - +# shellcheck disable=SC2086,SC1090,SC2206,SC1091 set -o errexit set -o nounset set -o pipefail From 421010a60456f591f3cdc900e048f4cac53a3e7a Mon Sep 17 00:00:00 2001 From: LiZhenCheng9527 Date: Tue, 27 Feb 2024 16:53:25 +0800 Subject: [PATCH 4/4] The original label of the object is preserved in Patch Signed-off-by: LiZhenCheng9527 --- e2e/resources/attachedcluster.go | 12 +++++++++-- e2e/resources/fleet.go | 12 +++++++++-- e2e/resources/secret.go | 12 +++++++++-- e2e/resources/util.go | 37 +++++++++++++++++++++++++++++--- 4 files changed, 64 insertions(+), 9 deletions(-) diff --git a/e2e/resources/attachedcluster.go b/e2e/resources/attachedcluster.go index 6b64cdb1..ae5dd238 100644 --- a/e2e/resources/attachedcluster.go +++ b/e2e/resources/attachedcluster.go @@ -53,8 +53,16 @@ func CreateOrUpdateAttachedCluster(client kurator.Interface, attachedCluster *cl if getErr != nil { return getErr } - attachedCluster.ResourceVersion = originalAttachedCluster.ResourceVersion - attachedClusterPatchData, createPatchErr := CreatePatchData(originalAttachedCluster, attachedCluster) + modifiedObjectMeta := ModifiedObjectMeta(originalAttachedCluster.ObjectMeta, attachedCluster.ObjectMeta) + oldAttachedCluster := clusterv1a1.AttachedCluster{ + ObjectMeta: originalAttachedCluster.ObjectMeta, + Spec: originalAttachedCluster.Spec, + } + modAttachedCluster := clusterv1a1.AttachedCluster{ + ObjectMeta: modifiedObjectMeta, + Spec: attachedCluster.Spec, + } + attachedClusterPatchData, createPatchErr := CreatePatchData(oldAttachedCluster, modAttachedCluster) if createPatchErr != nil { return createPatchErr } diff --git a/e2e/resources/fleet.go b/e2e/resources/fleet.go index 60fc367b..2aae959d 100644 --- a/e2e/resources/fleet.go +++ b/e2e/resources/fleet.go @@ -55,8 +55,16 @@ func CreateOrUpdateFleet(client kurator.Interface, fleet *fleetv1a1.Fleet) error if getErr != nil { return getErr } - fleet.ResourceVersion = originalFleet.ResourceVersion - fleetPatchData, createPatchErr := CreatePatchData(originalFleet, fleet) + modifiedObjectMeta := ModifiedObjectMeta(originalFleet.ObjectMeta, fleet.ObjectMeta) + oldFleet := fleetv1a1.Fleet{ + ObjectMeta: originalFleet.ObjectMeta, + Spec: originalFleet.Spec, + } + modFleet := fleetv1a1.Fleet{ + ObjectMeta: modifiedObjectMeta, + Spec: fleet.Spec, + } + fleetPatchData, createPatchErr := CreatePatchData(oldFleet, modFleet) if createPatchErr != nil { return createPatchErr } diff --git a/e2e/resources/secret.go b/e2e/resources/secret.go index 221427b5..50d723a9 100644 --- a/e2e/resources/secret.go +++ b/e2e/resources/secret.go @@ -50,8 +50,16 @@ func CreateOrUpdateSecret(client kubernetes.Interface, secret *corev1.Secret) er if getErr != nil { return getErr } - secret.ResourceVersion = originalSecret.ResourceVersion - secretPatchData, createPatchErr := CreatePatchData(originalSecret, secret) + modifiedObjectMeta := ModifiedObjectMeta(originalSecret.ObjectMeta, secret.ObjectMeta) + oldSecret := corev1.Secret{ + ObjectMeta: originalSecret.ObjectMeta, + Data: originalSecret.Data, + } + modSecret := corev1.Secret{ + ObjectMeta: modifiedObjectMeta, + Data: secret.Data, + } + secretPatchData, createPatchErr := CreatePatchData(oldSecret, modSecret) if createPatchErr != nil { return createPatchErr } diff --git a/e2e/resources/util.go b/e2e/resources/util.go index cf1a322b..e50d3d95 100644 --- a/e2e/resources/util.go +++ b/e2e/resources/util.go @@ -20,14 +20,15 @@ import ( "encoding/json" jsonpatch "github.com/evanphx/json-patch" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -func CreatePatchData(originalAttachedCluster, modifiedAttachedCluster interface{}) ([]byte, error) { - originalData, originalErr := json.Marshal(originalAttachedCluster) +func CreatePatchData(original, modified interface{}) ([]byte, error) { + originalData, originalErr := json.Marshal(original) if originalErr != nil { return nil, originalErr } - modifiedData, modifiedErr := json.Marshal(modifiedAttachedCluster) + modifiedData, modifiedErr := json.Marshal(modified) if modifiedErr != nil { return nil, modifiedErr } @@ -37,3 +38,33 @@ func CreatePatchData(originalAttachedCluster, modifiedAttachedCluster interface{ } return patchData, nil } + +func ModifiedObjectMeta(original, modified metav1.ObjectMeta) metav1.ObjectMeta { + if modified.Labels == nil { + modified.Labels = original.Labels + } else { + for k, v := range original.Labels { + if modified.Labels[k] == "" { + modified.Labels[k] = v + } + } + } + + if modified.Annotations == nil { + modified.Annotations = original.Annotations + } else { + for k, v := range original.Annotations { + if modified.Annotations[k] == "" { + modified.Annotations[k] = v + } + } + } + + if modified.Finalizers == nil { + modified.Finalizers = original.Finalizers + } + if modified.ResourceVersion == "" { + modified.ResourceVersion = original.ResourceVersion + } + return modified +}