Skip to content

Commit

Permalink
feat: experimental integration with helm-x
Browse files Browse the repository at this point in the history
This enhances helmfile so that it can:

- Treat K8s manifests directories and Kustomize projects as charts
- Add adhoc chart dependencies on sync/diff/template without forking or modifying chart(s) (#649)
- Add adhoc patches(JSON Patch or Strategic Merge Patch supported) to be applied to the K8s resources before sync/diff/template, without forking or modifyin chart(s) (#650)

The usage is as outlined in https://github.com/mumoshu/helm-x/tree/master/examples/helmfile.

Add any or all of `dependencies:`, `jsonPatches:` and `strategicMergePatches:` so that it adds additional flags to `helm` calls that is only supported by `helm x`.

```yaml
releases:
- name: kustomize
  chart: ../kustomize
- name: manifests
  chart: ../manifests
- name: foo
  chart: incubator/raw
  dependencies:
  - alias: bar
    chart: incubator/raw
  values:
  - values.yaml
  - bar:
      enabled: true
      resources:
      - apiVersion: v1
        kind: Pod
        metadata:
          name: bar
        spec:
          containers:
          - command:
            - sleep
            - 1000
            image: alpine:3.9.4
            imagePullPolicy: IfNotPresent
            name: bar
  jsonPatches:
  - target:
      version: v1
      kind: Pod
      name: foo
    patch:
    - op: replace
      path: /spec/containers/0/command
      value:
      - sleep
      - "123"
  strategicMergePatches:
  - apiVersion: v1
    kind: Pod
    metadata:
      name: bar
    spec:
      containers:
      - name: bar
        command:
        - sleep
        - "234"
```

You can alternatively provide `source: path/to/patch.yaml` for `jsonPatches` and `strategicMergePatches` items to externalize it. Add `.gotmpl` suffix like you would do for values files for templating.

When running `helmfile` you must point `--helm-binary` to the `helm-x` binary like below:

```
$ helmfile --helm-binary ~/.helm/plugins/helm-x/bin/helm-x --log-level debug apply
```

after installing the [helm-x](https://github.com/mumoshu/helm-x) plugin.

The integration should ideally be automatic. That is, it shouldn't force you to set `--helm-binary`. But I had no other way to not bloat helmfile's codebase to just add this experimental feature.

Resolves #649
Resolves #650
  • Loading branch information
mumoshu committed Jun 11, 2019
1 parent 65d404b commit 29b5a3a
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 1 deletion.
51 changes: 51 additions & 0 deletions pkg/state/helmx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package state

type Dependency struct {
Chart string `yaml:"chart"`
Version string `yaml:"version"`
Alias string `yaml:"alias"`
}

func (st *HelmState) appendHelmXFlags(flags []string, release *ReleaseSpec) ([]string, error) {
for _, d := range release.Dependencies {
var dep string
if d.Alias != "" {
dep += d.Alias + "="
}
dep += d.Chart
if d.Version != "" {
dep += ":" + d.Version
}
flags = append(flags, "--dependency", dep)
}

jsonPatches := release.JSONPatches
if len(jsonPatches) > 0 {
generatedFiles, err := st.generateTemporaryValuesFiles(jsonPatches, release.MissingFileHandler)
if err != nil {
return nil, err
}

for _, f := range generatedFiles {
flags = append(flags, "--json-patch", f)
}

release.generatedValues = append(release.generatedValues, generatedFiles...)
}

strategicMergePatches := release.StrategicMergePatches
if len(strategicMergePatches) > 0 {
generatedFiles, err := st.generateTemporaryValuesFiles(strategicMergePatches, release.MissingFileHandler)
if err != nil {
return nil, err
}

for _, f := range generatedFiles {
flags = append(flags, "--strategic-merge-patch", f)
}

release.generatedValues = append(release.generatedValues, generatedFiles...)
}

return flags, nil
}
36 changes: 35 additions & 1 deletion pkg/state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ type ReleaseSpec struct {
TLSKey string `yaml:"tlsKey"`
TLSCert string `yaml:"tlsCert"`

// These settings requires helm-x integration to work
Dependencies []Dependency `yaml:"dependencies"`
JSONPatches []interface{} `yaml:"jsonPatches"`
StrategicMergePatches []interface{} `yaml:"strategicMergePatches"`

// generatedValues are values that need cleaned up on exit
generatedValues []string
//version of the chart that has really been installed cause desired version may be fuzzy (~2.0.0)
Expand Down Expand Up @@ -1198,6 +1203,12 @@ func (st *HelmState) flagsForUpgrade(helm helmexec.Interface, release *ReleaseSp

flags = st.appendTillerFlags(flags, release)

var err error
flags, err = st.appendHelmXFlags(flags, release)
if err != nil {
return nil, err
}

common, err := st.namespaceAndValuesFlags(helm, release, workerIndex)
if err != nil {
return nil, err
Expand All @@ -1209,6 +1220,13 @@ func (st *HelmState) flagsForTemplate(helm helmexec.Interface, release *ReleaseS
flags := []string{
"--name", release.Name,
}

var err error
flags, err = st.appendHelmXFlags(flags, release)
if err != nil {
return nil, err
}

common, err := st.namespaceAndValuesFlags(helm, release, workerIndex)
if err != nil {
return nil, err
Expand All @@ -1228,6 +1246,12 @@ func (st *HelmState) flagsForDiff(helm helmexec.Interface, release *ReleaseSpec,

flags = st.appendTillerFlags(flags, release)

var err error
flags, err = st.appendHelmXFlags(flags, release)
if err != nil {
return nil, err
}

common, err := st.namespaceAndValuesFlags(helm, release, workerIndex)
if err != nil {
return nil, err
Expand All @@ -1245,7 +1269,17 @@ func (st *HelmState) isDevelopment(release *ReleaseSpec) bool {
}

func (st *HelmState) flagsForLint(helm helmexec.Interface, release *ReleaseSpec, workerIndex int) ([]string, error) {
return st.namespaceAndValuesFlags(helm, release, workerIndex)
flags, err := st.namespaceAndValuesFlags(helm, release, workerIndex)
if err != nil {
return nil, err
}

flags, err = st.appendHelmXFlags(flags, release)
if err != nil {
return nil, err
}

return flags, nil
}

func (st *HelmState) RenderValuesFileToBytes(path string) ([]byte, error) {
Expand Down

0 comments on commit 29b5a3a

Please sign in to comment.