feat: experimental integration with helm-x (#673)
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
This commit is contained in:
parent
78b03e0d92
commit
1da3488599
20
README.md
20
README.md
|
|
@ -1,19 +1,19 @@
|
|||
# helmfile [](https://circleci.com/gh/roboll/helmfile)
|
||||
# Helmfile [](https://circleci.com/gh/roboll/helmfile)
|
||||
|
||||
Deploy Kubernetes Helm Charts
|
||||
|
||||
[](https://quay.io/repository/roboll/helmfile)
|
||||
[](https://slack.sweetops.com)
|
||||
|
||||
## status
|
||||
## Status
|
||||
|
||||
Even though Helmfile is used in production environments [across multiple organizations](USERS.md), it is still in its early stage of development, hence versioned 0.x.
|
||||
|
||||
Helmfile complies to Semantic Versioning 2.0.0 in which v0.x means that there could be backward-incompatible changes for every release.
|
||||
|
||||
Note that we will try our best to document any backward incompatibility.
|
||||
Note that we will try our best to document any backward incompatibility. And in reality, helmfile had no breaking change for a year or so.
|
||||
|
||||
## about
|
||||
## About
|
||||
|
||||
Helmfile is a declarative spec for deploying helm charts. It lets you...
|
||||
|
||||
|
|
@ -23,7 +23,17 @@ Helmfile is a declarative spec for deploying helm charts. It lets you...
|
|||
|
||||
To avoid upgrades for each iteration of `helm`, the `helmfile` executable delegates to `helm` - as a result, `helm` must be installed.
|
||||
|
||||
## configuration syntax
|
||||
## Highlights
|
||||
|
||||
**Declarative**: Write, version-control, apply the desired state file for visibility and reproducibility.
|
||||
|
||||
**Modules**: Modularize common patterns of your infrastructure, distribute it via Git, S3, etc. to be reused across the entire company (See [#648](https://github.com/roboll/helmfile/pull/648))
|
||||
|
||||
**Versatility**: Manage your cluster consisting of charts, [kustomizations](https://github.com/kubernetes-sigs/kustomize), and directories of Kubernetes resources, turning everything to Helm releases (See [#673](https://github.com/roboll/helmfile/pull/673))
|
||||
|
||||
**Patch**: JSON/Strategic-Merge Patch Kubernetes resources before `helm-install`ing, without forking upstream charts (See [#673](https://github.com/roboll/helmfile/pull/673))
|
||||
|
||||
## Configuration
|
||||
|
||||
**CAUTION**: This documentation is for the development version of Helmfile. If you are looking for the documentation for any of releases, please switch to the corresponding release tag like [v0.31.0](https://github.com/roboll/helmfile/tree/v0.31.0).
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue