@@ -49,11 +49,13 @@ import (
4949 "sigs.k8s.io/controller-runtime/pkg/predicate"
5050 "sigs.k8s.io/controller-runtime/pkg/reconcile"
5151 "sigs.k8s.io/controller-runtime/pkg/source"
52+ "sigs.k8s.io/yaml"
5253
5354 "github.com/fluxcd/pkg/apis/meta"
5455 "github.com/fluxcd/pkg/runtime/events"
5556 "github.com/fluxcd/pkg/runtime/metrics"
5657 "github.com/fluxcd/pkg/runtime/predicates"
58+ "github.com/fluxcd/pkg/runtime/transform"
5759 "github.com/fluxcd/pkg/untar"
5860
5961 sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
@@ -380,30 +382,57 @@ func (r *HelmChartReconciler) reconcileFromHelmRepository(ctx context.Context,
380382 readyMessage = fmt .Sprintf ("Fetched revision: %s" , newArtifact .Revision )
381383 )
382384 switch {
383- case chart .Spec . ValuesFile != "" && chart . Spec . ValuesFile != chartutil . ValuesfileName :
385+ case len ( chart .GetValuesFiles ()) > 0 :
384386 var (
385387 tmpDir string
386388 pkgPath string
387389 )
390+ valuesMap := make (map [string ]interface {})
391+
388392 // Load the chart
389393 helmChart , err := loader .LoadArchive (res )
390394 if err != nil {
391395 err = fmt .Errorf ("load chart error: %w" , err )
392396 return sourcev1 .HelmChartNotReady (chart , sourcev1 .StorageOperationFailedReason , err .Error ()), err
393397 }
394398
395- // Find override file and retrieve contents
396- var valuesData []byte
397- cfn := filepath .Clean (chart .Spec .ValuesFile )
398- for _ , f := range helmChart .Files {
399- if f .Name == cfn {
400- valuesData = f .Data
401- break
399+ for _ , v := range chart .GetValuesFiles () {
400+ if v == "values.yaml" {
401+ valuesMap = transform .MergeMaps (valuesMap , helmChart .Values )
402+ continue
403+ }
404+
405+ var valuesData []byte
406+ cfn := filepath .Clean (v )
407+ for _ , f := range helmChart .Files {
408+ if f .Name == cfn {
409+ valuesData = f .Data
410+ break
411+ }
402412 }
413+ if valuesData == nil {
414+ err = fmt .Errorf ("invalid values file path: %s" , v )
415+ return sourcev1 .HelmChartNotReady (chart , sourcev1 .StorageOperationFailedReason , err .Error ()), err
416+ }
417+
418+ yamlMap := make (map [string ]interface {})
419+ err = yaml .Unmarshal (valuesData , & yamlMap )
420+ if err != nil {
421+ err = fmt .Errorf ("unmarshaling values from %s failed: %w" , v , err )
422+ return sourcev1 .HelmChartNotReady (chart , sourcev1 .StorageOperationFailedReason , err .Error ()), err
423+ }
424+
425+ valuesMap = transform .MergeMaps (valuesMap , yamlMap )
426+ }
427+
428+ yamlBytes , err := yaml .Marshal (valuesMap )
429+ if err != nil {
430+ err = fmt .Errorf ("marshaling values failed: %w" , err )
431+ return sourcev1 .HelmChartNotReady (chart , sourcev1 .ChartPackageFailedReason , err .Error ()), err
403432 }
404433
405434 // Overwrite values file
406- if changed , err := helm .OverwriteChartDefaultValues (helmChart , valuesData ); err != nil {
435+ if changed , err := helm .OverwriteChartDefaultValues (helmChart , yamlBytes ); err != nil {
407436 return sourcev1 .HelmChartNotReady (chart , sourcev1 .ChartPackageFailedReason , err .Error ()), err
408437 } else if ! changed {
409438 // No changes, skip to write original package to storage
@@ -508,22 +537,41 @@ func (r *HelmChartReconciler) reconcileFromTarballArtifact(ctx context.Context,
508537 // or write the chart directly to storage.
509538 pkgPath := chartPath
510539 isValuesFileOverriden := false
511- if chart .Spec .ValuesFile != "" {
512- srcPath , err := securejoin .SecureJoin (tmpDir , chart .Spec .ValuesFile )
513- if err != nil {
514- return sourcev1 .HelmChartNotReady (chart , sourcev1 .StorageOperationFailedReason , err .Error ()), err
515- }
516- if f , err := os .Stat (srcPath ); os .IsNotExist (err ) || ! f .Mode ().IsRegular () {
517- err = fmt .Errorf ("invalid values file path: %s" , chart .Spec .ValuesFile )
518- return sourcev1 .HelmChartNotReady (chart , sourcev1 .StorageOperationFailedReason , err .Error ()), err
540+ if len (chart .GetValuesFiles ()) > 0 {
541+ valuesMap := make (map [string ]interface {})
542+ for _ , v := range chart .GetValuesFiles () {
543+ srcPath , err := securejoin .SecureJoin (tmpDir , v )
544+ if err != nil {
545+ return sourcev1 .HelmChartNotReady (chart , sourcev1 .StorageOperationFailedReason , err .Error ()), err
546+ }
547+ if f , err := os .Stat (srcPath ); os .IsNotExist (err ) || ! f .Mode ().IsRegular () {
548+ err = fmt .Errorf ("invalid values file path: %s" , v )
549+ return sourcev1 .HelmChartNotReady (chart , sourcev1 .StorageOperationFailedReason , err .Error ()), err
550+ }
551+
552+ valuesData , err := ioutil .ReadFile (srcPath )
553+ if err != nil {
554+ err = fmt .Errorf ("failed to read from values file '%s': %w" , v , err )
555+ return sourcev1 .HelmChartNotReady (chart , sourcev1 .StorageOperationFailedReason , err .Error ()), err
556+ }
557+
558+ yamlMap := make (map [string ]interface {})
559+ err = yaml .Unmarshal (valuesData , & yamlMap )
560+ if err != nil {
561+ err = fmt .Errorf ("unmarshaling values from %s failed: %w" , v , err )
562+ return sourcev1 .HelmChartNotReady (chart , sourcev1 .StorageOperationFailedReason , err .Error ()), err
563+ }
564+
565+ valuesMap = transform .MergeMaps (valuesMap , yamlMap )
519566 }
520567
521- valuesData , err := ioutil . ReadFile ( srcPath )
568+ yamlBytes , err := yaml . Marshal ( valuesMap )
522569 if err != nil {
523- err = fmt .Errorf ("failed to read from values file '%s' : %w" , chart . Spec . ValuesFile , err )
524- return sourcev1 .HelmChartNotReady (chart , sourcev1 .StorageOperationFailedReason , err .Error ()), err
570+ err = fmt .Errorf ("marshaling values failed : %w" , err )
571+ return sourcev1 .HelmChartNotReady (chart , sourcev1 .ChartPackageFailedReason , err .Error ()), err
525572 }
526- isValuesFileOverriden , err = helm .OverwriteChartDefaultValues (helmChart , valuesData )
573+
574+ isValuesFileOverriden , err = helm .OverwriteChartDefaultValues (helmChart , yamlBytes )
527575 if err != nil {
528576 return sourcev1 .HelmChartNotReady (chart , sourcev1 .ChartPackageFailedReason , err .Error ()), err
529577 }
0 commit comments