parent
							
								
									9d851cda3b
								
							
						
					
					
						commit
						fd0133e10a
					
				
							
								
								
									
										25
									
								
								README.md
								
								
								
								
							
							
						
						
									
										25
									
								
								README.md
								
								
								
								
							|  | @ -212,17 +212,17 @@ helmfiles: | ||||||
| # The default is `environments: {"default": {}}` which implies: | # The default is `environments: {"default": {}}` which implies: | ||||||
| # | # | ||||||
| # - `{{ .Environment.Name }}` evaluates to "default" | # - `{{ .Environment.Name }}` evaluates to "default" | ||||||
| # - `{{ .Environment.Values }}` being empty | # - `{{ .Values }}` being empty | ||||||
| environments: | environments: | ||||||
|   # The "default" environment is available and used when `helmfile` is run without `--environment NAME`. |   # The "default" environment is available and used when `helmfile` is run without `--environment NAME`. | ||||||
|   default: |   default: | ||||||
|     # Everything from the values.yaml is available via `{{ .Environment.Values.KEY }}`. |     # Everything from the values.yaml is available via `{{ .Values.KEY }}`. | ||||||
|     # Suppose `{"foo": {"bar": 1}}` contained in the values.yaml below, |     # Suppose `{"foo": {"bar": 1}}` contained in the values.yaml below, | ||||||
|     # `{{ .Environment.Values.foo.bar }}` is evaluated to `1`. |     # `{{ .Values.foo.bar }}` is evaluated to `1`. | ||||||
|     values: |     values: | ||||||
|     - environments/default/values.yaml |     - environments/default/values.yaml | ||||||
|     # Each entry in values can be either a file path or inline values. |     # Each entry in values can be either a file path or inline values. | ||||||
|     # The below is an example of inline values, which is merged to the `.Environment.Values` |     # The below is an example of inline values, which is merged to the `.Values` | ||||||
|     - myChartVer: 1.0.0-dev |     - myChartVer: 1.0.0-dev | ||||||
|   # Any environment other than `default` is used only when `helmfile` is run with `--environment NAME`. |   # Any environment other than `default` is used only when `helmfile` is run with `--environment NAME`. | ||||||
|   # That is, the "production" env below is used when and only when it is run like `helmfile --environment production sync`. |   # That is, the "production" env below is used when and only when it is run like `helmfile --environment production sync`. | ||||||
|  | @ -625,7 +625,7 @@ releaseName: prod | ||||||
| `values.yaml.gotmpl` | `values.yaml.gotmpl` | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| domain: {{ .Environment.Values | getOrNil "my.domain" | default "dev.example.com" }} | domain: {{ .Values | getOrNil "my.domain" | default "dev.example.com" }} | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| `helmfile sync` installs `myapp` with the value `domain=dev.example.com`, | `helmfile sync` installs `myapp` with the value `domain=dev.example.com`, | ||||||
|  | @ -652,17 +652,26 @@ environments: | ||||||
|     - other.yaml.gotmpl  #  template directives with potential side-effects like `exec` and `readFile` will be honoured |     - other.yaml.gotmpl  #  template directives with potential side-effects like `exec` and `readFile` will be honoured | ||||||
| 
 | 
 | ||||||
| releases: | releases: | ||||||
| - name: myapp-{{ .Environment.Values.releaseName }} # release name will be one of `dev` or `prod` depending on selected environment | - name: myapp-{{ .Values.releaseName }} # release name will be one of `dev` or `prod` depending on selected environment | ||||||
|   values: |   values: | ||||||
|   - values.yaml.gotmpl |   - values.yaml.gotmpl | ||||||
| 
 | 
 | ||||||
| {{ if eq (.Environment.Values.releaseName "prod" ) }} | {{ if eq (.Values.releaseName "prod" ) }} | ||||||
| # this release would be installed only if selected environment is `production` | # this release would be installed only if selected environment is `production` | ||||||
| - name: production-specific-release | - name: production-specific-release | ||||||
|   ... |   ... | ||||||
| {{ end }} | {{ end }} | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | ### Note | ||||||
|  | 
 | ||||||
