diff --git a/apis/configuration/slo_controller_config.go b/apis/configuration/slo_controller_config.go index d4a2ab99b..03cf238de 100644 --- a/apis/configuration/slo_controller_config.go +++ b/apis/configuration/slo_controller_config.go @@ -152,7 +152,7 @@ func (in *ExtensionCfg) DeepCopy() *ExtensionCfg { // +k8s:deepcopy-gen=false type NodeExtensionStrategy struct { NodeCfgProfile `json:",inline"` - NodeStrategy interface{} // for third-party extension + NodeStrategy interface{} `json:",inline"` // for third-party extension } func (in *NodeExtensionStrategy) DeepCopyInto(out *NodeExtensionStrategy) { diff --git a/pkg/koordlet/statesinformer/impl/states_nodeslo.go b/pkg/koordlet/statesinformer/impl/states_nodeslo.go index dbdd9d291..1cb266146 100644 --- a/pkg/koordlet/statesinformer/impl/states_nodeslo.go +++ b/pkg/koordlet/statesinformer/impl/states_nodeslo.go @@ -254,11 +254,18 @@ func mergeSLOSpecExtensions(defaultSpec, if newSpec != nil { spec = newSpec } - // ignore err for serializing/deserializing the same struct type - data, _ := json.Marshal(spec) - // NOTE: use deepcopy to avoid a overwrite to the global default + out := defaultSpec.DeepCopy() - _ = json.Unmarshal(data, &out) + for key := range out.Object { + // merge extension one by one so that all extension types can be protected during unmarshal + if newObj, exist := spec.Object[key]; exist { + // ignore err for serializing/deserializing the same struct type + data, _ := json.Marshal(newObj) + // NOTE: use deepcopy to avoid a overwrite to the global default + _ = json.Unmarshal(data, out.Object[key]) + } + } + return out } diff --git a/pkg/koordlet/statesinformer/impl/states_nodeslo_test.go b/pkg/koordlet/statesinformer/impl/states_nodeslo_test.go index 855d5e8ad..50e22441b 100644 --- a/pkg/koordlet/statesinformer/impl/states_nodeslo_test.go +++ b/pkg/koordlet/statesinformer/impl/states_nodeslo_test.go @@ -58,7 +58,6 @@ func Test_mergeNodeSLOSpec(t *testing.T) { SystemStrategy: &slov1alpha1.SystemStrategy{ WatermarkScaleFactor: pointer.Int64(200), }, - Extensions: &slov1alpha1.ExtensionsMap{}, } testingMergedNodeSLOSpec := sloconfig.DefaultNodeSLOSpecConfig() mergedInterface, err := util.MergeCfg(&testingMergedNodeSLOSpec, &testingCustomNodeSLOSpec)