v1: Fix --state-values-set to override values of environments colocated with releases (#705)
This commit is contained in:
		
							parent
							
								
									522392c08c
								
							
						
					
					
						commit
						95c56d87fc
					
				|  | @ -117,8 +117,8 @@ func setGlobalOptionsForRootCmd(fs *pflag.FlagSet, globalOptions *config.GlobalO | |||
| 	fs.StringVarP(&globalOptions.HelmBinary, "helm-binary", "b", app.DefaultHelmBinary, "Path to the helm binary") | ||||
| 	fs.StringVarP(&globalOptions.File, "file", "f", "", "load config from file or directory. defaults to `helmfile.yaml` or `helmfile.yaml.gotmpl` or `helmfile.d`(means `helmfile.d/*.yaml` or `helmfile.d/*.yaml.gotmpl`) in this preference. Specify - to load the config from the standard input.") | ||||
| 	fs.StringVarP(&globalOptions.Environment, "environment", "e", "", `specify the environment name. defaults to "default"`) | ||||
| 	fs.StringArrayVar(&globalOptions.StateValuesSet, "state-values-set", nil, "set state values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)") | ||||
| 	fs.StringArrayVar(&globalOptions.StateValuesFile, "state-values-file", nil, "specify state values in a YAML file") | ||||
| 	fs.StringArrayVar(&globalOptions.StateValuesSet, "state-values-set", nil, "set state values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2). Used to override .Values within the helmfile template (not values template).") | ||||
| 	fs.StringArrayVar(&globalOptions.StateValuesFile, "state-values-file", nil, "specify state values in a YAML file. Used to override .Values within the helmfile template (not values template).") | ||||
| 	fs.BoolVarP(&globalOptions.Quiet, "quiet", "q", false, "Silence output. Equivalent to log-level warn") | ||||
| 	fs.StringVar(&globalOptions.KubeContext, "kube-context", "", "Set kubectl context. Uses current context by default") | ||||
| 	fs.BoolVar(&globalOptions.Debug, "debug", false, "Enable verbose output for Helm and set log-level to debug, this disables --quiet/-q effect") | ||||
|  |  | |||
|  | @ -553,8 +553,8 @@ Flags: | |||
|                                         A release must match all labels in a group in order to be used. Multiple groups can be specified at once. | ||||
|                                         "--selector tier=frontend,tier!=proxy --selector tier=backend" will match all frontend, non-proxy releases AND all backend releases. | ||||
|                                         The name of a release can be used as a label: "--selector name=myrelease" | ||||
|       --state-values-file stringArray   specify state values in a YAML file | ||||
|       --state-values-set stringArray    set state values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) | ||||
|       --state-values-file stringArray   specify state values in a YAML file. Used to override .Values within the helmfile template (not values template). | ||||
|       --state-values-set stringArray    set state values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2). Used to override .Values within the helmfile template (not values template). | ||||
|   -v, --version                         version for helmfile | ||||
| 
 | ||||
| Use "helmfile [command] --help" for more information about a command. | ||||
|  |  | |||
|  | @ -100,7 +100,7 @@ func (ld *desiredStateLoader) Load(f string, opts LoadOpts) (*state.HelmState, e | |||
| 	return st, nil | ||||
| } | ||||
| 
 | ||||
