Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feature: Add the UID of the owner resource in labels and include the details in annotations. #4007

Merged
merged 1 commit into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions pkg/apis/policy/v1alpha1/well_known_constants.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
package v1alpha1

const (
// PropagationPolicyUIDLabel is the uid of PropagationPolicy object.
PropagationPolicyUIDLabel = "propagationpolicy.karmada.io/uid"

// PropagationPolicyNamespaceAnnotation is added to objects to specify associated PropagationPolicy namespace.
PropagationPolicyNamespaceAnnotation = "propagationpolicy.karmada.io/namespace"

// PropagationPolicyNameAnnotation is added to objects to specify associated PropagationPolicy name.
PropagationPolicyNameAnnotation = "propagationpolicy.karmada.io/name"

// ClusterPropagationPolicyUIDLabel is the uid of ClusterPropagationPolicy object.
ClusterPropagationPolicyUIDLabel = "clusterpropagationpolicy.karmada.io/uid"

// ClusterPropagationPolicyAnnotation is added to objects to specify associated ClusterPropagationPolicy name.
ClusterPropagationPolicyAnnotation = "clusterpropagationpolicy.karmada.io/name"

// PropagationPolicyNamespaceLabel is added to objects to specify associated PropagationPolicy namespace.
PropagationPolicyNamespaceLabel = "propagationpolicy.karmada.io/namespace"

Expand Down
15 changes: 15 additions & 0 deletions pkg/apis/work/v1alpha2/well_known_constants.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
package v1alpha2

const (
// ResourceBindingUIDLabel is the UID of ResourceBinding object.
ResourceBindingUIDLabel = "resourcebinding.karmada.io/uid"

// ClusterResourceBindingUIDLabel is the uid of ClusterResourceBinding object.
ClusterResourceBindingUIDLabel = "clusterresourcebinding.karmada.io/uid"

// WorkNamespaceAnnotation is added to objects to specify associated Work's namespace.
WorkNamespaceAnnotation = "work.karmada.io/namespace"

// WorkNameAnnotation is added to objects to specify associated Work's name.
WorkNameAnnotation = "work.karmada.io/name"

// WorkUIDLabel is the uid of Work object.
WorkUIDLabel = "work.karmada.io/uid"

// ResourceBindingReferenceKey is the key of ResourceBinding object.
// It is usually a unique hash value of ResourceBinding object's namespace and name, intended to be added to the Work object.
// It will be used to retrieve all Works objects that derived from a specific ResourceBinding object.
Expand Down
11 changes: 9 additions & 2 deletions pkg/controllers/binding/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func ensureWork(
}
workLabel := mergeLabel(clonedWorkload, workNamespace, binding, scope)

annotations := mergeAnnotations(clonedWorkload, binding, scope)
annotations := mergeAnnotations(clonedWorkload, workNamespace, binding, scope)
annotations = mergeConflictResolution(clonedWorkload, conflictResolutionInBinding, annotations)
annotations, err = RecordAppliedOverrides(cops, ops, annotations)
if err != nil {
Expand Down Expand Up @@ -144,16 +144,23 @@ func mergeLabel(workload *unstructured.Unstructured, workNamespace string, bindi
util.MergeLabel(workload, util.ManagedByKarmadaLabel, util.ManagedByKarmadaLabelValue)
if scope == apiextensionsv1.NamespaceScoped {
util.MergeLabel(workload, workv1alpha2.ResourceBindingReferenceKey, names.GenerateBindingReferenceKey(binding.GetNamespace(), binding.GetName()))
util.MergeLabel(workload, workv1alpha2.ResourceBindingUIDLabel, string(binding.GetUID()))
workLabel[workv1alpha2.ResourceBindingReferenceKey] = names.GenerateBindingReferenceKey(binding.GetNamespace(), binding.GetName())
workLabel[workv1alpha2.ResourceBindingUIDLabel] = string(binding.GetUID())
} else {
util.MergeLabel(workload, workv1alpha2.ClusterResourceBindingReferenceKey, names.GenerateBindingReferenceKey("", binding.GetName()))
util.MergeLabel(workload, workv1alpha2.ClusterResourceBindingUIDLabel, string(binding.GetUID()))
workLabel[workv1alpha2.ClusterResourceBindingReferenceKey] = names.GenerateBindingReferenceKey("", binding.GetName())
workLabel[workv1alpha2.ClusterResourceBindingUIDLabel] = string(binding.GetUID())
}
return workLabel
}

func mergeAnnotations(workload *unstructured.Unstructured, binding metav1.Object, scope apiextensionsv1.ResourceScope) map[string]string {
func mergeAnnotations(workload *unstructured.Unstructured, workNamespace string, binding metav1.Object, scope apiextensionsv1.ResourceScope) map[string]string {
annotations := make(map[string]string)
util.MergeAnnotation(workload, workv1alpha2.WorkNameAnnotation, names.GenerateWorkName(workload.GetKind(), workload.GetName(), workload.GetNamespace()))
util.MergeAnnotation(workload, workv1alpha2.WorkNamespaceAnnotation, workNamespace)

if scope == apiextensionsv1.NamespaceScoped {
util.MergeAnnotation(workload, workv1alpha2.ResourceBindingNamespaceAnnotationKey, binding.GetNamespace())
util.MergeAnnotation(workload, workv1alpha2.ResourceBindingNameAnnotationKey, binding.GetName())
Expand Down
25 changes: 17 additions & 8 deletions pkg/controllers/binding/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"

policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
Expand Down Expand Up @@ -87,6 +88,7 @@ func Test_mergeTargetClusters(t *testing.T) {
func Test_mergeLabel(t *testing.T) {
namespace := "fake-ns"
bindingName := "fake-bindingName"
rbUID := "93162d3c-ee8e-4995-9034-05f4d5d2c2b9"

tests := []struct {
name string
Expand All @@ -113,10 +115,12 @@ func Test_mergeLabel(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: bindingName,
Namespace: namespace,
UID: types.UID(rbUID),
},
},
scope: v1.NamespaceScoped,
want: map[string]string{
workv1alpha2.ResourceBindingUIDLabel: rbUID,
workv1alpha2.ResourceBindingReferenceKey: names.GenerateBindingReferenceKey(namespace, bindingName),
},
},
Expand All @@ -134,10 +138,12 @@ func Test_mergeLabel(t *testing.T) {
binding: &workv1alpha2.ClusterResourceBinding{
ObjectMeta: metav1.ObjectMeta{
Name: bindingName,
UID: types.UID(rbUID),
},
},
scope: v1.ClusterScoped,
want: map[string]string{
workv1alpha2.ClusterResourceBindingUIDLabel: rbUID,
workv1alpha2.ClusterResourceBindingReferenceKey: names.GenerateBindingReferenceKey("", bindingName),
},
},
Expand All @@ -156,14 +162,16 @@ func Test_mergeAnnotations(t *testing.T) {
bindingName := "fake-bindingName"

tests := []struct {
name string
workload *unstructured.Unstructured
binding metav1.Object
scope v1.ResourceScope
want map[string]string
name string
namespace string
workload *unstructured.Unstructured
binding metav1.Object
scope v1.ResourceScope
want map[string]string
}{
{
name: "NamespaceScoped",
name: "NamespaceScoped",
namespace: "test",
workload: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "apps/v1",
Expand All @@ -187,7 +195,8 @@ func Test_mergeAnnotations(t *testing.T) {
},
},
{
name: "ClusterScoped",
name: "ClusterScoped",
namespace: "",
workload: &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "v1",
Expand All @@ -210,7 +219,7 @@ func Test_mergeAnnotations(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := mergeAnnotations(tt.workload, tt.binding, tt.scope); !reflect.DeepEqual(got, tt.want) {
if got := mergeAnnotations(tt.workload, tt.namespace, tt.binding, tt.scope); !reflect.DeepEqual(got, tt.want) {
t.Errorf("mergeAnnotations() = %v, want %v", got, tt.want)
}
})
Expand Down
3 changes: 2 additions & 1 deletion pkg/controllers/execution/execution_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/predicate"

workv1alpha1 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha1"
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
"github.com/karmada-io/karmada/pkg/events"
"github.com/karmada-io/karmada/pkg/metrics"
"github.com/karmada-io/karmada/pkg/sharedcli/ratelimiterflag"
Expand Down Expand Up @@ -302,8 +303,8 @@ func (c *Controller) syncToClusters(clusterName string, work *workv1alpha1.Work)
syncSucceedNum := 0
for _, manifest := range work.Spec.Workload.Manifests {
workload := &unstructured.Unstructured{}
util.MergeLabel(workload, util.ManagedByKarmadaLabel, util.ManagedByKarmadaLabelValue)
err := workload.UnmarshalJSON(manifest.Raw)
util.MergeLabel(workload, workv1alpha2.WorkUIDLabel, string(work.UID))
if err != nil {
klog.Errorf("Failed to unmarshal workload, error is: %v", err)
errs = append(errs, err)
Expand Down
40 changes: 26 additions & 14 deletions pkg/controllers/execution/execution_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,9 @@ func newPod(name string, labels map[string]string) *corev1.Pod {
}
}

func newWorkLabels(workNs, workName string) map[string]string {
func newWorkloadLabels(workNs, workName, workUID string) map[string]string {
labels := map[string]string{}

if workNs != "" {
labels[workv1alpha1.WorkNamespaceLabel] = workNs
}
Expand All @@ -388,6 +389,10 @@ func newWorkLabels(workNs, workName string) map[string]string {
labels[workv1alpha1.WorkNameLabel] = workName
}

if workUID != "" {
labels[workv1alpha2.WorkUIDLabel] = workUID
}

return labels
}

Expand Down Expand Up @@ -428,6 +433,7 @@ func TestExecutionController_tryDeleteWorkload(t *testing.T) {
podName := "pod"
workName := "work-name"
workNs := "karmada-es-cluster"
workUID := "99f1f7c3-1f1f-4f1f-9f1f-7c3f1f1f9f1f"
clusterName := "cluster"
podGVR := corev1.SchemeGroupVersion.WithResource("pods")

Expand All @@ -441,32 +447,32 @@ func TestExecutionController_tryDeleteWorkload(t *testing.T) {
}{
{
name: "failed to GetObjectFromCache, wrong InformerManager in ExecutionController",
pod: newPod(podName, newWorkLabels(workNs, workName)),
work: testhelper.NewWork(workName, workNs, raw),
pod: newPod(podName, newWorkloadLabels(workNs, workName, workUID)),
work: testhelper.NewWork(workName, workNs, workUID, raw),
controllerWithoutInformer: false,
expectedError: false,
objectNeedDelete: false,
},
{
name: "workload is not managed by karmada, without work-related labels",
pod: newPod(podName, nil),
work: testhelper.NewWork(workName, workNs, raw),
work: testhelper.NewWork(workName, workNs, workUID, raw),
controllerWithoutInformer: true,
expectedError: false,
objectNeedDelete: false,
},
{
name: "workload is not related to current work",
pod: newPod(podName, newWorkLabels(workNs, "wrong-work")),
work: testhelper.NewWork(workName, workNs, raw),
pod: newPod(podName, newWorkloadLabels(workNs, "wrong-work", workUID)),
work: testhelper.NewWork(workName, workNs, workUID, raw),
controllerWithoutInformer: true,
expectedError: false,
objectNeedDelete: false,
},
{
name: "normal case",
pod: newPod(podName, newWorkLabels(workNs, workName)),
work: testhelper.NewWork(workName, workNs, raw),
pod: newPod(podName, newWorkloadLabels(workNs, workName, workUID)),
work: testhelper.NewWork(workName, workNs, workUID, raw),
controllerWithoutInformer: true,
expectedError: false,
objectNeedDelete: true,
Expand Down Expand Up @@ -516,6 +522,7 @@ func TestExecutionController_tryCreateOrUpdateWorkload(t *testing.T) {
podName := "pod"
workName := "work-name"
workNs := "karmada-es-cluster"
workUID := "99f1f7c3-1f1f-4f1f-9f1f-7c3f1f1f9f1f"
clusterName := "cluster"
podGVR := corev1.SchemeGroupVersion.WithResource("pods")
annotations := map[string]string{
Expand All @@ -534,7 +541,7 @@ func TestExecutionController_tryCreateOrUpdateWorkload(t *testing.T) {
{
name: "created workload",
pod: newPod("wrong-pod", nil),
obj: newPodObj(podName, newWorkLabels(workNs, workName)),
obj: newPodObj(podName, newWorkloadLabels(workNs, workName, workUID)),
withAnnotation: false,
expectedError: false,
objectExist: true,
Expand All @@ -543,7 +550,7 @@ func TestExecutionController_tryCreateOrUpdateWorkload(t *testing.T) {
{
name: "failed to update object, overwrite conflict resolusion not set",
pod: newPod(podName, nil),
obj: newPodObj(podName, newWorkLabels(workNs, workName)),
obj: newPodObj(podName, newWorkloadLabels(workNs, workName, workUID)),
withAnnotation: false,
expectedError: true,
objectExist: true,
Expand All @@ -552,7 +559,7 @@ func TestExecutionController_tryCreateOrUpdateWorkload(t *testing.T) {
{
name: "updated object",
pod: newPod(podName, nil),
obj: newPodObj(podName, newWorkLabels(workNs, workName)),
obj: newPodObj(podName, newWorkloadLabels(workNs, workName, workUID)),
withAnnotation: true,
expectedError: false,
objectExist: true,
Expand Down Expand Up @@ -590,7 +597,11 @@ func TestExecutionController_tryCreateOrUpdateWorkload(t *testing.T) {
return
}

labels := map[string]string{workv1alpha1.WorkNamespaceLabel: workNs, workv1alpha1.WorkNameLabel: workName}
labels := map[string]string{
workv1alpha1.WorkNamespaceLabel: workNs,
workv1alpha1.WorkNameLabel: workName,
workv1alpha2.WorkUIDLabel: workUID,
}
if tt.labelMatch {
assert.Equal(t, resource.GetLabels(), labels)
} else {
Expand Down Expand Up @@ -706,6 +717,7 @@ func TestExecutionController_syncWork(t *testing.T) {
basePod := newPod("pod", nil)
workName := "work"
workNs := "karmada-es-cluster"
workUID := "93162d3c-ee8e-4995-9034-05f4d5d2c2b9"
podGVR := corev1.SchemeGroupVersion.WithResource("pods")
podRaw := []byte(`
{
Expand Down Expand Up @@ -789,7 +801,7 @@ func TestExecutionController_syncWork(t *testing.T) {
o.dynamicClientSet = dynamicClientSet
}

work := testhelper.NewWork(workName, tt.workNamespace, podRaw)
work := testhelper.NewWork(workName, tt.workNamespace, workUID, podRaw)
o.objects = append(o.objects, work)
o.objectsWithStatus = append(o.objectsWithStatus, &workv1alpha1.Work{})

Expand All @@ -810,7 +822,7 @@ func TestExecutionController_syncWork(t *testing.T) {
t.Fatalf("Failed to get pod: %v", err)
}

expectedLabels := newWorkLabels(workNs, workName)
expectedLabels := newWorkloadLabels(workNs, workName, workUID)
assert.Equal(t, resource.GetLabels(), expectedLabels)
}
})
Expand Down
5 changes: 3 additions & 2 deletions pkg/controllers/status/work_status_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,7 @@ func TestWorkStatusController_syncWorkStatus(t *testing.T) {
cluster := testhelper.NewClusterWithTypeAndStatus("cluster", clusterv1alpha1.ClusterConditionReady, metav1.ConditionFalse)
workName := "work"
workNs := "karmada-es-cluster"
workUID := "92345678-1234-5678-1234-567812345678"

tests := []struct {
name string
Expand Down Expand Up @@ -576,9 +577,9 @@ func TestWorkStatusController_syncWorkStatus(t *testing.T) {

var work *workv1alpha1.Work
if tt.workWithRigntNS {
work = testhelper.NewWork(workName, workNs, tt.raw)
work = testhelper.NewWork(workName, workNs, workUID, tt.raw)
} else {
work = testhelper.NewWork(workName, fmt.Sprintf("%v-test", workNs), tt.raw)
work = testhelper.NewWork(workName, fmt.Sprintf("%v-test", workNs), workUID, tt.raw)
}

key, _ := generateKey(tt.obj)
Expand Down
Loading
Loading