Merge pull request #1087 from iawia002/takeover-existing-resource

Introduce ResourceConflictResolution annotation to control the strategy for managing resources with the same name
This commit is contained in:
karmada-bot 2021-12-11 12:03:22 +08:00 committed by GitHub
commit c406aeeadc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 4 deletions

View File

@ -26,3 +26,17 @@ const (
// WorkNameLabel is added to objects to specify associated Work's name.
WorkNameLabel = "work.karmada.io/name"
)
// Define resource conflict resolution
const (
// ResourceConflictResolutionAnnotation is added to the resource template to specify how to resolve the conflict
// in case of resource already existing in member clusters.
// The valid value is:
// - overwrite: always overwrite the resource if already exist. The resource will be overwritten with the
// configuration from control plane.
// Note: Propagation of the resource template without this annotation will fail in case of already exists.
ResourceConflictResolutionAnnotation = "work.karmada.io/conflict-resolution"
// ResourceConflictResolutionOverwrite is the value of ResourceConflictResolutionAnnotation, indicating the overwrite strategy.
ResourceConflictResolutionOverwrite = "overwrite"
)

View File

@ -21,3 +21,11 @@ func MergeAnnotations(dst *unstructured.Unstructured, src *unstructured.Unstruct
MergeAnnotation(dst, key, value)
}
}
// GetAnnotationValue retrieves the value via 'annotationKey' if exist, otherwise returns an empty string.
func GetAnnotationValue(annotations map[string]string, annotationKey string) string {
if annotations == nil {
return ""
}
return annotations[annotationKey]
}

View File

@ -16,6 +16,7 @@ import (
configv1alpha1 "github.com/karmada-io/karmada/pkg/apis/config/v1alpha1"
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/resourceinterpreter"
"github.com/karmada-io/karmada/pkg/util"
"github.com/karmada-io/karmada/pkg/util/restmapper"
@ -84,12 +85,23 @@ func (o *objectWatcherImpl) Create(clusterName string, desireObj *unstructured.U
return fmt.Errorf("failed to get exist resource(kind=%s, %s/%s) in cluster %v: %v", desireObj.GetKind(), desireObj.GetNamespace(), desireObj.GetName(), clusterName, err)
}
// Avoid updating resources that not managed by karmada.
if util.GetLabelValue(desireObj.GetLabels(), workv1alpha1.WorkNameLabel) != util.GetLabelValue(existObj.GetLabels(), workv1alpha1.WorkNameLabel) {
return fmt.Errorf("resource(kind=%s, %s/%s) already exist in cluster %v but not managed by karamda", desireObj.GetKind(), desireObj.GetNamespace(), desireObj.GetName(), clusterName)
// If the existing resource is managed by Karmada, then just update it.
if util.GetLabelValue(desireObj.GetLabels(), workv1alpha1.WorkNameLabel) == util.GetLabelValue(existObj.GetLabels(), workv1alpha1.WorkNameLabel) {
return o.Update(clusterName, desireObj, existObj)
}
return o.Update(clusterName, desireObj, existObj)
// The existing resource is not managed by Karmada, then we should consult conflict resolution instruction in annotation.
switch util.GetAnnotationValue(desireObj.GetAnnotations(), workv1alpha2.ResourceConflictResolutionAnnotation) {
case workv1alpha2.ResourceConflictResolutionOverwrite:
klog.Infof("Overwriting the resource(kind=%s, %s/%s) as %s=%s", desireObj.GetKind(), desireObj.GetNamespace(), desireObj.GetName(),
workv1alpha2.ResourceConflictResolutionAnnotation, workv1alpha2.ResourceConflictResolutionOverwrite)
return o.Update(clusterName, desireObj, existObj)
default:
// The existing resource is not managed by Karmada, and no conflict resolution found, avoid updating the existing resource by default.
return fmt.Errorf("resource(kind=%s, %s/%s) already exist in cluster %v and the %s strategy value is empty, karmada will not manage this resource",
desireObj.GetKind(), desireObj.GetNamespace(), desireObj.GetName(), clusterName, workv1alpha2.ResourceConflictResolutionAnnotation,
)
}
}
klog.Errorf("Failed to create resource(kind=%s, %s/%s) in cluster %s, err is %v ", desireObj.GetKind(), desireObj.GetNamespace(), desireObj.GetName(), clusterName, err)
return err