feat: add resoruce id label
Signed-off-by: jwcesign <jwcesign@gmail.com>
This commit is contained in:
parent
d6e28817c3
commit
7e6387e98f
2
go.mod
2
go.mod
|
@ -11,6 +11,7 @@ require (
|
||||||
github.com/gogo/protobuf v1.3.2
|
github.com/gogo/protobuf v1.3.2
|
||||||
github.com/golang/mock v1.6.0
|
github.com/golang/mock v1.6.0
|
||||||
github.com/google/go-cmp v0.5.9
|
github.com/google/go-cmp v0.5.9
|
||||||
|
github.com/google/uuid v1.3.0
|
||||||
github.com/kr/pretty v0.3.1
|
github.com/kr/pretty v0.3.1
|
||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f
|
||||||
github.com/olekukonko/tablewriter v0.0.5
|
github.com/olekukonko/tablewriter v0.0.5
|
||||||
|
@ -100,7 +101,6 @@ require (
|
||||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
|
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
|
||||||
github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 // indirect
|
github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 // indirect
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
|
||||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
|
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
|
||||||
|
|
|
@ -1,6 +1,20 @@
|
||||||
package v1alpha1
|
package v1alpha1
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// PropagationPolicyPermanentIDLabel is the identifier of a PropagationPolicy object.
|
||||||
|
// Karmada generates a unique identifier, such as metadata.UUID, for each PropagationPolicy object.
|
||||||
|
// This identifier will be used as a label selector to locate corresponding resources, such as ResourceBinding.
|
||||||
|
// The reason for generating a new unique identifier instead of simply using metadata.UUID is because:
|
||||||
|
// In backup scenarios, when applying the backup resource manifest in a new cluster, the UUID may change.
|
||||||
|
PropagationPolicyPermanentIDLabel = "propagationpolicy.karmada.io/permanent-id"
|
||||||
|
|
||||||
|
// ClusterPropagationPolicyPermanentIDLabel is the identifier of a ClusterPropagationPolicy object.
|
||||||
|
// Karmada generates a unique identifier, such as metadata.UUID, for each ClusterPropagationPolicy object.
|
||||||
|
// This identifier will be used as a label selector to locate corresponding resources, such as ResourceBinding.
|
||||||
|
// The reason for generating a new unique identifier instead of simply using metadata.UUID is because:
|
||||||
|
// In backup scenarios, when applying the backup resource manifest in a new cluster, the UUID may change.
|
||||||
|
ClusterPropagationPolicyPermanentIDLabel = "clusterpropagationpolicy.karmada.io/permanent-id"
|
||||||
|
|
||||||
// PropagationPolicyUIDLabel is the uid of PropagationPolicy object.
|
// PropagationPolicyUIDLabel is the uid of PropagationPolicy object.
|
||||||
PropagationPolicyUIDLabel = "propagationpolicy.karmada.io/uid"
|
PropagationPolicyUIDLabel = "propagationpolicy.karmada.io/uid"
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,23 @@
|
||||||
package v1alpha2
|
package v1alpha2
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// ResourceBindingPermanentIDLabel is the identifier of a ResourceBinding object.
|
||||||
|
// Karmada generates a unique identifier, such as metadata.UUID, for each ResourceBinding object.
|
||||||
|
// This identifier will be used as a label selector to locate corresponding resources, such as Work.
|
||||||
|
// The reason for generating a new unique identifier instead of simply using metadata.UUID is because:
|
||||||
|
// In backup scenarios, when applying the backup resource manifest in a new cluster, the UUID may change.
|
||||||
|
ResourceBindingPermanentIDLabel = "resourcebinding.karmada.io/permanent-id"
|
||||||
|
|
||||||
|
// ClusterResourceBindingPermanentIDLabel is the identifier of a ClusterResourceBinding object.
|
||||||
|
// Karmada generates a unique identifier, such as metadata.UUID, for each ClusterResourceBinding object.
|
||||||
|
// This identifier will be used as a label selector to locate corresponding resources, such as Work.
|
||||||
|
// The reason for generating a new unique identifier instead of simply using metadata.UUID is because:
|
||||||
|
// In backup scenarios, when applying the backup resource manifest in a new cluster, the UUID may change.
|
||||||
|
ClusterResourceBindingPermanentIDLabel = "clusterresourcebinding.karmada.io/permanent-id"
|
||||||
|
|
||||||
|
// WorkPermanentIDLabel is the ID of Work object.
|
||||||
|
WorkPermanentIDLabel = "work.karmada.io/permanent-id"
|
||||||
|
|
||||||
// ResourceBindingUIDLabel is the UID of ResourceBinding object.
|
// ResourceBindingUIDLabel is the UID of ResourceBinding object.
|
||||||
ResourceBindingUIDLabel = "resourcebinding.karmada.io/uid"
|
ResourceBindingUIDLabel = "resourcebinding.karmada.io/uid"
|
||||||
|
|
||||||
|
|
|
@ -143,15 +143,23 @@ func mergeLabel(workload *unstructured.Unstructured, workNamespace string, bindi
|
||||||
util.MergeLabel(workload, workv1alpha1.WorkNameLabel, names.GenerateWorkName(workload.GetKind(), workload.GetName(), workload.GetNamespace()))
|
util.MergeLabel(workload, workv1alpha1.WorkNameLabel, names.GenerateWorkName(workload.GetKind(), workload.GetName(), workload.GetNamespace()))
|
||||||
util.MergeLabel(workload, util.ManagedByKarmadaLabel, util.ManagedByKarmadaLabelValue)
|
util.MergeLabel(workload, util.ManagedByKarmadaLabel, util.ManagedByKarmadaLabelValue)
|
||||||
if scope == apiextensionsv1.NamespaceScoped {
|
if scope == apiextensionsv1.NamespaceScoped {
|
||||||
|
util.RemoveLabels(workload, workv1alpha2.ResourceBindingUIDLabel)
|
||||||
|
|
||||||
|
bindingID := util.GetLabelValue(binding.GetLabels(), workv1alpha2.ResourceBindingPermanentIDLabel)
|
||||||
util.MergeLabel(workload, workv1alpha2.ResourceBindingReferenceKey, names.GenerateBindingReferenceKey(binding.GetNamespace(), binding.GetName()))
|
util.MergeLabel(workload, workv1alpha2.ResourceBindingReferenceKey, names.GenerateBindingReferenceKey(binding.GetNamespace(), binding.GetName()))
|
||||||
util.MergeLabel(workload, workv1alpha2.ResourceBindingUIDLabel, string(binding.GetUID()))
|
util.MergeLabel(workload, workv1alpha2.ResourceBindingPermanentIDLabel, bindingID)
|
||||||
|
|
||||||
workLabel[workv1alpha2.ResourceBindingReferenceKey] = names.GenerateBindingReferenceKey(binding.GetNamespace(), binding.GetName())
|
workLabel[workv1alpha2.ResourceBindingReferenceKey] = names.GenerateBindingReferenceKey(binding.GetNamespace(), binding.GetName())
|
||||||
workLabel[workv1alpha2.ResourceBindingUIDLabel] = string(binding.GetUID())
|
workLabel[workv1alpha2.ResourceBindingPermanentIDLabel] = bindingID
|
||||||
} else {
|
} else {
|
||||||
|
util.RemoveLabels(workload, workv1alpha2.ClusterResourceBindingUIDLabel)
|
||||||
|
|
||||||
|
bindingID := util.GetLabelValue(binding.GetLabels(), workv1alpha2.ClusterResourceBindingPermanentIDLabel)
|
||||||
util.MergeLabel(workload, workv1alpha2.ClusterResourceBindingReferenceKey, names.GenerateBindingReferenceKey("", binding.GetName()))
|
util.MergeLabel(workload, workv1alpha2.ClusterResourceBindingReferenceKey, names.GenerateBindingReferenceKey("", binding.GetName()))
|
||||||
util.MergeLabel(workload, workv1alpha2.ClusterResourceBindingUIDLabel, string(binding.GetUID()))
|
util.MergeLabel(workload, workv1alpha2.ClusterResourceBindingPermanentIDLabel, bindingID)
|
||||||
|
|
||||||
workLabel[workv1alpha2.ClusterResourceBindingReferenceKey] = names.GenerateBindingReferenceKey("", binding.GetName())
|
workLabel[workv1alpha2.ClusterResourceBindingReferenceKey] = names.GenerateBindingReferenceKey("", binding.GetName())
|
||||||
workLabel[workv1alpha2.ClusterResourceBindingUIDLabel] = string(binding.GetUID())
|
workLabel[workv1alpha2.ClusterResourceBindingPermanentIDLabel] = bindingID
|
||||||
}
|
}
|
||||||
return workLabel
|
return workLabel
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
|
|
||||||
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
|
||||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||||
|
@ -88,7 +87,7 @@ func Test_mergeTargetClusters(t *testing.T) {
|
||||||
func Test_mergeLabel(t *testing.T) {
|
func Test_mergeLabel(t *testing.T) {
|
||||||
namespace := "fake-ns"
|
namespace := "fake-ns"
|
||||||
bindingName := "fake-bindingName"
|
bindingName := "fake-bindingName"
|
||||||
rbUID := "93162d3c-ee8e-4995-9034-05f4d5d2c2b9"
|
rbID := "93162d3c-ee8e-4995-9034-05f4d5d2c2b9"
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -115,13 +114,15 @@ func Test_mergeLabel(t *testing.T) {
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: bindingName,
|
Name: bindingName,
|
||||||
Namespace: namespace,
|
Namespace: namespace,
|
||||||
UID: types.UID(rbUID),
|
Labels: map[string]string{
|
||||||
|
workv1alpha2.ResourceBindingPermanentIDLabel: rbID,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
scope: v1.NamespaceScoped,
|
scope: v1.NamespaceScoped,
|
||||||
want: map[string]string{
|
want: map[string]string{
|
||||||
workv1alpha2.ResourceBindingUIDLabel: rbUID,
|
workv1alpha2.ResourceBindingPermanentIDLabel: rbID,
|
||||||
workv1alpha2.ResourceBindingReferenceKey: names.GenerateBindingReferenceKey(namespace, bindingName),
|
workv1alpha2.ResourceBindingReferenceKey: names.GenerateBindingReferenceKey(namespace, bindingName),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -138,13 +139,15 @@ func Test_mergeLabel(t *testing.T) {
|
||||||
binding: &workv1alpha2.ClusterResourceBinding{
|
binding: &workv1alpha2.ClusterResourceBinding{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: bindingName,
|
Name: bindingName,
|
||||||
UID: types.UID(rbUID),
|
Labels: map[string]string{
|
||||||
|
workv1alpha2.ClusterResourceBindingPermanentIDLabel: rbID,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
scope: v1.ClusterScoped,
|
scope: v1.ClusterScoped,
|
||||||
want: map[string]string{
|
want: map[string]string{
|
||||||
workv1alpha2.ClusterResourceBindingUIDLabel: rbUID,
|
workv1alpha2.ClusterResourceBindingPermanentIDLabel: rbID,
|
||||||
workv1alpha2.ClusterResourceBindingReferenceKey: names.GenerateBindingReferenceKey("", bindingName),
|
workv1alpha2.ClusterResourceBindingReferenceKey: names.GenerateBindingReferenceKey("", bindingName),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,12 +190,12 @@ func (c *Controller) syncToClusters(clusterName string, work *workv1alpha1.Work)
|
||||||
for _, manifest := range work.Spec.Workload.Manifests {
|
for _, manifest := range work.Spec.Workload.Manifests {
|
||||||
workload := &unstructured.Unstructured{}
|
workload := &unstructured.Unstructured{}
|
||||||
err := workload.UnmarshalJSON(manifest.Raw)
|
err := workload.UnmarshalJSON(manifest.Raw)
|
||||||
util.MergeLabel(workload, workv1alpha2.WorkUIDLabel, string(work.UID))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf("Failed to unmarshal workload, error is: %v", err)
|
klog.Errorf("Failed to unmarshal workload, error is: %v", err)
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
util.MergeLabel(workload, workv1alpha2.WorkPermanentIDLabel, util.GetLabelValue(work.Labels, workv1alpha2.WorkPermanentIDLabel))
|
||||||
|
|
||||||
if err = c.tryCreateOrUpdateWorkload(clusterName, workload); err != nil {
|
if err = c.tryCreateOrUpdateWorkload(clusterName, workload); err != nil {
|
||||||
klog.Errorf("Failed to create or update resource(%v/%v) in the given member cluster %s, err is %v", workload.GetNamespace(), workload.GetName(), clusterName, err)
|
klog.Errorf("Failed to create or update resource(%v/%v) in the given member cluster %s, err is %v", workload.GetNamespace(), workload.GetName(), clusterName, err)
|
||||||
|
|
|
@ -71,7 +71,7 @@ func (r *HPAReplicasSyncer) Generic(e event.GenericEvent) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasBeenPropagated(hpa *autoscalingv2.HorizontalPodAutoscaler) bool {
|
func hasBeenPropagated(hpa *autoscalingv2.HorizontalPodAutoscaler) bool {
|
||||||
_, ppExist := hpa.GetLabels()[policyv1alpha1.PropagationPolicyUIDLabel]
|
_, ppExist := hpa.GetLabels()[policyv1alpha1.PropagationPolicyNameLabel]
|
||||||
_, cppExist := hpa.GetLabels()[policyv1alpha1.ClusterPropagationPolicyUIDLabel]
|
_, cppExist := hpa.GetLabels()[policyv1alpha1.ClusterPropagationPolicyLabel]
|
||||||
return ppExist || cppExist
|
return ppExist || cppExist
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
|
@ -45,6 +46,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// bindingDependedIdLabelKey is the resoruce id of the independent binding which the attached binding depends on.
|
||||||
|
bindingDependedIdLabelKey = "resourcebinding.karmada.io/depended-id"
|
||||||
|
|
||||||
// bindingDependedByLabelKeyPrefix is the prefix to a label key specifying an attached binding referred by which independent binding.
|
// bindingDependedByLabelKeyPrefix is the prefix to a label key specifying an attached binding referred by which independent binding.
|
||||||
// the key is in the label of an attached binding which should be unique, because resource like secret can be referred by multiple deployments.
|
// the key is in the label of an attached binding which should be unique, because resource like secret can be referred by multiple deployments.
|
||||||
bindingDependedByLabelKeyPrefix = "resourcebinding.karmada.io/depended-by-"
|
bindingDependedByLabelKeyPrefix = "resourcebinding.karmada.io/depended-by-"
|
||||||
|
@ -498,19 +502,14 @@ func (d *DependenciesDistributor) removeScheduleResultFromAttachedBindings(bindi
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DependenciesDistributor) createOrUpdateAttachedBinding(attachedBinding *workv1alpha2.ResourceBinding) error {
|
func (d *DependenciesDistributor) createOrUpdateAttachedBinding(attachedBinding *workv1alpha2.ResourceBinding) error {
|
||||||
if err := d.Client.Create(context.TODO(), attachedBinding); err != nil {
|
existBinding := &workv1alpha2.ResourceBinding{}
|
||||||
if !apierrors.IsAlreadyExists(err) {
|
key := client.ObjectKeyFromObject(attachedBinding)
|
||||||
klog.Infof("Failed to create resource binding(%s/%s): %v", attachedBinding.Namespace, attachedBinding.Name, err)
|
err := d.Client.Get(context.TODO(), key, existBinding)
|
||||||
return err
|
if err == nil {
|
||||||
|
if util.GetLabelValue(existBinding.Labels, workv1alpha2.ResourceBindingPermanentIDLabel) == "" {
|
||||||
|
existBinding.Labels = util.DedupeAndMergeLabels(existBinding.Labels,
|
||||||
|
map[string]string{workv1alpha2.ResourceBindingPermanentIDLabel: uuid.New().String()})
|
||||||
}
|
}
|
||||||
|
|
||||||
existBinding := &workv1alpha2.ResourceBinding{}
|
|
||||||
key := client.ObjectKeyFromObject(attachedBinding)
|
|
||||||
if err := d.Client.Get(context.TODO(), key, existBinding); err != nil {
|
|
||||||
klog.Infof("Failed to get resource binding(%s/%s): %v", attachedBinding.Namespace, attachedBinding.Name, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
existBinding.Spec.RequiredBy = mergeBindingSnapshot(existBinding.Spec.RequiredBy, attachedBinding.Spec.RequiredBy)
|
existBinding.Spec.RequiredBy = mergeBindingSnapshot(existBinding.Spec.RequiredBy, attachedBinding.Spec.RequiredBy)
|
||||||
existBinding.Labels = util.DedupeAndMergeLabels(existBinding.Labels, attachedBinding.Labels)
|
existBinding.Labels = util.DedupeAndMergeLabels(existBinding.Labels, attachedBinding.Labels)
|
||||||
existBinding.Spec.Resource = attachedBinding.Spec.Resource
|
existBinding.Spec.Resource = attachedBinding.Spec.Resource
|
||||||
|
@ -520,6 +519,17 @@ func (d *DependenciesDistributor) createOrUpdateAttachedBinding(attachedBinding
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !apierrors.IsNotFound(err) {
|
||||||
|
klog.Infof("Failed to get resource binding(%s/%s): %v", attachedBinding.Namespace, attachedBinding.Name, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
attachedBinding.Labels = util.DedupeAndMergeLabels(attachedBinding.Labels,
|
||||||
|
map[string]string{workv1alpha2.ResourceBindingPermanentIDLabel: uuid.New().String()})
|
||||||
|
if err := d.Client.Create(context.TODO(), attachedBinding); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,6 +640,8 @@ func buildAttachedBinding(binding *workv1alpha2.ResourceBinding, object *unstruc
|
||||||
Clusters: binding.Spec.Clusters,
|
Clusters: binding.Spec.Clusters,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
policyID := util.GetLabelValue(binding.Labels, workv1alpha2.ResourceBindingPermanentIDLabel)
|
||||||
|
dependedLabels = util.DedupeAndMergeLabels(dependedLabels, map[string]string{bindingDependedIdLabelKey: policyID})
|
||||||
return &workv1alpha2.ResourceBinding{
|
return &workv1alpha2.ResourceBinding{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: names.GenerateBindingName(object.GetKind(), object.GetName()),
|
Name: names.GenerateBindingName(object.GetKind(), object.GetName()),
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
|
@ -388,15 +389,16 @@ func (d *ResourceDetector) ApplyPolicy(object *unstructured.Unstructured, object
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := d.ClaimPolicyForObject(object, policy.Namespace, policy.Name, string(policy.UID)); err != nil {
|
policyID, err := d.ClaimPolicyForObject(object, policy)
|
||||||
|
if err != nil {
|
||||||
klog.Errorf("Failed to claim policy(%s) for object: %s", policy.Name, object)
|
klog.Errorf("Failed to claim policy(%s) for object: %s", policy.Name, object)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
policyLabels := map[string]string{
|
policyLabels := map[string]string{
|
||||||
policyv1alpha1.PropagationPolicyNamespaceLabel: policy.GetNamespace(),
|
policyv1alpha1.PropagationPolicyNamespaceLabel: policy.GetNamespace(),
|
||||||
policyv1alpha1.PropagationPolicyNameLabel: policy.GetName(),
|
policyv1alpha1.PropagationPolicyNameLabel: policy.GetName(),
|
||||||
policyv1alpha1.PropagationPolicyUIDLabel: string(policy.UID),
|
policyv1alpha1.PropagationPolicyPermanentIDLabel: policyID,
|
||||||
}
|
}
|
||||||
policyAnnotations := map[string]string{
|
policyAnnotations := map[string]string{
|
||||||
policyv1alpha1.PropagationPolicyNamespaceAnnotation: policy.GetNamespace(),
|
policyv1alpha1.PropagationPolicyNamespaceAnnotation: policy.GetNamespace(),
|
||||||
|
@ -417,6 +419,14 @@ func (d *ResourceDetector) ApplyPolicy(object *unstructured.Unstructured, object
|
||||||
return fmt.Errorf("failed to update binding due to different owner reference UID, will " +
|
return fmt.Errorf("failed to update binding due to different owner reference UID, will " +
|
||||||
"try again later after binding is garbage collected, see https://github.com/karmada-io/karmada/issues/2090")
|
"try again later after binding is garbage collected, see https://github.com/karmada-io/karmada/issues/2090")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Delete following two lines in release-1.9
|
||||||
|
delete(bindingCopy.Labels, workv1alpha2.ResourceBindingUIDLabel)
|
||||||
|
delete(bindingCopy.Labels, policyv1alpha1.PropagationPolicyUIDLabel)
|
||||||
|
if util.GetLabelValue(bindingCopy.Labels, workv1alpha2.ResourceBindingPermanentIDLabel) == "" {
|
||||||
|
bindingCopy.Labels = util.DedupeAndMergeLabels(bindingCopy.Labels,
|
||||||
|
map[string]string{workv1alpha2.ResourceBindingPermanentIDLabel: uuid.New().String()})
|
||||||
|
}
|
||||||
// Just update necessary fields, especially avoid modifying Spec.Clusters which is scheduling result, if already exists.
|
// Just update necessary fields, especially avoid modifying Spec.Clusters which is scheduling result, if already exists.
|
||||||
bindingCopy.Annotations = util.DedupeAndMergeAnnotations(bindingCopy.Annotations, binding.Annotations)
|
bindingCopy.Annotations = util.DedupeAndMergeAnnotations(bindingCopy.Annotations, binding.Annotations)
|
||||||
bindingCopy.Labels = util.DedupeAndMergeLabels(bindingCopy.Labels, binding.Labels)
|
bindingCopy.Labels = util.DedupeAndMergeLabels(bindingCopy.Labels, binding.Labels)
|
||||||
|
@ -469,14 +479,15 @@ func (d *ResourceDetector) ApplyClusterPolicy(object *unstructured.Unstructured,
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := d.ClaimClusterPolicyForObject(object, policy.Name, string(policy.UID)); err != nil {
|
policyID, err := d.ClaimClusterPolicyForObject(object, policy)
|
||||||
|
if err != nil {
|
||||||
klog.Errorf("Failed to claim cluster policy(%s) for object: %s", policy.Name, object)
|
klog.Errorf("Failed to claim cluster policy(%s) for object: %s", policy.Name, object)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
policyLabels := map[string]string{
|
policyLabels := map[string]string{
|
||||||
policyv1alpha1.ClusterPropagationPolicyLabel: policy.GetName(),
|
policyv1alpha1.ClusterPropagationPolicyLabel: policy.GetName(),
|
||||||
policyv1alpha1.ClusterPropagationPolicyUIDLabel: string(policy.UID),
|
policyv1alpha1.ClusterPropagationPolicyPermanentIDLabel: policyID,
|
||||||
}
|
}
|
||||||
policyAnnotations := map[string]string{
|
policyAnnotations := map[string]string{
|
||||||
policyv1alpha1.ClusterPropagationPolicyAnnotation: policy.GetName(),
|
policyv1alpha1.ClusterPropagationPolicyAnnotation: policy.GetName(),
|
||||||
|
@ -500,6 +511,14 @@ func (d *ResourceDetector) ApplyClusterPolicy(object *unstructured.Unstructured,
|
||||||
return fmt.Errorf("failed to update binding due to different owner reference UID, will " +
|
return fmt.Errorf("failed to update binding due to different owner reference UID, will " +
|
||||||
"try again later after binding is garbage collected, see https://github.com/karmada-io/karmada/issues/2090")
|
"try again later after binding is garbage collected, see https://github.com/karmada-io/karmada/issues/2090")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Delete following two lines in release-1.9
|
||||||
|
delete(bindingCopy.Labels, workv1alpha2.ResourceBindingUIDLabel)
|
||||||
|
delete(bindingCopy.Labels, policyv1alpha1.ClusterPropagationPolicyUIDLabel)
|
||||||
|
if util.GetLabelValue(bindingCopy.Labels, workv1alpha2.ResourceBindingPermanentIDLabel) == "" {
|
||||||
|
bindingCopy.Labels = util.DedupeAndMergeLabels(bindingCopy.Labels,
|
||||||
|
map[string]string{workv1alpha2.ResourceBindingPermanentIDLabel: uuid.New().String()})
|
||||||
|
}
|
||||||
// Just update necessary fields, especially avoid modifying Spec.Clusters which is scheduling result, if already exists.
|
// Just update necessary fields, especially avoid modifying Spec.Clusters which is scheduling result, if already exists.
|
||||||
bindingCopy.Annotations = util.DedupeAndMergeAnnotations(bindingCopy.Annotations, binding.Annotations)
|
bindingCopy.Annotations = util.DedupeAndMergeAnnotations(bindingCopy.Annotations, binding.Annotations)
|
||||||
bindingCopy.Labels = util.DedupeAndMergeLabels(bindingCopy.Labels, binding.Labels)
|
bindingCopy.Labels = util.DedupeAndMergeLabels(bindingCopy.Labels, binding.Labels)
|
||||||
|
@ -547,6 +566,14 @@ func (d *ResourceDetector) ApplyClusterPolicy(object *unstructured.Unstructured,
|
||||||
return fmt.Errorf("failed to update binding due to different owner reference UID, will " +
|
return fmt.Errorf("failed to update binding due to different owner reference UID, will " +
|
||||||
"try again later after binding is garbage collected, see https://github.com/karmada-io/karmada/issues/2090")
|
"try again later after binding is garbage collected, see https://github.com/karmada-io/karmada/issues/2090")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: delete following two lines in release-1.9
|
||||||
|
delete(bindingCopy.Labels, workv1alpha2.ClusterResourceBindingUIDLabel)
|
||||||
|
delete(bindingCopy.Labels, policyv1alpha1.ClusterPropagationPolicyUIDLabel)
|
||||||
|
if util.GetLabelValue(bindingCopy.Labels, workv1alpha2.ClusterResourceBindingPermanentIDLabel) == "" {
|
||||||
|
bindingCopy.Labels = util.DedupeAndMergeLabels(bindingCopy.Labels,
|
||||||
|
map[string]string{workv1alpha2.ClusterResourceBindingPermanentIDLabel: uuid.New().String()})
|
||||||
|
}
|
||||||
// Just update necessary fields, especially avoid modifying Spec.Clusters which is scheduling result, if already exists.
|
// Just update necessary fields, especially avoid modifying Spec.Clusters which is scheduling result, if already exists.
|
||||||
bindingCopy.Annotations = util.DedupeAndMergeAnnotations(bindingCopy.Annotations, binding.Annotations)
|
bindingCopy.Annotations = util.DedupeAndMergeAnnotations(bindingCopy.Annotations, binding.Annotations)
|
||||||
bindingCopy.Labels = util.DedupeAndMergeLabels(bindingCopy.Labels, binding.Labels)
|
bindingCopy.Labels = util.DedupeAndMergeLabels(bindingCopy.Labels, binding.Labels)
|
||||||
|
@ -614,51 +641,95 @@ func (d *ResourceDetector) GetUnstructuredObject(objectKey keys.ClusterWideKey)
|
||||||
return unstructuredObj, nil
|
return unstructuredObj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *ResourceDetector) getPropagationPolicyID(policy *policyv1alpha1.PropagationPolicy) (string, error) {
|
||||||
|
id := util.GetLabelValue(policy.GetLabels(), policyv1alpha1.PropagationPolicyPermanentIDLabel)
|
||||||
|
if id == "" {
|
||||||
|
id = uuid.New().String()
|
||||||
|
policy.Labels = util.DedupeAndMergeLabels(policy.Labels, map[string]string{policyv1alpha1.PropagationPolicyPermanentIDLabel: id})
|
||||||
|
if err := d.Client.Update(context.TODO(), policy); err != nil {
|
||||||
|
return id, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ClaimPolicyForObject set policy identifier which the object associated with.
|
// ClaimPolicyForObject set policy identifier which the object associated with.
|
||||||
func (d *ResourceDetector) ClaimPolicyForObject(object *unstructured.Unstructured, policyNamespace, policyName, policyUID string) error {
|
func (d *ResourceDetector) ClaimPolicyForObject(object *unstructured.Unstructured, policy *policyv1alpha1.PropagationPolicy) (string, error) {
|
||||||
|
policyID, err := d.getPropagationPolicyID(policy)
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf("Get PropagationPolicy(%s/%s) ID error:%v", policy.Namespace, policy.Name, err)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
objLabels := object.GetLabels()
|
objLabels := object.GetLabels()
|
||||||
if objLabels == nil {
|
if objLabels == nil {
|
||||||
objLabels = make(map[string]string)
|
objLabels = make(map[string]string)
|
||||||
} else if len(objLabels) > 0 {
|
} else if len(objLabels) > 0 {
|
||||||
// object has been claimed, don't need to claim again
|
// object has been claimed, don't need to claim again
|
||||||
if !excludeClusterPolicy(objLabels) &&
|
if !excludeClusterPolicy(objLabels) &&
|
||||||
objLabels[policyv1alpha1.PropagationPolicyNamespaceLabel] == policyNamespace &&
|
objLabels[policyv1alpha1.PropagationPolicyPermanentIDLabel] == policyID {
|
||||||
objLabels[policyv1alpha1.PropagationPolicyNameLabel] == policyName {
|
return policyID, nil
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
objLabels[policyv1alpha1.PropagationPolicyNamespaceLabel] = policyNamespace
|
// Delete following line when release-1.9
|
||||||
objLabels[policyv1alpha1.PropagationPolicyNameLabel] = policyName
|
delete(objLabels, policyv1alpha1.PropagationPolicyUIDLabel)
|
||||||
objLabels[policyv1alpha1.PropagationPolicyUIDLabel] = policyUID
|
objLabels[policyv1alpha1.PropagationPolicyNamespaceLabel] = policy.Namespace
|
||||||
|
objLabels[policyv1alpha1.PropagationPolicyNameLabel] = policy.Name
|
||||||
|
objLabels[policyv1alpha1.PropagationPolicyPermanentIDLabel] = policyID
|
||||||
|
|
||||||
objectAnnotations := object.GetAnnotations()
|
objectAnnotations := object.GetAnnotations()
|
||||||
if objectAnnotations == nil {
|
if objectAnnotations == nil {
|
||||||
objectAnnotations = make(map[string]string)
|
objectAnnotations = make(map[string]string)
|
||||||
}
|
}
|
||||||
objectAnnotations[policyv1alpha1.PropagationPolicyNamespaceAnnotation] = policyNamespace
|
objectAnnotations[policyv1alpha1.PropagationPolicyNamespaceAnnotation] = policy.Namespace
|
||||||
objectAnnotations[policyv1alpha1.PropagationPolicyNameAnnotation] = policyName
|
objectAnnotations[policyv1alpha1.PropagationPolicyNameAnnotation] = policy.Name
|
||||||
|
|
||||||
objectCopy := object.DeepCopy()
|
objectCopy := object.DeepCopy()
|
||||||
objectCopy.SetLabels(objLabels)
|
objectCopy.SetLabels(objLabels)
|
||||||
objectCopy.SetAnnotations(objectAnnotations)
|
objectCopy.SetAnnotations(objectAnnotations)
|
||||||
return d.Client.Update(context.TODO(), objectCopy)
|
return policyID, d.Client.Update(context.TODO(), objectCopy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClaimClusterPolicyForObject set cluster identifier which the object associated with.
|
func (d *ResourceDetector) getClusterPropagationPolicyID(policy *policyv1alpha1.ClusterPropagationPolicy) (string, error) {
|
||||||
func (d *ResourceDetector) ClaimClusterPolicyForObject(object *unstructured.Unstructured, policyName, policyUID string) error {
|
id := util.GetLabelValue(policy.GetLabels(), policyv1alpha1.ClusterPropagationPolicyPermanentIDLabel)
|
||||||
claimedName := util.GetLabelValue(object.GetLabels(), policyv1alpha1.ClusterPropagationPolicyLabel)
|
if id == "" {
|
||||||
|
id = uuid.New().String()
|
||||||
|
policy.Labels = util.DedupeAndMergeLabels(policy.Labels, map[string]string{policyv1alpha1.ClusterPropagationPolicyPermanentIDLabel: id})
|
||||||
|
if err := d.Client.Update(context.TODO(), policy); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClaimClusterPolicyForObject set cluster identifier which the object associated with
|
||||||
|
func (d *ResourceDetector) ClaimClusterPolicyForObject(object *unstructured.Unstructured, policy *policyv1alpha1.ClusterPropagationPolicy) (string, error) {
|
||||||
|
policyID, err := d.getClusterPropagationPolicyID(policy)
|
||||||
|
if err != nil {
|
||||||
|
klog.Errorf("Get ClusterPropagationPolicy(%s) ID error:%v", policy.Name, err)
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
claimedID := util.GetLabelValue(object.GetLabels(), policyv1alpha1.ClusterPropagationPolicyPermanentIDLabel)
|
||||||
// object has been claimed, don't need to claim again
|
// object has been claimed, don't need to claim again
|
||||||
if claimedName == policyName {
|
if claimedID == policyID {
|
||||||
return nil
|
return policyID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
objectCopy := object.DeepCopy()
|
objectCopy := object.DeepCopy()
|
||||||
util.MergeLabel(objectCopy, policyv1alpha1.ClusterPropagationPolicyLabel, policyName)
|
// TODO: delete following 3 lines in release-1.9
|
||||||
util.MergeLabel(objectCopy, policyv1alpha1.ClusterPropagationPolicyUIDLabel, policyUID)
|
labels := objectCopy.GetLabels()
|
||||||
|
delete(labels, policyv1alpha1.ClusterPropagationPolicyUIDLabel)
|
||||||
|
objectCopy.SetLabels(labels)
|
||||||
|
|
||||||
util.MergeAnnotation(objectCopy, policyv1alpha1.ClusterPropagationPolicyAnnotation, policyName)
|
util.MergeLabel(objectCopy, policyv1alpha1.ClusterPropagationPolicyLabel, policy.Name)
|
||||||
return d.Client.Update(context.TODO(), objectCopy)
|
util.MergeLabel(objectCopy, policyv1alpha1.ClusterPropagationPolicyPermanentIDLabel, policyID)
|
||||||
|
|
||||||
|
util.MergeAnnotation(objectCopy, policyv1alpha1.ClusterPropagationPolicyAnnotation, policy.Name)
|
||||||
|
return policyID, d.Client.Update(context.TODO(), objectCopy)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildResourceBinding builds a desired ResourceBinding for object.
|
// BuildResourceBinding builds a desired ResourceBinding for object.
|
||||||
|
|
|
@ -119,7 +119,7 @@ func (d *ResourceDetector) preemptPropagationPolicy(resourceTemplate *unstructur
|
||||||
"Propagation policy(%s/%s) preempted propagation policy(%s/%s) successfully", policy.Namespace, policy.Name, claimedPolicyNamespace, claimedPolicyName)
|
"Propagation policy(%s/%s) preempted propagation policy(%s/%s) successfully", policy.Namespace, policy.Name, claimedPolicyNamespace, claimedPolicyName)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err = d.ClaimPolicyForObject(resourceTemplate, policy.Namespace, policy.Name, string(policy.UID)); err != nil {
|
if _, err = d.ClaimPolicyForObject(resourceTemplate, policy); err != nil {
|
||||||
klog.Errorf("Failed to claim new propagation policy(%s/%s) on resource template(%s, kind=%s, %s): %v.", policy.Namespace, policy.Name,
|
klog.Errorf("Failed to claim new propagation policy(%s/%s) on resource template(%s, kind=%s, %s): %v.", policy.Namespace, policy.Name,
|
||||||
resourceTemplate.GetAPIVersion(), resourceTemplate.GetKind(), names.NamespacedKey(resourceTemplate.GetNamespace(), resourceTemplate.GetName()), err)
|
resourceTemplate.GetAPIVersion(), resourceTemplate.GetKind(), names.NamespacedKey(resourceTemplate.GetNamespace(), resourceTemplate.GetName()), err)
|
||||||
return err
|
return err
|
||||||
|
@ -147,7 +147,7 @@ func (d *ResourceDetector) preemptClusterPropagationPolicyDirectly(resourceTempl
|
||||||
"Propagation policy(%s/%s) preempted cluster propagation policy(%s) successfully", policy.Namespace, policy.Name, claimedPolicyName)
|
"Propagation policy(%s/%s) preempted cluster propagation policy(%s) successfully", policy.Namespace, policy.Name, claimedPolicyName)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err = d.ClaimPolicyForObject(resourceTemplate, policy.Namespace, policy.Name, string(policy.UID)); err != nil {
|
if _, err = d.ClaimPolicyForObject(resourceTemplate, policy); err != nil {
|
||||||
klog.Errorf("Failed to claim new propagation policy(%s/%s) on resource template(%s, kind=%s, %s) directly: %v.", policy.Namespace, policy.Name,
|
klog.Errorf("Failed to claim new propagation policy(%s/%s) on resource template(%s, kind=%s, %s) directly: %v.", policy.Namespace, policy.Name,
|
||||||
resourceTemplate.GetAPIVersion(), resourceTemplate.GetKind(), names.NamespacedKey(resourceTemplate.GetNamespace(), resourceTemplate.GetName()), err)
|
resourceTemplate.GetAPIVersion(), resourceTemplate.GetKind(), names.NamespacedKey(resourceTemplate.GetNamespace(), resourceTemplate.GetName()), err)
|
||||||
return err
|
return err
|
||||||
|
@ -197,7 +197,7 @@ func (d *ResourceDetector) preemptClusterPropagationPolicy(resourceTemplate *uns
|
||||||
"Cluster propagation policy(%s) preempted cluster propagation policy(%s) successfully", policy.Name, claimedPolicyName)
|
"Cluster propagation policy(%s) preempted cluster propagation policy(%s) successfully", policy.Name, claimedPolicyName)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err = d.ClaimClusterPolicyForObject(resourceTemplate, policy.Name, string(policy.UID)); err != nil {
|
if _, err = d.ClaimClusterPolicyForObject(resourceTemplate, policy); err != nil {
|
||||||
klog.Errorf("Failed to claim new cluster propagation policy(%s) on resource template(%s, kind=%s, %s): %v.", policy.Name,
|
klog.Errorf("Failed to claim new cluster propagation policy(%s) on resource template(%s, kind=%s, %s): %v.", policy.Name,
|
||||||
resourceTemplate.GetAPIVersion(), resourceTemplate.GetKind(), names.NamespacedKey(resourceTemplate.GetNamespace(), resourceTemplate.GetName()), err)
|
resourceTemplate.GetAPIVersion(), resourceTemplate.GetKind(), names.NamespacedKey(resourceTemplate.GetNamespace(), resourceTemplate.GetName()), err)
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
@ -29,7 +30,6 @@ func CreateOrUpdateWork(client client.Client, workMeta metav1.ObjectMeta, resour
|
||||||
}
|
}
|
||||||
util.MergeAnnotation(workload, workv1alpha2.ResourceTemplateUIDAnnotation, string(workload.GetUID()))
|
util.MergeAnnotation(workload, workv1alpha2.ResourceTemplateUIDAnnotation, string(workload.GetUID()))
|
||||||
util.RecordManagedAnnotations(workload)
|
util.RecordManagedAnnotations(workload)
|
||||||
util.RecordManagedLabels(workload)
|
|
||||||
workloadJSON, err := workload.MarshalJSON()
|
workloadJSON, err := workload.MarshalJSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.Errorf("Failed to marshal workload(%s/%s), Error: %v", workload.GetNamespace(), workload.GetName(), err)
|
klog.Errorf("Failed to marshal workload(%s/%s), Error: %v", workload.GetNamespace(), workload.GetName(), err)
|
||||||
|
@ -58,9 +58,16 @@ func CreateOrUpdateWork(client client.Client, workMeta metav1.ObjectMeta, resour
|
||||||
if !runtimeObject.DeletionTimestamp.IsZero() {
|
if !runtimeObject.DeletionTimestamp.IsZero() {
|
||||||
return fmt.Errorf("work %s/%s is being deleted", runtimeObject.GetNamespace(), runtimeObject.GetName())
|
return fmt.Errorf("work %s/%s is being deleted", runtimeObject.GetNamespace(), runtimeObject.GetName())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Delete following one line in release-1.9
|
||||||
|
delete(runtimeObject.Labels, workv1alpha2.WorkUIDLabel)
|
||||||
runtimeObject.Spec = work.Spec
|
runtimeObject.Spec = work.Spec
|
||||||
runtimeObject.Labels = work.Labels
|
runtimeObject.Labels = work.Labels
|
||||||
runtimeObject.Annotations = work.Annotations
|
runtimeObject.Annotations = work.Annotations
|
||||||
|
if util.GetLabelValue(runtimeObject.Labels, workv1alpha2.WorkPermanentIDLabel) == "" {
|
||||||
|
runtimeObject.Labels = util.DedupeAndMergeLabels(runtimeObject.Labels, map[string]string{workv1alpha2.WorkPermanentIDLabel: uuid.New().String()})
|
||||||
|
}
|
||||||
|
util.RecordManagedLabels(runtimeObject)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
|
|
||||||
|
workv1alpha1 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha1"
|
||||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -42,6 +43,8 @@ func RetainLabels(desired *unstructured.Unstructured, observed *unstructured.Uns
|
||||||
}
|
}
|
||||||
labels[key] = value
|
labels[key] = value
|
||||||
}
|
}
|
||||||
|
// TODO: Delete following one line in release-1.9
|
||||||
|
delete(labels, workv1alpha2.WorkUIDLabel)
|
||||||
if len(labels) > 0 {
|
if len(labels) > 0 {
|
||||||
desired.SetLabels(labels)
|
desired.SetLabels(labels)
|
||||||
}
|
}
|
||||||
|
@ -92,18 +95,18 @@ func getDeletedLabelKeys(desired, observed *unstructured.Unstructured) sets.Set[
|
||||||
|
|
||||||
// RecordManagedLabels sets or updates the annotation(resourcetemplate.karmada.io/managed-labels)
|
// RecordManagedLabels sets or updates the annotation(resourcetemplate.karmada.io/managed-labels)
|
||||||
// to record the label keys.
|
// to record the label keys.
|
||||||
func RecordManagedLabels(object *unstructured.Unstructured) {
|
func RecordManagedLabels(w *workv1alpha1.Work) {
|
||||||
annotations := object.GetAnnotations()
|
annotations := w.GetAnnotations()
|
||||||
if annotations == nil {
|
if annotations == nil {
|
||||||
annotations = make(map[string]string, 1)
|
annotations = make(map[string]string, 1)
|
||||||
}
|
}
|
||||||
var managedKeys []string
|
var managedKeys []string
|
||||||
// record labels.
|
// record labels.
|
||||||
labels := object.GetLabels()
|
labels := w.GetLabels()
|
||||||
for key := range labels {
|
for key := range labels {
|
||||||
managedKeys = append(managedKeys, key)
|
managedKeys = append(managedKeys, key)
|
||||||
}
|
}
|
||||||
sort.Strings(managedKeys)
|
sort.Strings(managedKeys)
|
||||||
annotations[workv1alpha2.ManagedLabels] = strings.Join(managedKeys, ",")
|
annotations[workv1alpha2.ManagedLabels] = strings.Join(managedKeys, ",")
|
||||||
object.SetAnnotations(annotations)
|
w.SetAnnotations(annotations)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,10 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
|
||||||
|
workv1alpha1 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha1"
|
||||||
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -510,71 +512,65 @@ func TestRetainLabels(t *testing.T) {
|
||||||
func TestRecordManagedLabels(t *testing.T) {
|
func TestRecordManagedLabels(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
object *unstructured.Unstructured
|
object *workv1alpha1.Work
|
||||||
expected *unstructured.Unstructured
|
expected *workv1alpha1.Work
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "nil label",
|
name: "nil label",
|
||||||
object: &unstructured.Unstructured{
|
object: &workv1alpha1.Work{
|
||||||
Object: map[string]interface{}{
|
TypeMeta: metav1.TypeMeta{
|
||||||
"apiVersion": "apps/v1",
|
APIVersion: "work.karmada.io/v1alpha1",
|
||||||
"kind": "Deployment",
|
Kind: "Work",
|
||||||
"metadata": map[string]interface{}{
|
},
|
||||||
"name": "demo-deployment-1",
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
},
|
Name: "demo-work-1",
|
||||||
"spec": map[string]interface{}{
|
Namespace: "cluster1-ns",
|
||||||
"replicas": 2,
|
Labels: nil,
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: &unstructured.Unstructured{
|
expected: &workv1alpha1.Work{
|
||||||
Object: map[string]interface{}{
|
TypeMeta: metav1.TypeMeta{
|
||||||
"apiVersion": "apps/v1",
|
APIVersion: "work.karmada.io/v1alpha1",
|
||||||
"kind": "Deployment",
|
Kind: "Work",
|
||||||
"metadata": map[string]interface{}{
|
},
|
||||||
"name": "demo-deployment-1",
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
"annotations": map[string]interface{}{
|
Name: "demo-work-1",
|
||||||
workv1alpha2.ManagedLabels: "",
|
Namespace: "cluster1-ns",
|
||||||
},
|
Annotations: map[string]string{
|
||||||
},
|
workv1alpha2.ManagedLabels: "",
|
||||||
"spec": map[string]interface{}{
|
|
||||||
"replicas": 2,
|
|
||||||
},
|
},
|
||||||
|
Labels: nil,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "object has has labels",
|
name: "object has has labels",
|
||||||
object: &unstructured.Unstructured{
|
object: &workv1alpha1.Work{
|
||||||
Object: map[string]interface{}{
|
TypeMeta: metav1.TypeMeta{
|
||||||
"apiVersion": "apps/v1",
|
APIVersion: "work.karmada.io/v1alpha1",
|
||||||
"kind": "Deployment",
|
Kind: "Work",
|
||||||
"metadata": map[string]interface{}{
|
},
|
||||||
"name": "demo-deployment-1",
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
"labels": map[string]interface{}{
|
Name: "demo-work-1",
|
||||||
"foo": "foo",
|
Namespace: "cluster1-ns",
|
||||||
},
|
Labels: map[string]string{
|
||||||
},
|
"foo": "bar",
|
||||||
"spec": map[string]interface{}{
|
|
||||||
"replicas": 2,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expected: &unstructured.Unstructured{
|
expected: &workv1alpha1.Work{
|
||||||
Object: map[string]interface{}{
|
TypeMeta: metav1.TypeMeta{
|
||||||
"apiVersion": "apps/v1",
|
APIVersion: "work.karmada.io/v1alpha1",
|
||||||
"kind": "Deployment",
|
Kind: "Work",
|
||||||
"metadata": map[string]interface{}{
|
},
|
||||||
"name": "demo-deployment-1",
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
"annotations": map[string]interface{}{
|
Name: "demo-work-1",
|
||||||
workv1alpha2.ManagedLabels: "foo",
|
Namespace: "cluster1-ns",
|
||||||
},
|
Annotations: map[string]string{
|
||||||
"labels": map[string]interface{}{
|
workv1alpha2.ManagedLabels: "foo",
|
||||||
"foo": "foo",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
"spec": map[string]interface{}{
|
Labels: map[string]string{
|
||||||
"replicas": 2,
|
"foo": "bar",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue