@@ -23,10 +23,13 @@ import (
2323 "context"
2424 "errors"
2525 "fmt"
26+ "slices"
27+ "strings"
2628
2729 kbappsv1 "github.com/apecloud/kubeblocks/apis/apps/v1"
2830 parametersv1alpha1 "github.com/apecloud/kubeblocks/apis/parameters/v1alpha1"
2931 "github.com/apecloud/kubeblocks/pkg/client/clientset/versioned"
32+ "github.com/apecloud/kubeblocks/pkg/controller/component"
3033 "github.com/apecloud/kubeblocks/pkg/generics"
3134 configctrl "github.com/apecloud/kubeblocks/pkg/parameters"
3235 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -40,6 +43,7 @@ type ReconfigureContext struct {
4043 Cluster * kbappsv1.Cluster
4144 Cmpd * kbappsv1.ComponentDefinition
4245 ConfigRender * parametersv1alpha1.ParamConfigRenderer
46+ ConfigDescs []parametersv1alpha1.ComponentConfigDescription
4347 ParametersDefs []* parametersv1alpha1.ParametersDefinition
4448
4549 CompName string
@@ -60,7 +64,7 @@ func (w *ReconfigureWrapper) ConfigSpecName() string {
6064 return w .configFileKey
6165 }
6266 file := w .ConfigFile ()
63- if file != "" && w . rctx . ConfigRender != nil {
67+ if file != "" {
6468 config := configctrl .GetComponentConfigDescription (configDescriptions (w .rctx ), file )
6569 if config != nil {
6670 return config .TemplateName
@@ -77,14 +81,20 @@ func (w *ReconfigureWrapper) ConfigFile() string {
7781 if w .configFileKey != "" {
7882 return w .configFileKey
7983 }
80- if w . rctx . ConfigRender != nil && len (w .rctx . ConfigRender . Spec . Configs ) > 0 {
81- return w . rctx . ConfigRender . Spec . Configs [0 ].Name
84+ if configDescs := configDescriptions (w .rctx ); len ( configDescs ) > 0 {
85+ return configDescs [0 ].Name
8286 }
8387 return ""
8488}
8589
8690func configDescriptions (rctx * ReconfigureContext ) []parametersv1alpha1.ComponentConfigDescription {
87- if rctx == nil || rctx .ConfigRender == nil {
91+ if rctx == nil {
92+ return nil
93+ }
94+ if len (rctx .ConfigDescs ) > 0 {
95+ return rctx .ConfigDescs
96+ }
97+ if rctx .ConfigRender == nil {
8898 return nil
8999 }
90100 return rctx .ConfigRender .Spec .Configs
@@ -191,20 +201,117 @@ func resolveComponentDefObj(ctx context.Context, client versioned.Interface, clu
191201}
192202
193203func resolveCmpdParametersDefs (rctx * ReconfigureContext ) error {
194- configRender , err := resolveComponentConfigRender (rctx , rctx . Cmpd )
204+ configDescs , paramsDefs , coveredFiles , err := resolveDirectParametersDefs (rctx )
195205 if err != nil {
196206 return err
197207 }
198- if configRender == nil || len (configRender .Spec .ParametersDefs ) == 0 {
199- return nil
208+
209+ configRender , err := resolveComponentConfigRender (rctx , rctx .Cmpd )
210+ if err != nil {
211+ return err
200212 }
201213 rctx .ConfigRender = configRender
202- for _ , defName := range configRender .Spec .ParametersDefs {
203- pd , err := rctx .Client .ParametersV1alpha1 ().ParametersDefinitions ().Get (rctx .Context , defName , metav1.GetOptions {})
214+ if configRender != nil {
215+ legacyConfigFiles := make (map [string ]struct {}, len (configRender .Spec .Configs ))
216+ for _ , configDesc := range configRender .Spec .Configs {
217+ if _ , ok := coveredFiles [configDesc .Name ]; ok {
218+ continue
219+ }
220+ configDescs = append (configDescs , configDesc )
221+ legacyConfigFiles [configDesc .Name ] = struct {}{}
222+ }
223+ for _ , defName := range configRender .Spec .ParametersDefs {
224+ pd , err := rctx .Client .ParametersV1alpha1 ().ParametersDefinitions ().Get (rctx .Context , defName , metav1.GetOptions {})
225+ if err != nil {
226+ return err
227+ }
228+ if pd .Status .Phase != parametersv1alpha1 .PDAvailablePhase {
229+ return fmt .Errorf ("the referenced ParametersDefinition is unavailable: %s" , pd .Name )
230+ }
231+ if _ , ok := legacyConfigFiles [pd .Spec .FileName ]; ok {
232+ paramsDefs = append (paramsDefs , pd )
233+ }
234+ }
235+ }
236+
237+ rctx .ConfigDescs = configDescs
238+ rctx .ParametersDefs = paramsDefs
239+ return nil
240+ }
241+
242+ func resolveDirectParametersDefs (rctx * ReconfigureContext ) ([]parametersv1alpha1.ComponentConfigDescription , []* parametersv1alpha1.ParametersDefinition , map [string ]struct {}, error ) {
243+ paramsDefList , err := rctx .Client .ParametersV1alpha1 ().ParametersDefinitions ().List (rctx .Context , metav1.ListOptions {})
244+ if err != nil {
245+ return nil , nil , nil , err
246+ }
247+ slices .SortFunc (paramsDefList .Items , func (a , b parametersv1alpha1.ParametersDefinition ) int {
248+ if cmp := strings .Compare (b .Spec .ComponentDef , a .Spec .ComponentDef ); cmp != 0 {
249+ return cmp
250+ }
251+ if cmp := strings .Compare (a .Spec .TemplateName , b .Spec .TemplateName ); cmp != 0 {
252+ return cmp
253+ }
254+ if cmp := strings .Compare (a .Spec .FileName , b .Spec .FileName ); cmp != 0 {
255+ return cmp
256+ }
257+ return strings .Compare (a .Name , b .Name )
258+ })
259+
260+ var paramsDefs []* parametersv1alpha1.ParametersDefinition
261+ configDescs := make ([]parametersv1alpha1.ComponentConfigDescription , 0 , len (paramsDefList .Items ))
262+ coveredFiles := make (map [string ]struct {})
263+ for i := range paramsDefList .Items {
264+ paramsDef := & paramsDefList .Items [i ]
265+ matched , err := matchParametersDefinition (rctx .Cmpd , paramsDef )
204266 if err != nil {
205- return err
267+ return nil , nil , nil , err
268+ }
269+ if ! matched {
270+ continue
206271 }
207- rctx .ParametersDefs = append (rctx .ParametersDefs , pd )
272+ if paramsDef .Status .Phase != parametersv1alpha1 .PDAvailablePhase {
273+ return nil , nil , nil , fmt .Errorf ("the referenced ParametersDefinition is unavailable: %s" , paramsDef .Name )
274+ }
275+ if err := validateMatchedParametersDefinition (paramsDef ); err != nil {
276+ return nil , nil , nil , err
277+ }
278+ if _ , ok := coveredFiles [paramsDef .Spec .FileName ]; ok {
279+ return nil , nil , nil , fmt .Errorf ("config file[%s] has been defined in other parametersdefinition" , paramsDef .Spec .FileName )
280+ }
281+ coveredFiles [paramsDef .Spec .FileName ] = struct {}{}
282+ paramsDefs = append (paramsDefs , paramsDef )
283+ configDescs = append (configDescs , parametersv1alpha1.ComponentConfigDescription {
284+ Name : paramsDef .Spec .FileName ,
285+ TemplateName : paramsDef .Spec .TemplateName ,
286+ FileFormatConfig : paramsDef .Spec .FileFormatConfig .DeepCopy (),
287+ })
288+ }
289+ return configDescs , paramsDefs , coveredFiles , nil
290+ }
291+
292+ func matchParametersDefinition (cmpd * kbappsv1.ComponentDefinition , paramsDef * parametersv1alpha1.ParametersDefinition ) (bool , error ) {
293+ if cmpd == nil || paramsDef == nil {
294+ return false , nil
295+ }
296+ pattern := paramsDef .Spec .ComponentDef
297+ if pattern == "" {
298+ return false , nil
299+ }
300+ if ! component .PrefixOrRegexMatched (cmpd .Name , pattern ) {
301+ return false , nil
302+ }
303+ return paramsDef .Spec .ServiceVersion == "" || paramsDef .Spec .ServiceVersion == cmpd .Spec .ServiceVersion , nil
304+ }
305+
306+ func validateMatchedParametersDefinition (paramsDef * parametersv1alpha1.ParametersDefinition ) error {
307+ if paramsDef .Spec .TemplateName == "" {
308+ return fmt .Errorf ("ParametersDefinition[%s] misses templateName" , paramsDef .Name )
309+ }
310+ if paramsDef .Spec .FileName == "" {
311+ return fmt .Errorf ("ParametersDefinition[%s] misses fileName" , paramsDef .Name )
312+ }
313+ if paramsDef .Spec .FileFormatConfig == nil {
314+ return fmt .Errorf ("ParametersDefinition[%s] misses fileFormatConfig" , paramsDef .Name )
208315 }
209316 return nil
210317}
@@ -217,7 +324,7 @@ func resolveComponentConfigRender(rctx *ReconfigureContext, cmpd *kbappsv1.Compo
217324
218325 var prcs []parametersv1alpha1.ParamConfigRenderer
219326 for i , item := range pcrList .Items {
220- if item .Spec .ComponentDef != cmpd . Name {
327+ if ! component . PrefixOrRegexMatched ( cmpd . Name , item .Spec .ComponentDef ) {
221328 continue
222329 }
223330 if item .Spec .ServiceVersion == "" || item .Spec .ServiceVersion == cmpd .Spec .ServiceVersion {
0 commit comments