diff --git a/pkg/app/app.go b/pkg/app/app.go index 1ee1cb48..29a1ce40 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -166,6 +166,7 @@ func (a *App) Diff(c DiffConfigProvider) error { SkipRepos: c.SkipRefresh() || c.SkipDeps(), SkipRefresh: c.SkipRefresh(), SkipDeps: c.SkipDeps(), + SkipSchemaValidation: c.SkipSchemaValidation(), IncludeCRDs: &includeCRDs, Validate: c.Validate(), Concurrency: c.Concurrency(), @@ -237,6 +238,7 @@ func (a *App) Template(c TemplateConfigProvider) error { SkipRepos: c.SkipRefresh() || c.SkipDeps(), SkipRefresh: c.SkipRefresh(), SkipDeps: c.SkipDeps(), + SkipSchemaValidation: c.SkipSchemaValidation(), IncludeCRDs: &includeCRDs, SkipCleanup: c.SkipCleanup(), Validate: c.Validate(), @@ -420,6 +422,7 @@ func (a *App) Sync(c SyncConfigProvider) error { SkipRepos: c.SkipRefresh() || c.SkipDeps(), SkipRefresh: c.SkipRefresh(), SkipDeps: c.SkipDeps(), + SkipSchemaValidation: c.SkipSchemaValidation(), Wait: c.Wait(), WaitRetries: c.WaitRetries(), WaitForJobs: c.WaitForJobs(), @@ -456,6 +459,7 @@ func (a *App) Apply(c ApplyConfigProvider) error { SkipRepos: c.SkipRefresh() || c.SkipDeps(), SkipRefresh: c.SkipRefresh(), SkipDeps: c.SkipDeps(), + SkipSchemaValidation: c.SkipSchemaValidation(), Wait: c.Wait(), WaitRetries: c.WaitRetries(), WaitForJobs: c.WaitForJobs(), diff --git a/pkg/state/helmx.go b/pkg/state/helmx.go index b337cd30..f1a2daeb 100644 --- a/pkg/state/helmx.go +++ b/pkg/state/helmx.go @@ -135,20 +135,28 @@ func (st *HelmState) appendPostRenderArgsFlags(flags []string, release *ReleaseS // append skip-schema-validation flags to helm flags func (st *HelmState) appendSkipSchemaValidationFlags(flags []string, release *ReleaseSpec, skipSchemaValidation bool) []string { - switch { - // Check if SkipSchemaValidation is true in the release spec. - case release.SkipSchemaValidation != nil && *release.SkipSchemaValidation: - flags = append(flags, "--skip-schema-validation") - // Check if skipSchemaValidation argument is true. - case skipSchemaValidation: - flags = append(flags, "--skip-schema-validation") - // Check if SkipSchemaValidation is true in HelmDefaults. - case st.HelmDefaults.SkipSchemaValidation != nil && *st.HelmDefaults.SkipSchemaValidation: + if st.shouldSkipSchemaValidation(release, skipSchemaValidation) { flags = append(flags, "--skip-schema-validation") } return flags } +func (st *HelmState) shouldSkipSchemaValidation(release *ReleaseSpec, skipSchemaValidation bool) bool { + switch { + // Check if SkipSchemaValidation is true in the release spec. + case release.SkipSchemaValidation != nil && *release.SkipSchemaValidation: + return true + // Check if skipSchemaValidation argument is true. + case skipSchemaValidation: + return true + // Check if SkipSchemaValidation is true in HelmDefaults. + case st.HelmDefaults.SkipSchemaValidation != nil && *st.HelmDefaults.SkipSchemaValidation: + return true + default: + return false + } +} + // append suppress-output-line-regex flags to helm diff flags func (st *HelmState) appendSuppressOutputLineRegexFlags(flags []string, release *ReleaseSpec, suppressOutputLineRegex []string) []string { suppressOutputLineRegexFlags := []string{} diff --git a/pkg/state/issue_2549_test.go b/pkg/state/issue_2549_test.go new file mode 100644 index 00000000..3dd6e343 --- /dev/null +++ b/pkg/state/issue_2549_test.go @@ -0,0 +1,86 @@ +package state + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestAppendSkipSchemaValidationFlagToChartifyTemplateArgs(t *testing.T) { + enable := true + + tests := []struct { + name string + defaults HelmSpec + release *ReleaseSpec + fromCLI bool + templateArgs string + want string + }{ + { + name: "adds flag from release setting", + release: &ReleaseSpec{ + SkipSchemaValidation: &enable, + }, + want: "--skip-schema-validation", + }, + { + name: "adds flag from helm defaults", + defaults: HelmSpec{ + SkipSchemaValidation: &enable, + }, + release: &ReleaseSpec{}, + want: "--skip-schema-validation", + }, + { + name: "appends flag to existing args", + release: &ReleaseSpec{ + SkipSchemaValidation: &enable, + }, + templateArgs: "--kube-context default", + want: "--kube-context default --skip-schema-validation", + }, + { + name: "does not duplicate existing flag", + release: &ReleaseSpec{ + SkipSchemaValidation: &enable, + }, + templateArgs: "--skip-schema-validation --kube-context default", + want: "--skip-schema-validation --kube-context default", + }, + { + name: "does not treat similar flag values as existing flag", + release: &ReleaseSpec{ + SkipSchemaValidation: &enable, + }, + templateArgs: "--set name=foo--skip-schema-validation", + want: "--set name=foo--skip-schema-validation --skip-schema-validation", + }, + { + name: "adds flag from cli setting", + release: &ReleaseSpec{}, + fromCLI: true, + templateArgs: "--kube-context default", + want: "--kube-context default --skip-schema-validation", + }, + { + name: "does not add flag when disabled", + release: &ReleaseSpec{}, + templateArgs: "--kube-context default", + want: "--kube-context default", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + st := &HelmState{ + ReleaseSetSpec: ReleaseSetSpec{ + HelmDefaults: tt.defaults, + }, + } + + got := st.appendSkipSchemaValidationFlagToChartifyTemplateArgs(tt.templateArgs, tt.release, tt.fromCLI) + require.Equal(t, tt.want, got) + }) + } +} diff --git a/pkg/state/state.go b/pkg/state/state.go index f51a0dd1..594680e5 100644 --- a/pkg/state/state.go +++ b/pkg/state/state.go @@ -1341,6 +1341,8 @@ type ChartPrepareOptions struct { SkipRefresh bool SkipResolve bool SkipCleanup bool + // SkipSchemaValidation configures chartify to pass --skip-schema-validation to helm-template run by it. + SkipSchemaValidation bool // Validate configures chartify to pass --validate to helm-template run by it. // It's required when one of your chart relies on Capabilities.APIVersions in a template Validate bool @@ -1622,6 +1624,12 @@ func (st *HelmState) processChartification(chartification *Chartify, release *Re } } + chartifyOpts.TemplateArgs = st.appendSkipSchemaValidationFlagToChartifyTemplateArgs( + chartifyOpts.TemplateArgs, + release, + opts.SkipSchemaValidation, + ) + out, err := c.Chartify(release.Name, chartPath, chartify.WithChartifyOpts(chartifyOpts)) if err != nil { return "", false, err @@ -1634,6 +1642,30 @@ func (st *HelmState) processChartification(chartification *Chartify, release *Re return chartPath, buildDeps, nil } +func (st *HelmState) appendSkipSchemaValidationFlagToChartifyTemplateArgs(templateArgs string, release *ReleaseSpec, skipSchemaValidation bool) string { + if !st.shouldSkipSchemaValidation(release, skipSchemaValidation) || hasTemplateArg(templateArgs, "--skip-schema-validation") { + return templateArgs + } + + return appendTemplateArg(templateArgs, "--skip-schema-validation") +} + +func hasTemplateArg(templateArgs, arg string) bool { + for _, token := range strings.Fields(templateArgs) { + if token == arg || strings.HasPrefix(token, arg+"=") { + return true + } + } + return false +} + +func appendTemplateArg(templateArgs, arg string) string { + if templateArgs == "" { + return arg + } + return templateArgs + " " + arg +} + // processLocalChart handles local chart processing func (st *HelmState) processLocalChart(normalizedChart, dir string, release *ReleaseSpec, helmfileCommand string, opts ChartPrepareOptions, isLocal bool) (string, error) { chartPath := normalizedChart