| func (ld *desiredStateLoader) loadFile(inheritedEnv *environment.Environment, baseDir, file string, evaluateBases bool) (*state.HelmState, error) { | ||||
| func (ld *desiredStateLoader) loadFile(inheritedEnv, overrodeEnv *environment.Environment, baseDir, file string, evaluateBases bool) (*state.HelmState, error) { | ||||
| 	path, err := ld.remote.Locate(file) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("locate: %v", err) | ||||
|  | @ -109,7 +109,7 @@ func (ld *desiredStateLoader) loadFile(inheritedEnv *environment.Environment, ba | |||
| 		ld.logger.Debugf("fetched remote \"%s\" to local cache \"%s\" and loading the latter...", file, path) | ||||
| 	} | ||||
| 	file = path | ||||
| 	return ld.loadFileWithOverrides(inheritedEnv, nil, baseDir, file, evaluateBases) | ||||
| 	return ld.loadFileWithOverrides(inheritedEnv, overrodeEnv, baseDir, file, evaluateBases) | ||||
| } | ||||
| 
 | ||||
| func (ld *desiredStateLoader) loadFileWithOverrides(inheritedEnv, overrodeEnv *environment.Environment, baseDir, file string, evaluateBases bool) (*state.HelmState, error) { | ||||
|  | @ -157,16 +157,24 @@ func (a *desiredStateLoader) underlying() *state.StateCreator { | |||
| } | ||||
| 
 | ||||
| func (a *desiredStateLoader) rawLoad(yaml []byte, baseDir, file string, evaluateBases bool, env, overrodeEnv *environment.Environment) (*state.HelmState, error) { | ||||
| 	var st *state.HelmState | ||||
| 	var err error | ||||
| 	if runtime.V1Mode { | ||||
| 		st, err = a.underlying().ParseAndLoad(yaml, baseDir, file, a.env, evaluateBases, env, overrodeEnv) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} else { | ||||
| 		merged, err := env.Merge(overrodeEnv) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 
 | ||||
| 	st, err := a.underlying().ParseAndLoad(yaml, baseDir, file, a.env, evaluateBases, merged) | ||||
| 		st, err = a.underlying().ParseAndLoad(yaml, baseDir, file, a.env, evaluateBases, merged, nil) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 	helmfiles, err := st.ExpandedHelmfiles() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
|  |  | |||
|  | @ -22,8 +22,12 @@ func prependLineNumbers(text string) string { | |||
| 	return buf.String() | ||||
| } | ||||
| 
 | ||||
| func (r *desiredStateLoader) renderPrestate(firstPassEnv *environment.Environment, baseDir, filename string, content []byte) (*environment.Environment, *state.HelmState) { | ||||
| 	tmplData := state.NewEnvironmentTemplateData(*firstPassEnv, r.namespace, map[string]interface{}{}) | ||||
| func (r *desiredStateLoader) renderPrestate(firstPassEnv, overrode *environment.Environment, baseDir, filename string, content []byte) (*environment.Environment, *state.HelmState) { | ||||
| 	initEnv, err := firstPassEnv.Merge(overrode) | ||||
| 	if err != nil { | ||||
| 		return firstPassEnv, nil | ||||
| 	} | ||||
| 	tmplData := state.NewEnvironmentTemplateData(*initEnv, r.namespace, map[string]interface{}{}) | ||||
| 	firstPassRenderer := tmpl.NewFirstPassRenderer(baseDir, tmplData) | ||||
| 
 | ||||
| 	// parse as much as we can, tolerate errors, this is a preparse
 | ||||
|  | @ -49,7 +53,7 @@ func (r *desiredStateLoader) renderPrestate(firstPassEnv *environment.Environmen | |||
| 	c := r.underlying() | ||||
| 	c.Strict = false | ||||
| 	// create preliminary state, as we may have an environment. Tolerate errors.
 | ||||
| 	prestate, err := c.ParseAndLoad([]byte(sanitized), baseDir, filename, r.env, false, firstPassEnv) | ||||
| 	prestate, err := c.ParseAndLoad([]byte(sanitized), baseDir, filename, r.env, false, firstPassEnv, overrode) | ||||
| 	if err != nil { | ||||
| 		if _, ok := err.(*state.StateLoadError); ok { | ||||
| 			r.logger.Debugf("could not deduce `environment:` block, configuring only .Environment.Name. error: %v", err) | ||||
|  | @ -85,7 +89,7 @@ func (r *desiredStateLoader) twoPassRenderTemplateToYaml(inherited, overrode *en | |||
| 	} | ||||
| 	r.logger.Debugf("%srendering starting for \"%s\": inherited=%v, overrode=%v", phase, filename, inherited, overrode) | ||||
| 
 | ||||
| 	initEnv, err := inherited.Merge(overrode) | ||||
| 	initEnv, err := inherited.Merge(nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | @ -99,7 +103,10 @@ func (r *desiredStateLoader) twoPassRenderTemplateToYaml(inherited, overrode *en | |||
| 	if runtime.V1Mode { | ||||
| 		var err error | ||||
| 
 | ||||
| 		finalEnv = initEnv | ||||
| 		finalEnv, err = initEnv.Merge(overrode) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 
 | ||||
| 		vals, err = finalEnv.GetMergedValues() | ||||
| 		if err != nil { | ||||
|  | @ -107,8 +114,11 @@ func (r *desiredStateLoader) twoPassRenderTemplateToYaml(inherited, overrode *en | |||
| 		} | ||||
| 	} else { | ||||
| 		r.logger.Debugf("first-pass uses: %v", initEnv) | ||||
| 
 | ||||
| 		renderedEnv, prestate := r.renderPrestate(initEnv, baseDir, filename, content) | ||||
| 		firstPassEnv, err := initEnv.Merge(nil) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		renderedEnv, prestate := r.renderPrestate(firstPassEnv, overrode, baseDir, filename, content) | ||||
| 
 | ||||
| 		r.logger.Debugf("first-pass produced: %v", renderedEnv) | ||||
| 
 | ||||
|  |  | |||
|  | @ -47,7 +47,7 @@ type StateCreator struct { | |||
| 
 | ||||
| 	Strict bool | ||||
| 
 | ||||
| 	LoadFile func(inheritedEnv *environment.Environment, baseDir, file string, evaluateBases bool) (*HelmState, error) | ||||
| 	LoadFile func(inheritedEnv, overrodeEnv *environment.Environment, baseDir, file string, evaluateBases bool) (*HelmState, error) | ||||
| 
 | ||||
| 	getHelm func(*HelmState) helmexec.Interface | ||||
| 
 | ||||
|  | @ -138,10 +138,10 @@ func (c *StateCreator) Parse(content []byte, baseDir, file string) (*HelmState, | |||
| } | ||||
| 
 | ||||
| // LoadEnvValues loads environment values files relative to the `baseDir`
 | ||||
| func (c *StateCreator) LoadEnvValues(target *HelmState, env string, ctxEnv *environment.Environment, failOnMissingEnv bool) (*HelmState, error) { | ||||
| func (c *StateCreator) LoadEnvValues(target *HelmState, env string, ctxEnv, overrode *environment.Environment, failOnMissingEnv bool) (*HelmState, error) { | ||||
| 	state := *target | ||||
| 
 | ||||
| 	e, err := c.loadEnvValues(&state, env, failOnMissingEnv, ctxEnv) | ||||
| 	e, err := c.loadEnvValues(&state, env, failOnMissingEnv, ctxEnv, overrode) | ||||
| 	if err != nil { | ||||
| 		return nil, &StateLoadError{fmt.Sprintf("failed to read %s", state.FilePath), err} | ||||
| 	} | ||||
|  | @ -162,7 +162,7 @@ func (c *StateCreator) LoadEnvValues(target *HelmState, env string, ctxEnv *envi | |||
| 
 | ||||
| // Parses YAML into HelmState, while loading environment values files relative to the `baseDir`
 | ||||
| // evaluateBases=true means that this is NOT a base helmfile
 | ||||
| func (c *StateCreator) ParseAndLoad(content []byte, baseDir, file string, envName string, evaluateBases bool, envValues *environment.Environment) (*HelmState, error) { | ||||
| func (c *StateCreator) ParseAndLoad(content []byte, baseDir, file string, envName string, evaluateBases bool, envValues, overrode *environment.Environment) (*HelmState, error) { | ||||
| 	state, err := c.Parse(content, baseDir, file) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
|  | @ -173,13 +173,13 @@ func (c *StateCreator) ParseAndLoad(content []byte, baseDir, file string, envNam | |||
| 			return nil, errors.New("nested `base` helmfile is unsupported. please submit a feature request if you need this!") | ||||
| 		} | ||||
| 	} else { | ||||
| 		state, err = c.loadBases(envValues, state, baseDir) | ||||
| 		state, err = c.loadBases(envValues, overrode, state, baseDir) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	state, err = c.LoadEnvValues(state, envName, envValues, evaluateBases) | ||||
| 	state, err = c.LoadEnvValues(state, envName, envValues, overrode, evaluateBases) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | @ -195,10 +195,10 @@ func (c *StateCreator) ParseAndLoad(content []byte, baseDir, file string, envNam | |||
| 	return state, nil | ||||
| } | ||||
| 
 | ||||
| func (c *StateCreator) loadBases(envValues *environment.Environment, st *HelmState, baseDir string) (*HelmState, error) { | ||||
| func (c *StateCreator) loadBases(envValues, overrodeEnv *environment.Environment, st *HelmState, baseDir string) (*HelmState, error) { | ||||
| 	layers := []*HelmState{} | ||||
| 	for _, b := range st.Bases { | ||||
| 		base, err := c.LoadFile(envValues, baseDir, b, false) | ||||
| 		base, err := c.LoadFile(envValues, overrodeEnv, baseDir, b, false) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | @ -216,7 +216,7 @@ func (c *StateCreator) loadBases(envValues *environment.Environment, st *HelmSta | |||
| } | ||||
| 
 | ||||
| // nolint: unparam
 | ||||
| func (c *StateCreator) loadEnvValues(st *HelmState, name string, failOnMissingEnv bool, ctxEnv *environment.Environment) (*environment.Environment, error) { | ||||
| func (c *StateCreator) loadEnvValues(st *HelmState, name string, failOnMissingEnv bool, ctxEnv, overrode *environment.Environment) (*environment.Environment, error) { | ||||
| 	envVals := map[string]interface{}{} | ||||
| 	envSpec, ok := st.Environments[name] | ||||
| 	if ok { | ||||
|  | @ -250,13 +250,23 @@ func (c *StateCreator) loadEnvValues(st *HelmState, name string, failOnMissingEn | |||
| 	newEnv := &environment.Environment{Name: name, Values: envVals} | ||||
| 
 | ||||
| 	if ctxEnv != nil { | ||||
| 		intEnv := *ctxEnv | ||||
| 		intCtxEnv := *ctxEnv | ||||
| 
 | ||||
| 		if err := mergo.Merge(&intEnv, newEnv, mergo.WithOverride, mergo.WithOverwriteWithEmptyValue); err != nil { | ||||
| 		if err := mergo.Merge(&intCtxEnv, newEnv, mergo.WithOverride, mergo.WithOverwriteWithEmptyValue); err != nil { | ||||
| 			return nil, fmt.Errorf("error while merging environment values for \"%s\": %v", name, err) | ||||
| 		} | ||||
| 
 | ||||
| 		newEnv = &intEnv | ||||
| 		newEnv = &intCtxEnv | ||||
| 	} | ||||
| 
 | ||||
| 	if overrode != nil { | ||||
| 		intOverrodeEnv := *newEnv | ||||
| 
 | ||||
| 		if err := mergo.Merge(&intOverrodeEnv, overrode, mergo.WithOverride, mergo.WithOverwriteWithEmptyValue); err != nil { | ||||
| 			return nil, fmt.Errorf("error while merging environment overrode values for \"%s\": %v", name, err) | ||||
| 		} | ||||
| 
 | ||||
| 		newEnv = &intOverrodeEnv | ||||
| 	} | ||||
| 
 | ||||
| 	return newEnv, nil | ||||
|  |  | |||
|  | @ -20,7 +20,7 @@ func createFromYaml(content []byte, file string, env string, logger *zap.Sugared | |||
| 		fs:     filesystem.DefaultFileSystem(), | ||||
| 		Strict: true, | ||||
| 	} | ||||
| 	return c.ParseAndLoad(content, filepath.Dir(file), file, env, true, nil) | ||||
| 	return c.ParseAndLoad(content, filepath.Dir(file), file, env, true, nil, nil) | ||||
| } | ||||
| 
 | ||||
| func TestReadFromYaml(t *testing.T) { | ||||
|  | @ -84,7 +84,7 @@ func (testEnv stateTestEnv) MustLoadStateWithEnableLiveOutput(t *testing.T, file | |||
| 
 | ||||
| 	r := remote.NewRemote(logger, testFs.Cwd, testFs.ToFileSystem()) | ||||
| 	state, err := NewCreator(logger, testFs.ToFileSystem(), nil, nil, "", r, enableLiveOutput, ""). | ||||
| 		ParseAndLoad([]byte(yamlContent), filepath.Dir(file), file, envName, true, nil) | ||||
| 		ParseAndLoad([]byte(yamlContent), filepath.Dir(file), file, envName, true, nil, nil) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("unexpected error: %v", err) | ||||
| 	} | ||||
|  | @ -154,7 +154,7 @@ releaseNamespace: mynamespace | |||
| 		Name: "production", | ||||
| 	} | ||||
| 	state, err := NewCreator(logger, testFs.ToFileSystem(), nil, nil, "", r, false, ""). | ||||
| 		ParseAndLoad(yamlContent, filepath.Dir(yamlFile), yamlFile, "production", true, &env) | ||||
| 		ParseAndLoad(yamlContent, filepath.Dir(yamlFile), yamlFile, "production", true, &env, nil) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("unexpected error: %v", err) | ||||
| 	} | ||||
|  | @ -241,7 +241,7 @@ overrideNamespace: myns | |||
| 
 | ||||
| 	r := remote.NewRemote(logger, testFs.Cwd, testFs.ToFileSystem()) | ||||
| 	state, err := NewCreator(logger, testFs.ToFileSystem(), nil, nil, "", r, false, ""). | ||||
| 		ParseAndLoad(yamlContent, filepath.Dir(yamlFile), yamlFile, "production", true, nil) | ||||
| 		ParseAndLoad(yamlContent, filepath.Dir(yamlFile), yamlFile, "production", true, nil, nil) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("unexpected error: %v", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -0,0 +1,29 @@ | |||
| cli-overwrite-environment-values_input_dir="${cases_dir}/cli-overwrite-environment-values/input" | ||||
| cli-overwrite-environment-values_output_dir="${cases_dir}/cli-overwrite-environment-values/output" | ||||
| 
 | ||||
| cli_overwrite_environment_values_tmp=$(mktemp -d) | ||||
| cli_overwrite_environment_values_reverse=${cli_overwrite_environment_values_tmp}/cli.environment.override.build.yaml | ||||
| 
 | ||||
| case_title="cli overwrite environment values" | ||||
| 
 | ||||
| if [[ ${HELMFILE_V1MODE} = true ]]; then | ||||
|   test_start "$case_title for v1" | ||||
|   info "Comparing ${case_title} for v1 output ${cli_overwrite_environment_values_reverse} with ${cli-overwrite-environment-values_output_dir}/overwritten.yaml" | ||||
|   for i in $(seq 10); do | ||||
|       info "Comparing build/cli-overwrite-environment-values #$i" | ||||
|       ${helmfile} -f ${cli-overwrite-environment-values_input_dir}/input_v1.yaml.gotmpl template --state-values-set ns=test3 > ${cli_overwrite_environment_values_reverse} || fail "\"helmfile template\" shouldn't fail" | ||||
|       diff -u ${cli-overwrite-environment-values_output_dir}/output_v1.yaml ${cli_overwrite_environment_values_reverse} || fail "\"helmfile template\" should be consistent" | ||||
|       echo code=$? | ||||
|   done | ||||
|   test_pass "cli overwrite environment values for v1" | ||||
| else | ||||
|   test_start "${case_title}"  | ||||
|   info "Comparing ${case_title} output ${cli_overwrite_environment_values_reverse} with ${cli-overwrite-environment-values_output_dir}/overwritten.yaml" | ||||
|   for i in $(seq 10); do | ||||
|       info "Comparing build/cli-overwrite-environment-values #$i" | ||||
|       ${helmfile} -f ${cli-overwrite-environment-values_input_dir}/input_v1.yaml.gotmpl template --state-values-set ns=test3 > ${cli_overwrite_environment_values_reverse} || fail "\"helmfile template\" shouldn't fail" | ||||
|       diff -u ${cli-overwrite-environment-values_output_dir}/output_v1.yaml ${cli_overwrite_environment_values_reverse} || fail "\"helmfile template\" should be consistent" | ||||
|       echo code=$? | ||||
|   done | ||||
|   test_pass "${case_title}" | ||||
| fi | ||||
|  | @ -0,0 +1 @@ | |||
| ns: test1 | ||||
|  | @ -0,0 +1,5 @@ | |||
| chartifyTempDir: environment_overwrite_values | ||||
| helmfileArgs: | ||||
| - template | ||||
| - --state-values-set | ||||
| - ns=test3 | ||||
|  | @ -0,0 +1,17 @@ | |||
| environments: | ||||
|   default: | ||||
|     values: | ||||
|       - base.yaml | ||||
|       - override.yaml | ||||
| 
 | ||||
| repositories: | ||||
|   - name: bitnami | ||||
|     url: https://charts.bitnami.com/bitnami | ||||
| 
 | ||||
| releases: | ||||
|   - name: test | ||||
|     chart: bitnami/nginx | ||||
|     namespace: {{ .Values.ns }} | ||||
|     version: 13.2.27 | ||||
|     values: | ||||
|       - values.yaml.gotmpl | ||||
|  | @ -0,0 +1,17 @@ | |||
| environments: | ||||
|   default: | ||||
|     values: | ||||
|       - base.yaml | ||||
|       - override.yaml | ||||
| --- | ||||
| repositories: | ||||
|   - name: bitnami | ||||
|     url: https://charts.bitnami.com/bitnami | ||||
| 
 | ||||
| releases: | ||||
|   - name: test | ||||
|     chart: bitnami/nginx | ||||
|     namespace: {{ .Values.ns }} | ||||
|     version: 13.2.27 | ||||
|     values: | ||||
|       - values.yaml.gotmpl | ||||
|  | @ -0,0 +1 @@ | |||
| ns: test2 | ||||
|  | @ -0,0 +1,2 @@ | |||
| image: | ||||
|   tag: {{ .Values.ns }} | ||||
|  | @ -0,0 +1,116 @@ | |||
| Warning: environments and releases cannot be defined within the same YAML part. Use --- to extract the environments into a dedicated part | ||||
| Warning: environments and releases cannot be defined within the same YAML part. Use --- to extract the environments into a dedicated part | ||||
| Adding repo bitnami https://charts.bitnami.com/bitnami | ||||
| "bitnami" has been added to your repositories | ||||
| 
 | ||||
| Templating release=test, chart=bitnami/nginx | ||||
| --- | ||||
| # Source: nginx/templates/svc.yaml | ||||
| apiVersion: v1 | ||||
| kind: Service | ||||
| metadata: | ||||
|   name: test-nginx | ||||
|   namespace: "test3" | ||||
|   labels: | ||||
|     app.kubernetes.io/name: nginx | ||||
|     helm.sh/chart: nginx-13.2.27 | ||||
|     app.kubernetes.io/instance: test | ||||
|     app.kubernetes.io/managed-by: Helm | ||||
|   annotations: | ||||
| spec: | ||||
|   type: LoadBalancer | ||||
|   sessionAffinity: None | ||||
|   externalTrafficPolicy: "Cluster" | ||||
|   ports: | ||||
|     - name: http | ||||
|       port: 80 | ||||
|       targetPort: http | ||||
|   selector: | ||||
|     app.kubernetes.io/name: nginx | ||||
|     app.kubernetes.io/instance: test | ||||
| --- | ||||
| # Source: nginx/templates/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: test-nginx | ||||
|   namespace: "test3" | ||||
|   labels: | ||||
|     app.kubernetes.io/name: nginx | ||||
|     helm.sh/chart: nginx-13.2.27 | ||||
|     app.kubernetes.io/instance: test | ||||
|     app.kubernetes.io/managed-by: Helm | ||||
| spec: | ||||
|   replicas: 1 | ||||
|   strategy: | ||||
|     rollingUpdate: {} | ||||
|     type: RollingUpdate | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app.kubernetes.io/name: nginx | ||||
|       app.kubernetes.io/instance: test | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app.kubernetes.io/name: nginx | ||||
|         helm.sh/chart: nginx-13.2.27 | ||||
|         app.kubernetes.io/instance: test | ||||
|         app.kubernetes.io/managed-by: Helm | ||||
|       annotations: | ||||
|     spec: | ||||
|        | ||||
|       automountServiceAccountToken: false | ||||
|       shareProcessNamespace: false | ||||
|       serviceAccountName: default | ||||
|       affinity: | ||||
|         podAffinity: | ||||
|            | ||||
|         podAntiAffinity: | ||||
|           preferredDuringSchedulingIgnoredDuringExecution: | ||||
|             - podAffinityTerm: | ||||
|                 labelSelector: | ||||
|                   matchLabels: | ||||
|                     app.kubernetes.io/name: nginx | ||||
|                     app.kubernetes.io/instance: test | ||||
|                 topologyKey: kubernetes.io/hostname | ||||
|               weight: 1 | ||||
|         nodeAffinity: | ||||
|            | ||||
|       hostNetwork: false | ||||
|       hostIPC: false | ||||
|       initContainers: | ||||
|       containers: | ||||
|         - name: nginx | ||||
|           image: docker.io/bitnami/nginx:test3 | ||||
|           imagePullPolicy: "IfNotPresent" | ||||
|           env: | ||||
|             - name: BITNAMI_DEBUG | ||||
|               value: "false" | ||||
|             - name: NGINX_HTTP_PORT_NUMBER | ||||
|               value: "8080" | ||||
|           envFrom: | ||||
|           ports: | ||||
|             - name: http | ||||
|               containerPort: 8080 | ||||
|           livenessProbe: | ||||
|             failureThreshold: 6 | ||||
|             initialDelaySeconds: 30 | ||||
|             periodSeconds: 10 | ||||
|             successThreshold: 1 | ||||
|             timeoutSeconds: 5 | ||||
|             tcpSocket: | ||||
|               port: http | ||||
|           readinessProbe: | ||||
|             failureThreshold: 3 | ||||
|             initialDelaySeconds: 5 | ||||
|             periodSeconds: 5 | ||||
|             successThreshold: 1 | ||||
|             timeoutSeconds: 3 | ||||
|             tcpSocket: | ||||
|               port: http | ||||
|           resources: | ||||
|             limits: {} | ||||
|             requests: {} | ||||
|           volumeMounts: | ||||
|       volumes: | ||||
| 
 | ||||
|  | @ -0,0 +1,110 @@ | |||
| --- | ||||
| # Source: nginx/templates/svc.yaml | ||||
| apiVersion: v1 | ||||
| kind: Service | ||||
| metadata: | ||||
|   name: test-nginx | ||||
|   namespace: "test3" | ||||
|   labels: | ||||
|     app.kubernetes.io/name: nginx | ||||
|     helm.sh/chart: nginx-13.2.27 | ||||
|     app.kubernetes.io/instance: test | ||||
|     app.kubernetes.io/managed-by: Helm | ||||
|   annotations: | ||||
| spec: | ||||
|   type: LoadBalancer | ||||
|   sessionAffinity: None | ||||
|   externalTrafficPolicy: "Cluster" | ||||
|   ports: | ||||
|     - name: http | ||||
|       port: 80 | ||||
|       targetPort: http | ||||
|   selector: | ||||
|     app.kubernetes.io/name: nginx | ||||
|     app.kubernetes.io/instance: test | ||||
| --- | ||||
| # Source: nginx/templates/deployment.yaml | ||||
| apiVersion: apps/v1 | ||||
| kind: Deployment | ||||
| metadata: | ||||
|   name: test-nginx | ||||
|   namespace: "test3" | ||||
|   labels: | ||||
|     app.kubernetes.io/name: nginx | ||||
|     helm.sh/chart: nginx-13.2.27 | ||||
|     app.kubernetes.io/instance: test | ||||
|     app.kubernetes.io/managed-by: Helm | ||||
| spec: | ||||
|   replicas: 1 | ||||
|   strategy: | ||||
|     rollingUpdate: {} | ||||
|     type: RollingUpdate | ||||
|   selector: | ||||
|     matchLabels: | ||||
|       app.kubernetes.io/name: nginx | ||||
|       app.kubernetes.io/instance: test | ||||
|   template: | ||||
|     metadata: | ||||
|       labels: | ||||
|         app.kubernetes.io/name: nginx | ||||
|         helm.sh/chart: nginx-13.2.27 | ||||
|         app.kubernetes.io/instance: test | ||||
|         app.kubernetes.io/managed-by: Helm | ||||
|       annotations: | ||||
|     spec: | ||||
|        | ||||
|       automountServiceAccountToken: false | ||||
|       shareProcessNamespace: false | ||||
|       serviceAccountName: default | ||||
|       affinity: | ||||
|         podAffinity: | ||||
|            | ||||
|         podAntiAffinity: | ||||
|           preferredDuringSchedulingIgnoredDuringExecution: | ||||
|             - podAffinityTerm: | ||||
|                 labelSelector: | ||||
|                   matchLabels: | ||||
|                     app.kubernetes.io/name: nginx | ||||
|                     app.kubernetes.io/instance: test | ||||
|                 topologyKey: kubernetes.io/hostname | ||||
|               weight: 1 | ||||
|         nodeAffinity: | ||||
|            | ||||
|       hostNetwork: false | ||||
|       hostIPC: false | ||||
|       initContainers: | ||||
|       containers: | ||||
|         - name: nginx | ||||
|           image: docker.io/bitnami/nginx:test3 | ||||
|           imagePullPolicy: "IfNotPresent" | ||||
|           env: | ||||
|             - name: BITNAMI_DEBUG | ||||
|               value: "false" | ||||
|             - name: NGINX_HTTP_PORT_NUMBER | ||||
|               value: "8080" | ||||
|           envFrom: | ||||
|           ports: | ||||
|             - name: http | ||||
|               containerPort: 8080 | ||||
|           livenessProbe: | ||||
|             failureThreshold: 6 | ||||
|             initialDelaySeconds: 30 | ||||
|             periodSeconds: 10 | ||||
|             successThreshold: 1 | ||||
|             timeoutSeconds: 5 | ||||
|             tcpSocket: | ||||
|               port: http | ||||
|           readinessProbe: | ||||
|             failureThreshold: 3 | ||||
|             initialDelaySeconds: 5 | ||||
|             periodSeconds: 5 | ||||
|             successThreshold: 1 | ||||
|             timeoutSeconds: 3 | ||||
|             tcpSocket: | ||||
|               port: http | ||||
|           resources: | ||||
|             limits: {} | ||||
|             requests: {} | ||||
|           volumeMounts: | ||||
|       volumes: | ||||
| 
 | ||||
|  | @ -0,0 +1 @@ | |||
| https://github.com/helmfile/helmfile/issues/700 | ||||
		Loading…
	
		Reference in New Issue