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