|  | The `{{ .Values.foo }}` syntax is the recommended way of using environment values. | ||||||
|  | 
 | ||||||
|  | Prior to this [pull request](https://github.com/roboll/helmfile/pull/647), environment values were made available through the `{{ .Environment.Values.foo }}` syntax. | ||||||
|  | This is still working but is **deprecated** and the new `{{ .Values.foo }}` syntax should be used instead. | ||||||
|  | 
 | ||||||
|  | You can read more infos about the feature proposal [here](https://github.com/roboll/helmfile/issues/640). | ||||||
|  | 
 | ||||||
| ## Environment Secrets | ## Environment Secrets | ||||||
| 
 | 
 | ||||||
| Environment Secrets (not to be confused with Kubernetes Secrets) are encrypted versions of `Environment Values`. | Environment Secrets (not to be confused with Kubernetes Secrets) are encrypted versions of `Environment Values`. | ||||||
|  | @ -697,7 +706,7 @@ releases: | ||||||
| Then the environment secret `foo.bar` can be referenced by the below template expression in your `values.yaml.gotmpl`: | Then the environment secret `foo.bar` can be referenced by the below template expression in your `values.yaml.gotmpl`: | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| {{ .Environment.Values.foo.bar }} | {{ .Values.foo.bar }} | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| ## Tillerless | ## Tillerless | ||||||
|  |  | ||||||
|  | @ -11,13 +11,13 @@ One example of how helmfile achieves it is that, `helmfile` fails when you tried | ||||||
| That is, the following example let `helmfile` fail when you have no `eventApi.replicas` defined in environment values. | That is, the following example let `helmfile` fail when you have no `eventApi.replicas` defined in environment values. | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| {{ .Environment.Values.eventApi.replicas | default 1 }} | {{ .Values.eventApi.replicas | default 1 }} | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| In case it isn't a mistake and you do want to allow missing keys, use the `getOrNil` template function: | In case it isn't a mistake and you do want to allow missing keys, use the `getOrNil` template function: | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| {{ .Environment.Values | getOrNil "eventApi.replicas" }} | {{ .Values | getOrNil "eventApi.replicas" }} | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| This result in printing `<no value` in your template, that may or may not result in a failure. | This result in printing `<no value` in your template, that may or may not result in a failure. | ||||||
|  | @ -25,7 +25,7 @@ This result in printing `<no value` in your template, that may or may not result | ||||||
| If you want a kind of default values that is used when a missing key was referenced, use `default` like: | If you want a kind of default values that is used when a missing key was referenced, use `default` like: | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| {{ .Environment.Values | getOrNil "eventApi.replicas" | default 1 }} | {{ .Values | getOrNil "eventApi.replicas" | default 1 }} | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Now, you get `1` when there is no `eventApi.replicas` defined in environment values. | Now, you get `1` when there is no `eventApi.replicas` defined in environment values. | ||||||
|  | @ -267,7 +267,7 @@ bases: | ||||||
| # Part 3: Dynamic Releases | # Part 3: Dynamic Releases | ||||||
| releases: | releases: | ||||||
|   - name: test1 |   - name: test1 | ||||||
|     chart: mychart-{{ .Environment.Values.myname }} |     chart: mychart-{{ .Values.myname }} | ||||||
|     values: |     values: | ||||||
|       replicaCount: 1 |       replicaCount: 1 | ||||||
|       image: |       image: | ||||||
|  | @ -302,9 +302,9 @@ Where the gotmpl file loaded in the second part looks like: | ||||||
| ```yaml | ```yaml | ||||||
| helmDefaults: | helmDefaults: | ||||||
|   tillerNamespace: kube-system |   tillerNamespace: kube-system | ||||||
|   kubeContext: {{ .Environment.Values.kubeContext }} |   kubeContext: {{ .Values.kubeContext }} | ||||||
|   verify: false |   verify: false | ||||||
|   {{ if .Environment.Values.wait }} |   {{ if .Values.wait }} | ||||||
|   wait: true |   wait: true | ||||||
|   {{ else }} |   {{ else }} | ||||||
|   wait: false |   wait: false | ||||||
|  | @ -314,9 +314,9 @@ helmDefaults: | ||||||
|   force: true |   force: true | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Each go template is rendered in the context where `.Environment.Values` is inherited from the previous part.  | Each go template is rendered in the context where `.Values` is inherited from the previous part.  | ||||||
| 
 | 
 | ||||||
| So in `mydefaults.yaml.gotmpl`, both `.Environment.Values.kubeContext` and `.Environment.Values.wait` are valid as they do exist in the environment values inherited from the previous part(=the first part) of your `helmfile.yaml.gotmpl`, and therefore the template is rendered to: | So in `mydefaults.yaml.gotmpl`, both `.Values.kubeContext` and `.Values.wait` are valid as they do exist in the environment values inherited from the previous part(=the first part) of your `helmfile.yaml.gotmpl`, and therefore the template is rendered to: | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| helmDefaults: | helmDefaults: | ||||||
|  | @ -329,13 +329,13 @@ helmDefaults: | ||||||
|   force: true |   force: true | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Similarly, the third part of the top-level `helmfile.yaml.gotmpl`, `.Environment.Values.myname` is valid as it is included in the environment values inherited from the previous parts: | Similarly, the third part of the top-level `helmfile.yaml.gotmpl`, `.Values.myname` is valid as it is included in the environment values inherited from the previous parts: | ||||||
| 
 | 
 | ||||||
| ```yaml | ```yaml | ||||||
| # Part 3: Dynamic Releases | # Part 3: Dynamic Releases | ||||||
| releases: | releases: | ||||||
|   - name: test1 |   - name: test1 | ||||||
|     chart: mychart-{{ .Environment.Values.myname }} |     chart: mychart-{{ .Values.myname }} | ||||||
|     values: |     values: | ||||||
|       replicaCount: 1 |       replicaCount: 1 | ||||||
|       image: |       image: | ||||||
|  |  | ||||||
|  | @ -3,7 +3,6 @@ package app | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"gotest.tools/assert" |  | ||||||
| 	"io" | 	"io" | ||||||
| 	"log" | 	"log" | ||||||
| 	"os" | 	"os" | ||||||
|  | @ -14,6 +13,8 @@ import ( | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
|  | 	"gotest.tools/assert" | ||||||
|  | 
 | ||||||
| 	"github.com/roboll/helmfile/pkg/helmexec" | 	"github.com/roboll/helmfile/pkg/helmexec" | ||||||
| 	"github.com/roboll/helmfile/pkg/state" | 	"github.com/roboll/helmfile/pkg/state" | ||||||
| 	"github.com/roboll/helmfile/pkg/testhelper" | 	"github.com/roboll/helmfile/pkg/testhelper" | ||||||
|  | @ -1755,6 +1756,24 @@ releases: | ||||||
| 		{stateExternal, `{{ if (keys .Environment.Values | has "bar") }}{{ if (keys .Environment.Values.bar | has "baz") }}{{ .Environment.Values.bar.baz }}{{ end }}{{ end }}`, `BAZ`}, | 		{stateExternal, `{{ if (keys .Environment.Values | has "bar") }}{{ if (keys .Environment.Values.bar | has "baz") }}{{ .Environment.Values.bar.baz }}{{ end }}{{ end }}`, `BAZ`}, | ||||||
| 		// See https://github.com/roboll/helmfile/issues/643
 | 		// See https://github.com/roboll/helmfile/issues/643
 | ||||||
| 		{stateExternal, `{{ range $service := .Environment.Values.services }}{{ $service.name }}{{ if hasKey $service "something" }}{{ $service.something }}{{ end }}{{ end }}`, `xyfalse`}, | 		{stateExternal, `{{ range $service := .Environment.Values.services }}{{ $service.name }}{{ if hasKey $service "something" }}{{ $service.something }}{{ end }}{{ end }}`, `xyfalse`}, | ||||||
|  | 		// Same test with .Values
 | ||||||
|  | 		{stateInline, `{{ getOrNil "foo" .Values }}`, `FOO`}, | ||||||
|  | 		{stateInline, `{{ getOrNil "baz" (getOrNil "bar" .Values) }}`, `BAZ`}, | ||||||
|  | 		{stateInline, `{{ if hasKey .Values "foo" }}{{ .Values.foo }}{{ end }}`, `FOO`}, | ||||||
|  | 		{stateInline, `{{ if hasKey .Values "bar" }}{{ .Values.bar.baz }}{{ end }}`, `BAZ`}, | ||||||
|  | 		{stateInline, `{{ if (keys .Values | has "foo") }}{{ .Values.foo }}{{ end }}`, `FOO`}, | ||||||
|  | 		// See https://github.com/roboll/helmfile/issues/624
 | ||||||
|  | 		// This fails when .Values.bar is not map[string]interface{}. At the time of #624 it was map[interface{}]interface{}, which sprig's dict funcs don't support.
 | ||||||
|  | 		{stateInline, `{{ if (keys .Values | has "bar") }}{{ if (keys .Values.bar | has "baz") }}{{ .Values.bar.baz }}{{ end }}{{ end }}`, `BAZ`}, | ||||||
|  | 		{stateExternal, `{{ getOrNil "foo" .Values }}`, `FOO`}, | ||||||
|  | 		{stateExternal, `{{ getOrNil "baz" (getOrNil "bar" .Values) }}`, `BAZ`}, | ||||||
|  | 		{stateExternal, `{{ if hasKey .Values "foo" }}{{ .Values.foo }}{{ end }}`, `FOO`}, | ||||||
|  | 		{stateExternal, `{{ if hasKey .Values "bar" }}{{ .Values.bar.baz }}{{ end }}`, `BAZ`}, | ||||||
|  | 		{stateExternal, `{{ if (keys .Values | has "foo") }}{{ .Values.foo }}{{ end }}`, `FOO`}, | ||||||
|  | 		// See https://github.com/roboll/helmfile/issues/624
 | ||||||
|  | 		{stateExternal, `{{ if (keys .Values | has "bar") }}{{ if (keys .Values.bar | has "baz") }}{{ .Values.bar.baz }}{{ end }}{{ end }}`, `BAZ`}, | ||||||
|  | 		// See https://github.com/roboll/helmfile/issues/643
 | ||||||
|  | 		{stateExternal, `{{ range $service := .Values.services }}{{ $service.name }}{{ if hasKey $service "something" }}{{ $service.something }}{{ end }}{{ end }}`, `xyfalse`}, | ||||||
| 	} | 	} | ||||||
| 	for i := range testcases { | 	for i := range testcases { | ||||||
| 		tc := testcases[i] | 		tc := testcases[i] | ||||||
|  |  | ||||||
|  | @ -1,13 +1,14 @@ | ||||||
| package app | package app | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"github.com/roboll/helmfile/pkg/helmexec" |  | ||||||
| 	"github.com/roboll/helmfile/pkg/state" |  | ||||||
| 	"github.com/roboll/helmfile/pkg/testhelper" |  | ||||||
| 	"os" | 	"os" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/roboll/helmfile/pkg/helmexec" | ||||||
|  | 	"github.com/roboll/helmfile/pkg/state" | ||||||
|  | 	"github.com/roboll/helmfile/pkg/testhelper" | ||||||
|  | 
 | ||||||
| 	"gopkg.in/yaml.v2" | 	"gopkg.in/yaml.v2" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue