feat: add skip json schema validation during the install /upgrade of a Chart (#1737)

* open PR for --skip-schema-validation flag

Signed-off-by: zhaque44 <haque.zubair@gmail.com>
This commit is contained in:
Zubair Haque 2024-10-24 07:53:18 -05:00 committed by GitHub
parent 32409acc61
commit d1416ec7b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 123 additions and 37 deletions

View File

@ -69,6 +69,7 @@ func NewApplyCmd(globalCfg *config.GlobalImpl) *cobra.Command {
f.BoolVar(&applyOptions.ResetValues, "reset-values", false, `Override helmDefaults.reuseValues "helm upgrade --install --reset-values"`) f.BoolVar(&applyOptions.ResetValues, "reset-values", false, `Override helmDefaults.reuseValues "helm upgrade --install --reset-values"`)
f.StringVar(&applyOptions.PostRenderer, "post-renderer", "", `pass --post-renderer to "helm template" or "helm upgrade --install"`) f.StringVar(&applyOptions.PostRenderer, "post-renderer", "", `pass --post-renderer to "helm template" or "helm upgrade --install"`)
f.StringArrayVar(&applyOptions.PostRendererArgs, "post-renderer-args", nil, `pass --post-renderer-args to "helm template" or "helm upgrade --install"`) f.StringArrayVar(&applyOptions.PostRendererArgs, "post-renderer-args", nil, `pass --post-renderer-args to "helm template" or "helm upgrade --install"`)
f.BoolVar(&applyOptions.SkipSchemaValidation, "skip-schema-validation", false, `pass --skip-schema-validation to "helm template" or "helm upgrade --install"`)
f.StringVar(&applyOptions.Cascade, "cascade", "", "pass cascade to helm exec, default: background") f.StringVar(&applyOptions.Cascade, "cascade", "", "pass cascade to helm exec, default: background")
f.StringArrayVar(&applyOptions.SuppressOutputLineRegex, "suppress-output-line-regex", nil, "a list of regex patterns to suppress output lines from the diff output") f.StringArrayVar(&applyOptions.SuppressOutputLineRegex, "suppress-output-line-regex", nil, "a list of regex patterns to suppress output lines from the diff output")

View File

@ -48,6 +48,7 @@ func NewSyncCmd(globalCfg *config.GlobalImpl) *cobra.Command {
f.BoolVar(&syncOptions.ResetValues, "reset-values", false, `Override helmDefaults.reuseValues "helm upgrade --install --reset-values"`) f.BoolVar(&syncOptions.ResetValues, "reset-values", false, `Override helmDefaults.reuseValues "helm upgrade --install --reset-values"`)
f.StringVar(&syncOptions.PostRenderer, "post-renderer", "", `pass --post-renderer to "helm template" or "helm upgrade --install"`) f.StringVar(&syncOptions.PostRenderer, "post-renderer", "", `pass --post-renderer to "helm template" or "helm upgrade --install"`)
f.StringArrayVar(&syncOptions.PostRendererArgs, "post-renderer-args", nil, `pass --post-renderer-args to "helm template" or "helm upgrade --install"`) f.StringArrayVar(&syncOptions.PostRendererArgs, "post-renderer-args", nil, `pass --post-renderer-args to "helm template" or "helm upgrade --install"`)
f.BoolVar(&syncOptions.SkipSchemaValidation, "skip-schema-validation", false, `pass --skip-schema-validation to "helm template" or "helm upgrade --install"`)
f.StringVar(&syncOptions.Cascade, "cascade", "", "pass cascade to helm exec, default: background") f.StringVar(&syncOptions.Cascade, "cascade", "", "pass cascade to helm exec, default: background")
return cmd return cmd

View File

@ -47,6 +47,7 @@ func NewTemplateCmd(globalCfg *config.GlobalImpl) *cobra.Command {
f.BoolVar(&templateOptions.SkipCleanup, "skip-cleanup", false, "Stop cleaning up temporary values generated by helmfile and helm-secrets. Useful for debugging. Don't use in production for security") f.BoolVar(&templateOptions.SkipCleanup, "skip-cleanup", false, "Stop cleaning up temporary values generated by helmfile and helm-secrets. Useful for debugging. Don't use in production for security")
f.StringVar(&templateOptions.PostRenderer, "post-renderer", "", `pass --post-renderer to "helm template" or "helm upgrade --install"`) f.StringVar(&templateOptions.PostRenderer, "post-renderer", "", `pass --post-renderer to "helm template" or "helm upgrade --install"`)
f.StringArrayVar(&templateOptions.PostRendererArgs, "post-renderer-args", nil, `pass --post-renderer-args to "helm template" or "helm upgrade --install"`) f.StringArrayVar(&templateOptions.PostRendererArgs, "post-renderer-args", nil, `pass --post-renderer-args to "helm template" or "helm upgrade --install"`)
f.BoolVar(&templateOptions.SkipSchemaValidation, "skip-schema-validation", false, `pass skip-schema-validation to "helm template" or "helm upgrade --install"`)
f.StringVar(&templateOptions.KubeVersion, "kube-version", "", `pass --kube-version to "helm template". Overrides kubeVersion in helmfile.yaml`) f.StringVar(&templateOptions.KubeVersion, "kube-version", "", `pass --kube-version to "helm template". Overrides kubeVersion in helmfile.yaml`)
f.StringArrayVar(&templateOptions.ShowOnly, "show-only", nil, `pass --show-only to "helm template"`) f.StringArrayVar(&templateOptions.ShowOnly, "show-only", nil, `pass --show-only to "helm template"`)

View File

@ -1537,17 +1537,18 @@ Do you really want to apply?
subst.Releases = rs subst.Releases = rs
syncOpts := &state.SyncOpts{ syncOpts := &state.SyncOpts{
Set: c.Set(), Set: c.Set(),
SkipCleanup: c.RetainValuesFiles() || c.SkipCleanup(), SkipCleanup: c.RetainValuesFiles() || c.SkipCleanup(),
SkipCRDs: c.SkipCRDs(), SkipCRDs: c.SkipCRDs(),
Wait: c.Wait(), Wait: c.Wait(),
WaitForJobs: c.WaitForJobs(), WaitForJobs: c.WaitForJobs(),
ReuseValues: c.ReuseValues(), ReuseValues: c.ReuseValues(),
ResetValues: c.ResetValues(), ResetValues: c.ResetValues(),
PostRenderer: c.PostRenderer(), PostRenderer: c.PostRenderer(),
PostRendererArgs: c.PostRendererArgs(), PostRendererArgs: c.PostRendererArgs(),
SyncArgs: c.SyncArgs(), SkipSchemaValidation: c.SkipSchemaValidation(),
HideNotes: c.HideNotes(), SyncArgs: c.SyncArgs(),
HideNotes: c.HideNotes(),
} }
return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), syncOpts) return subst.SyncReleases(&affectedReleases, helm, c.Values(), c.Concurrency(), syncOpts)
})) }))
@ -1673,6 +1674,7 @@ func (a *App) diff(r *Run, c DiffConfigProvider) (*string, bool, bool, []error)
ResetValues: c.ResetValues(), ResetValues: c.ResetValues(),
PostRenderer: c.PostRenderer(), PostRenderer: c.PostRenderer(),
PostRendererArgs: c.PostRendererArgs(), PostRendererArgs: c.PostRendererArgs(),
SkipSchemaValidation: c.SkipSchemaValidation(),
SuppressOutputLineRegex: c.SuppressOutputLineRegex(), SuppressOutputLineRegex: c.SuppressOutputLineRegex(),
} }

View File

@ -2085,15 +2085,16 @@ services:
} }
type configImpl struct { type configImpl struct {
selectors []string selectors []string
set []string set []string
output string output string
includeCRDs bool includeCRDs bool
skipCleanup bool skipCleanup bool
skipCRDs bool skipCRDs bool
skipDeps bool skipDeps bool
skipRefresh bool skipTests bool
skipTests bool skipSchemaValidation bool
skipRefresh bool
skipNeeds bool skipNeeds bool
includeNeeds bool includeNeeds bool
@ -2194,6 +2195,10 @@ func (c configImpl) KubeVersion() string {
return c.kubeVersion return c.kubeVersion
} }
func (c configImpl) SkipSchemaValidation() bool {
return c.skipSchemaValidation
}
func (c configImpl) ShowOnly() []string { func (c configImpl) ShowOnly() []string {
return nil return nil
} }
@ -2238,6 +2243,7 @@ type applyConfig struct {
reuseValues bool reuseValues bool
postRenderer string postRenderer string
postRendererArgs []string postRendererArgs []string
skipSchemaValidation bool
kubeVersion string kubeVersion string
suppressOutputLineRegex []string suppressOutputLineRegex []string
showOnly []string showOnly []string
@ -2422,6 +2428,10 @@ func (a applyConfig) KubeVersion() string {
return a.kubeVersion return a.kubeVersion
} }
func (a applyConfig) SkipSchemaValidation() bool {
return a.skipSchemaValidation
}
func (a applyConfig) ShowOnly() []string { func (a applyConfig) ShowOnly() []string {
return a.showOnly return a.showOnly
} }

View File

@ -51,6 +51,7 @@ type ApplyConfigProvider interface {
Args() string Args() string
PostRenderer() string PostRenderer() string
PostRendererArgs() []string PostRendererArgs() []string
SkipSchemaValidation() bool
Cascade() string Cascade() string
HideNotes() bool HideNotes() bool
SuppressOutputLineRegex() []string SuppressOutputLineRegex() []string
@ -130,6 +131,7 @@ type DiffConfigProvider interface {
Args() string Args() string
PostRenderer() string PostRenderer() string
PostRendererArgs() []string PostRendererArgs() []string
SkipSchemaValidation() bool
SuppressOutputLineRegex() []string SuppressOutputLineRegex() []string
Values() []string Values() []string

View File

@ -43,6 +43,7 @@ type diffConfig struct {
stripTrailingCR bool stripTrailingCR bool
interactive bool interactive bool
skipDiffOnInstall bool skipDiffOnInstall bool
skipSchemaValidation bool
reuseValues bool reuseValues bool
logger *zap.SugaredLogger logger *zap.SugaredLogger
} }
@ -175,6 +176,10 @@ func (a diffConfig) PostRendererArgs() []string {
return nil return nil
} }
func (a diffConfig) SkipSchemaValidation() bool {
return a.skipSchemaValidation
}
func (a diffConfig) SuppressOutputLineRegex() []string { func (a diffConfig) SuppressOutputLineRegex() []string {
return a.suppressOutputLineRegex return a.suppressOutputLineRegex
} }

View File

@ -52,6 +52,8 @@ type ApplyOptions struct {
Wait bool Wait bool
// WaitForJobs is true if the helm command should wait for the jobs to be completed // WaitForJobs is true if the helm command should wait for the jobs to be completed
WaitForJobs bool WaitForJobs bool
// Propagate '--skipSchemaValidation' to helmv3 template and helm install
SkipSchemaValidation bool
// ReuseValues is true if the helm command should reuse the values // ReuseValues is true if the helm command should reuse the values
ReuseValues bool ReuseValues bool
// ResetValues is true if helm command should reset values to charts' default // ResetValues is true if helm command should reset values to charts' default
@ -235,6 +237,11 @@ func (a *ApplyImpl) PostRendererArgs() []string {
return a.ApplyOptions.PostRendererArgs return a.ApplyOptions.PostRendererArgs
} }
// SkipSchemaValidation returns the SkipSchemaValidation.
func (a *ApplyImpl) SkipSchemaValidation() bool {
return a.ApplyOptions.SkipSchemaValidation
}
// Cascade returns cascade flag // Cascade returns cascade flag
func (a *ApplyImpl) Cascade() string { func (a *ApplyImpl) Cascade() string {
return a.ApplyOptions.Cascade return a.ApplyOptions.Cascade

View File

@ -48,6 +48,7 @@ type DiffOptions struct {
DiffArgs string DiffArgs string
// SuppressOutputLineRegex is a list of regexes to suppress output lines // SuppressOutputLineRegex is a list of regexes to suppress output lines
SuppressOutputLineRegex []string SuppressOutputLineRegex []string
SkipSchemaValidation bool
} }
// NewDiffOptions creates a new Apply // NewDiffOptions creates a new Apply
@ -199,3 +200,7 @@ func (t *DiffImpl) PostRendererArgs() []string {
func (t *DiffImpl) SuppressOutputLineRegex() []string { func (t *DiffImpl) SuppressOutputLineRegex() []string {
return t.DiffOptions.SuppressOutputLineRegex return t.DiffOptions.SuppressOutputLineRegex
} }
func (t *DiffImpl) SkipSchemaValidation() bool {
return t.DiffOptions.SkipSchemaValidation
}

View File

@ -30,6 +30,8 @@ type SyncOptions struct {
PostRenderer string PostRenderer string
// Propagate '--post-renderer-args' to helmv3 template and helm install // Propagate '--post-renderer-args' to helmv3 template and helm install
PostRendererArgs []string PostRendererArgs []string
// Propagate '--skipSchemaValidation' to helmv3 template and helm install
SkipSchemaValidation bool
// Cascade '--cascade' to helmv3 delete, available values: background, foreground, or orphan, default: background // Cascade '--cascade' to helmv3 delete, available values: background, foreground, or orphan, default: background
Cascade string Cascade string
// SyncArgs is the list of arguments to pass to the helm upgrade command. // SyncArgs is the list of arguments to pass to the helm upgrade command.
@ -132,6 +134,11 @@ func (t *SyncImpl) PostRendererArgs() []string {
return t.SyncOptions.PostRendererArgs return t.SyncOptions.PostRendererArgs
} }
// SkipSchemaValidation returns the SkipSchemaValidation.
func (t *SyncImpl) SkipSchemaValidation() bool {
return t.SyncOptions.SkipSchemaValidation
}
// Cascade returns cascade flag // Cascade returns cascade flag
func (t *SyncImpl) Cascade() string { func (t *SyncImpl) Cascade() string {
return t.SyncOptions.Cascade return t.SyncOptions.Cascade

View File

@ -36,6 +36,8 @@ type TemplateOptions struct {
PostRenderer string PostRenderer string
// Propagate '--post-renderer-args' to helmv3 template and helm install // Propagate '--post-renderer-args' to helmv3 template and helm install
PostRendererArgs []string PostRendererArgs []string
// Propagate '--skipSchemaValidation' to helmv3 template and helm install
SkipSchemaValidation bool
// KubeVersion is the kube-version flag // KubeVersion is the kube-version flag
KubeVersion string KubeVersion string
// Propagate '--show-only` to helm template // Propagate '--show-only` to helm template
@ -135,6 +137,11 @@ func (t *TemplateImpl) PostRendererArgs() []string {
return t.TemplateOptions.PostRendererArgs return t.TemplateOptions.PostRendererArgs
} }
// SkipSchemaValidation returns the SkipSchemaValidation.
func (t *TemplateImpl) SkipSchemaValidation() bool {
return t.TemplateOptions.SkipSchemaValidation
}
// KubeVersion returns the the KubeVersion. // KubeVersion returns the the KubeVersion.
func (t *TemplateImpl) KubeVersion() string { func (t *TemplateImpl) KubeVersion() string {
return t.TemplateOptions.KubeVersion return t.TemplateOptions.KubeVersion

View File

@ -94,6 +94,8 @@ func (helm *Helm) SetEnableLiveOutput(enableLiveOutput bool) {
} }
func (helm *Helm) SetDisableForceUpdate(forceUpdate bool) { func (helm *Helm) SetDisableForceUpdate(forceUpdate bool) {
} }
func (helm *Helm) SkipSchemaValidation(skipSchemaValidation bool) {
}
func (helm *Helm) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials, skipTLSVerify bool) error { func (helm *Helm) AddRepo(name, repository, cafile, certfile, keyfile, username, password string, managed string, passCredentials, skipTLSVerify bool) error {
helm.Repo = []string{name, repository, cafile, certfile, keyfile, username, password, managed, fmt.Sprintf("%v", passCredentials), fmt.Sprintf("%v", skipTLSVerify)} helm.Repo = []string{name, repository, cafile, certfile, keyfile, username, password, managed, fmt.Sprintf("%v", passCredentials), fmt.Sprintf("%v", skipTLSVerify)}
return nil return nil

View File

@ -58,6 +58,22 @@ func (st *HelmState) appendPostRenderArgsFlags(flags []string, release *ReleaseS
return flags return flags
} }
// 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:
flags = append(flags, "--skip-schema-validation")
}
return flags
}
// append suppress-output-line-regex flags to helm diff flags // append suppress-output-line-regex flags to helm diff flags
func (st *HelmState) appendSuppressOutputLineRegexFlags(flags []string, release *ReleaseSpec, suppressOutputLineRegex []string) []string { func (st *HelmState) appendSuppressOutputLineRegexFlags(flags []string, release *ReleaseSpec, suppressOutputLineRegex []string) []string {
suppressOutputLineRegexFlags := []string{} suppressOutputLineRegexFlags := []string{}

View File

@ -160,6 +160,8 @@ type HelmSpec struct {
Keyring string `yaml:"keyring,omitempty"` Keyring string `yaml:"keyring,omitempty"`
// EnableDNS, when set to true, enable DNS lookups when rendering templates // EnableDNS, when set to true, enable DNS lookups when rendering templates
EnableDNS bool `yaml:"enableDNS"` EnableDNS bool `yaml:"enableDNS"`
// Propagate '--skipSchemaValidation' to helmv3 template and helm install
SkipSchemaValidation *bool `yaml:"skipSchemaValidation,omitempty"`
// Devel, when set to true, use development versions, too. Equivalent to version '>0.0.0-0' // Devel, when set to true, use development versions, too. Equivalent to version '>0.0.0-0'
Devel bool `yaml:"devel"` Devel bool `yaml:"devel"`
// Wait, if set to true, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful // Wait, if set to true, will wait until all Pods, PVCs, Services, and minimum number of Pods of a Deployment are in a ready state before marking the release as successful
@ -382,6 +384,9 @@ type ReleaseSpec struct {
// Propagate '--post-renderer' to helmv3 template and helm install // Propagate '--post-renderer' to helmv3 template and helm install
PostRenderer *string `yaml:"postRenderer,omitempty"` PostRenderer *string `yaml:"postRenderer,omitempty"`
// Propagate '--skipSchemaValidation' to helmv3 template and helm install
SkipSchemaValidation *bool `yaml:"skipSchemaValidation,omitempty"`
// Propagate '--post-renderer-args' to helmv3 template and helm install // Propagate '--post-renderer-args' to helmv3 template and helm install
PostRendererArgs []string `yaml:"postRendererArgs,omitempty"` PostRendererArgs []string `yaml:"postRendererArgs,omitempty"`
@ -770,17 +775,18 @@ func (st *HelmState) DetectReleasesToBeDeleted(helm helmexec.Interface, releases
} }
type SyncOpts struct { type SyncOpts struct {
Set []string Set []string
SkipCleanup bool SkipCleanup bool
SkipCRDs bool SkipCRDs bool
Wait bool Wait bool
WaitForJobs bool WaitForJobs bool
ReuseValues bool ReuseValues bool
ResetValues bool ResetValues bool
PostRenderer string PostRenderer string
PostRendererArgs []string SkipSchemaValidation bool
SyncArgs string PostRendererArgs []string
HideNotes bool SyncArgs string
HideNotes bool
} }
type SyncOpt interface{ Apply(*SyncOpts) } type SyncOpt interface{ Apply(*SyncOpts) }
@ -1997,6 +2003,7 @@ type DiffOpts struct {
PostRenderer string PostRenderer string
PostRendererArgs []string PostRendererArgs []string
SuppressOutputLineRegex []string SuppressOutputLineRegex []string
SkipSchemaValidation bool
} }
func (o *DiffOpts) Apply(opts *DiffOpts) { func (o *DiffOpts) Apply(opts *DiffOpts) {
@ -2742,6 +2749,13 @@ func (st *HelmState) flagsForUpgrade(helm helmexec.Interface, release *ReleaseSp
} }
flags = st.appendPostRenderArgsFlags(flags, release, postRendererArgs) flags = st.appendPostRenderArgsFlags(flags, release, postRendererArgs)
skipSchemaValidation := false
if opt != nil {
skipSchemaValidation = opt.SkipSchemaValidation
}
flags = st.appendSkipSchemaValidationFlags(flags, release, skipSchemaValidation)
// append hide-notes flag // append hide-notes flag
flags = st.appendHideNotesFlags(flags, helm, opt) flags = st.appendHideNotesFlags(flags, helm, opt)
@ -2849,6 +2863,12 @@ func (st *HelmState) flagsForDiff(helm helmexec.Interface, release *ReleaseSpec,
} }
flags = st.appendPostRenderArgsFlags(flags, release, postRendererArgs) flags = st.appendPostRenderArgsFlags(flags, release, postRendererArgs)
skipSchemaValidation := false
if opt != nil {
skipSchemaValidation = opt.SkipSchemaValidation
}
flags = st.appendSkipSchemaValidationFlags(flags, release, skipSchemaValidation)
suppressOutputLineRegex := []string{} suppressOutputLineRegex := []string{}
if opt != nil { if opt != nil {
suppressOutputLineRegex = opt.SuppressOutputLineRegex suppressOutputLineRegex = opt.SuppressOutputLineRegex

View File

@ -38,39 +38,39 @@ func TestGenerateID(t *testing.T) {
run(testcase{ run(testcase{
subject: "baseline", subject: "baseline",
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"}, release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"},
want: "foo-values-d566bffd8", want: "foo-values-5db58595d7",
}) })
run(testcase{ run(testcase{
subject: "different bytes content", subject: "different bytes content",
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"}, release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"},
data: []byte(`{"k":"v"}`), data: []byte(`{"k":"v"}`),
want: "foo-values-65b557f8c5", want: "foo-values-78d88d86dd",
}) })
run(testcase{ run(testcase{
subject: "different map content", subject: "different map content",
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"}, release: ReleaseSpec{Name: "foo", Chart: "incubator/raw"},
data: map[string]any{"k": "v"}, data: map[string]any{"k": "v"},
want: "foo-values-74d5cd8cc7", want: "foo-values-f9c8967cd",
}) })
run(testcase{ run(testcase{
subject: "different chart", subject: "different chart",
release: ReleaseSpec{Name: "foo", Chart: "stable/envoy"}, release: ReleaseSpec{Name: "foo", Chart: "stable/envoy"},
want: "foo-values-85db6bbb4c", want: "foo-values-cdfb97444",
}) })
run(testcase{ run(testcase{
subject: "different name", subject: "different name",
release: ReleaseSpec{Name: "bar", Chart: "incubator/raw"}, release: ReleaseSpec{Name: "bar", Chart: "incubator/raw"},
want: "bar-values-85cf974b7", want: "bar-values-749bc4c6d4",
}) })
run(testcase{ run(testcase{
subject: "specific ns", subject: "specific ns",
release: ReleaseSpec{Name: "foo", Chart: "incubator/raw", Namespace: "myns"}, release: ReleaseSpec{Name: "foo", Chart: "incubator/raw", Namespace: "myns"},
want: "myns-foo-values-574676fbb9", want: "myns-foo-values-7b74fbd6d6",
}) })
for id, n := range ids { for id, n := range ids {