feat: Merge multiple docs inside a single helmfile.yaml (#270)

Resolves #254
This commit is contained in:
KUOKA Yusuke 2018-09-19 15:42:01 +09:00 committed by GitHub
parent 1ade353c1a
commit 9808849986
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 95 additions and 5 deletions

72
docs/writing-helmfile.md Normal file
View File

@ -0,0 +1,72 @@
# The Helmfile Best Practices Guide
This guide covers the Helmfiles considered patterns for writing advanced helmfiles. It focuses on how helmfile should be structured and executed.
## Layering
You may occasionally end up with many helmfiles that shares common parts like which repositories to use, and whichi release to be bundled by default.
Use Layering to extract te common parts into a dedicated *library helmfile*s, so that each helmfile becomes DRY.
Let's assume that your `helmfile.yaml` looks like:
```
{ readFile "commons.yaml" }}
---
{{ readFile "environments.yaml" }}
---
releases:
- name: myapp
chart: mychart
```
Whereas `commons.yaml` contained a monitoring agent:
```yaml
releases:
- name: metricbaet
chart: stable/metricbeat
```
And `environments.yaml` contained well-known environments:
```yaml
environments:
development:
production:
```
At run time, template expressions in your `helmfile.yaml` are executed:
```yaml
releases:
- name: metricbaet
chart: stable/metricbeat
---
environments:
development:
production:
---
releases:
- name: myapp
chart: mychart
```
Resulting YAML documents are merged in the order of occurrence,
so that your `helmfile.yaml` becomes:
```yaml
environments:
development:
production:
releases:
- name: metricbaet
chart: stable/metricbeat
- name: myapp
chart: mychart
```
Great!
Now, repeat the above steps for each your `helmfile.yaml`, so that all your helmfiles becomes DRY.

View File

@ -1,6 +1,7 @@
package state
import (
"bytes"
"fmt"
"github.com/imdario/mergo"
"github.com/roboll/helmfile/environment"
@ -8,6 +9,7 @@ import (
"github.com/roboll/helmfile/valuesfile"
"go.uber.org/zap"
"gopkg.in/yaml.v2"
"io"
"io/ioutil"
"os"
"path/filepath"
@ -64,16 +66,32 @@ func (c *creator) CreateFromYaml(content []byte, file string, env string) (*Helm
if err != nil {
return nil, &StateLoadError{fmt.Sprintf("failed to read %s", file), err}
}
state.FilePath = file
state.basePath = basePath
unmarshal := yaml.UnmarshalStrict
decoder := yaml.NewDecoder(bytes.NewReader(content))
if !c.Strict {
unmarshal = yaml.Unmarshal
decoder.SetStrict(false)
} else {
decoder.SetStrict(true)
}
if err := unmarshal(content, &state); err != nil {
return nil, &StateLoadError{fmt.Sprintf("failed to read %s", file), err}
i := 0
for {
i++
var intermediate HelmState
err := decoder.Decode(&intermediate)
if err == io.EOF {
break
} else if err != nil {
return nil, &StateLoadError{fmt.Sprintf("failed to read %s: reading document at index %d", file, i), err}
}
if err := mergo.Merge(&state, &intermediate, mergo.WithAppendSlice); err != nil {
return nil, &StateLoadError{fmt.Sprintf("failed to read %s: merging document at index %d", file, i), err}
}
}
state.FilePath = file
if len(state.DeprecatedReleases) > 0 {
if len(state.Releases) > 0 {