diff --git a/pkg/resourceinterpreter/default/native/prune/prune.go b/pkg/resourceinterpreter/default/native/prune/prune.go index 42126df82636..096aee77b3f1 100644 --- a/pkg/resourceinterpreter/default/native/prune/prune.go +++ b/pkg/resourceinterpreter/default/native/prune/prune.go @@ -28,6 +28,15 @@ import ( "github.com/karmada-io/karmada/pkg/util/helper" ) +// pruneIrrelevantField is the function that prune irrelevant fields from Work Object. +type irrelevantFieldPruneFunc func(workload *unstructured.Unstructured) error + +var kindIrrelevantFieldPruners = map[string]irrelevantFieldPruneFunc{ + util.JobKind: removeJobIrrelevantField, + util.ServiceAccountKind: removeServiceAccountIrrelevantField, + util.ServiceKind: removeServiceIrrelevantField, +} + // RemoveIrrelevantField used to remove fields that generated by kube-apiserver and no need(or can't) propagate to // member clusters. func RemoveIrrelevantField(workload *unstructured.Unstructured, extraHooks ...func(*unstructured.Unstructured)) error { @@ -66,40 +75,10 @@ func RemoveIrrelevantField(workload *unstructured.Unstructured, extraHooks ...fu unstructured.RemoveNestedField(workload.Object, "status") - if workload.GetKind() == util.ServiceKind { - // In the case spec.clusterIP is set to `None`, means user want a headless service, then it shouldn't be removed. - clusterIP, exist, _ := unstructured.NestedString(workload.Object, "spec", "clusterIP") - if exist && clusterIP != corev1.ClusterIPNone { - unstructured.RemoveNestedField(workload.Object, "spec", "clusterIP") - unstructured.RemoveNestedField(workload.Object, "spec", "clusterIPs") - } - } - - if workload.GetKind() == util.JobKind { - job := &batchv1.Job{} - err := helper.ConvertToTypedObject(workload, job) - if err != nil { + if pruneFunc, ok := kindIrrelevantFieldPruners[workload.GetKind()]; ok { + if err := pruneFunc(workload); err != nil { return err } - if job.Spec.ManualSelector == nil || !*job.Spec.ManualSelector { - if err = removeGenerateSelectorOfJob(workload); err != nil { - return err - } - } - } - - if workload.GetKind() == util.ServiceAccountKind { - secrets, exist, _ := unstructured.NestedSlice(workload.Object, "secrets") - // If 'secrets' exists in ServiceAccount, remove the automatic generation secrets(e.g. default-token-xxx) - if exist && len(secrets) > 0 { - tokenPrefix := fmt.Sprintf("%s-token-", workload.GetName()) - for idx := 0; idx < len(secrets); idx++ { - if strings.HasPrefix(secrets[idx].(map[string]interface{})["name"].(string), tokenPrefix) { - secrets = append(secrets[:idx], secrets[idx+1:]...) - } - } - _ = unstructured.SetNestedSlice(workload.Object, secrets, "secrets") - } } for i := range extraHooks { @@ -159,3 +138,45 @@ func RemoveJobTTLSeconds(workload *unstructured.Unstructured) { unstructured.RemoveNestedField(workload.Object, "spec", "ttlSecondsAfterFinished") } } + +// removeJobIrrelevantField removes the irrelevant fields from Job (e.g. ManualSelector) +func removeJobIrrelevantField(workload *unstructured.Unstructured) error { + job := &batchv1.Job{} + err := helper.ConvertToTypedObject(workload, job) + if err != nil { + return err + } + if job.Spec.ManualSelector == nil || !*job.Spec.ManualSelector { + if err = removeGenerateSelectorOfJob(workload); err != nil { + return err + } + } + return nil +} + +// removeServiceAccountIrrelevantField removes the auto-generated secrets from ServiceAccount. +func removeServiceAccountIrrelevantField(workload *unstructured.Unstructured) error { + secrets, exist, _ := unstructured.NestedSlice(workload.Object, "secrets") + // If 'secrets' exists in ServiceAccount, remove the automatic generation secrets (e.g. default-token-xxx) + if exist && len(secrets) > 0 { + tokenPrefix := fmt.Sprintf("%s-token-", workload.GetName()) + for idx := 0; idx < len(secrets); idx++ { + if strings.HasPrefix(secrets[idx].(map[string]interface{})["name"].(string), tokenPrefix) { + secrets = append(secrets[:idx], secrets[idx+1:]...) + } + } + _ = unstructured.SetNestedSlice(workload.Object, secrets, "secrets") + } + return nil +} + +// removeServiceIrrelevantField removes member cluster specific fields from Service (e.g. clusterIP, clusterIPs) +func removeServiceIrrelevantField(workload *unstructured.Unstructured) error { + // In the case spec.clusterIP is set to `None`, means user want a headless service, then it shouldn't be removed. + clusterIP, exist, _ := unstructured.NestedString(workload.Object, "spec", "clusterIP") + if exist && clusterIP != corev1.ClusterIPNone { + unstructured.RemoveNestedField(workload.Object, "spec", "clusterIP") + unstructured.RemoveNestedField(workload.Object, "spec", "clusterIPs") + } + return nil +}