Skip to content

Commit 930f91a

Browse files
authored
Merge pull request #1273 from roboll/fix-chartify
fix: Follow-up fixes for #1172
2 parents 16288df + 1cfce32 commit 930f91a

File tree

8 files changed

+201
-19
lines changed

8 files changed

+201
-19
lines changed

docs/advanced-features.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,49 @@ At this point, Helmfile can generate a complete kustomization from the base kust
8989
which can be included in the temporary chart.
9090

9191
After all, Helmfile just installs the temporary chart like standard charts, which allows you to manage everything with Helmfile regardless of each app is declared using a Helm chart or a kustomization.
92+
93+
Please also see [test/advanced/helmfile.yaml](https://github.com/roboll/helmfile/tree/master/test/advanced/helmfile.yaml) for an example of kustomization support and more.
94+
95+
## Adhoc Customization of Helm charts
96+
97+
You can add/update any Kubernetes resource field rendered from a Helm chart by specifying `releases[].strategicMergePatches`:
98+
99+
```
100+
repositories:
101+
- name: incubator
102+
url: https://kubernetes-charts-incubator.storage.googleapis.com
103+
104+
releases:
105+
- name: raw1
106+
chart: incubator/raw
107+
values:
108+
- resources:
109+
- apiVersion: v1
110+
kind: ConfigMap
111+
metadata:
112+
name: raw1
113+
namespace: default
114+
data:
115+
foo: FOO
116+
strategicMergePatches:
117+
- apiVersion: v1
118+
kind: ConfigMap
119+
metadata:
120+
name: raw1
121+
namespace: default
122+
data:
123+
bar: BAR
124+
```
125+
126+
Running `helmfile template` on the above example results in a ConfigMap called `raw` whose `data` is:
127+
128+
```yaml
129+
foo: FOO
130+
bar: BAR
131+
```
132+
133+
Please note that the second `data` field `bar` is coming from the strategic-merge patch defined in the above helmfile.yaml.
134+
135+
There's also `releases[].jsonPatches` that works similarly to `strategicMergePatches` but has additional capability to remove fields.
136+
137+
Please also see [test/advanced/helmfile.yaml](https://github.com/roboll/helmfile/tree/master/test/advanced/helmfile.yaml) for an example of patching support and more.

pkg/state/helmx.go

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package state
22

33
import (
4+
"github.com/roboll/helmfile/pkg/helmexec"
45
"github.com/variantdev/chartify"
6+
"os"
7+
"path/filepath"
58
"strings"
69
)
710

@@ -19,11 +22,22 @@ func (st *HelmState) appendHelmXFlags(flags []string, release *ReleaseSpec) ([]s
1922
return flags, nil
2023
}
2124

22-
func (st *HelmState) PrepareChartify(release *ReleaseSpec) (bool, *chartify.ChartifyOpts) {
25+
func (st *HelmState) PrepareChartify(helm helmexec.Interface, release *ReleaseSpec, workerIndex int) (bool, *chartify.ChartifyOpts, error) {
2326
var opts chartify.ChartifyOpts
2427

2528
var shouldRun bool
2629

30+
opts.EnableKustomizeAlphaPlugins = true
31+
32+
opts.ChartVersion = release.Version
33+
34+
dir := filepath.Join(st.basePath, release.Chart)
35+
if stat, _ := os.Stat(dir); stat != nil && stat.IsDir() {
36+
if exists, err := st.fileExists(filepath.Join(dir, "Chart.yaml")); err == nil && !exists {
37+
shouldRun = true
38+
}
39+
}
40+
2741
for _, d := range release.Dependencies {
2842
var dep string
2943

@@ -52,7 +66,7 @@ func (st *HelmState) PrepareChartify(release *ReleaseSpec) (bool, *chartify.Char
5266
if len(jsonPatches) > 0 {
5367
generatedFiles, err := st.generateTemporaryValuesFiles(jsonPatches, release.MissingFileHandler)
5468
if err != nil {
55-
return false, nil
69+
return false, nil, err
5670
}
5771

5872
for _, f := range generatedFiles {
@@ -68,7 +82,7 @@ func (st *HelmState) PrepareChartify(release *ReleaseSpec) (bool, *chartify.Char
6882
if len(strategicMergePatches) > 0 {
6983
generatedFiles, err := st.generateTemporaryValuesFiles(strategicMergePatches, release.MissingFileHandler)
7084
if err != nil {
71-
return false, nil
85+
return false, nil, err
7286
}
7387

7488
for _, f := range generatedFiles {
@@ -80,5 +94,14 @@ func (st *HelmState) PrepareChartify(release *ReleaseSpec) (bool, *chartify.Char
8094
shouldRun = true
8195
}
8296

83-
return shouldRun, &opts
97+
if shouldRun {
98+
generatedFiles, err := st.generateValuesFiles(helm, release, workerIndex)
99+
if err != nil {
100+
return false, nil, err
101+
}
102+
103+
opts.ValuesFiles = generatedFiles
104+
}
105+
106+
return shouldRun, &opts, nil
84107
}

pkg/state/state.go

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,7 @@ func PrepareCharts(helm helmexec.Interface, st *HelmState, dir string, concurren
718718
type downloadResults struct {
719719
releaseName string
720720
chartPath string
721+
err error
721722
}
722723
errs := []error{}
723724

@@ -739,11 +740,17 @@ func PrepareCharts(helm helmexec.Interface, st *HelmState, dir string, concurren
739740
}
740741
close(jobQueue)
741742
},
742-
func(_ int) {
743+
func(workerIndex int) {
743744
for release := range jobQueue {
744745
var chartPath string
745746

746-
if shouldChartify, opts := st.PrepareChartify(release); shouldChartify {
747+
shouldChartify, opts, err := st.PrepareChartify(helm, release, workerIndex)
748+
if err != nil {
749+
results <- &downloadResults{err: err}
750+
return
751+
}
752+
753+
if shouldChartify {
747754
c := chartify.New(
748755
chartify.HelmBin(st.DefaultHelmBinary),
749756
chartify.UseHelm3(helm3),
@@ -787,12 +794,18 @@ func PrepareCharts(helm helmexec.Interface, st *HelmState, dir string, concurren
787794
}
788795
}
789796

790-
results <- &downloadResults{release.Name, chartPath}
797+
results <- &downloadResults{releaseName: release.Name, chartPath: chartPath}
791798
}
792799
},
793800
func() {
794801
for i := 0; i < len(st.Releases); i++ {
795802
downloadRes := <-results
803+
804+
if downloadRes.err != nil {
805+
errs = append(errs, downloadRes.err)
806+
807+
return
808+
}
796809
temp[downloadRes.releaseName] = downloadRes.chartPath
797810
}
798811
},
@@ -1886,12 +1899,7 @@ func (st *HelmState) generateTemporaryValuesFiles(values []interface{}, missingF
18861899
return generatedFiles, nil
18871900
}
18881901

1889-
func (st *HelmState) namespaceAndValuesFlags(helm helmexec.Interface, release *ReleaseSpec, workerIndex int) ([]string, error) {
1890-
flags := []string{}
1891-
if release.Namespace != "" {
1892-
flags = append(flags, "--namespace", release.Namespace)
1893-
}
1894-
1902+
func (st *HelmState) generateVanillaValuesFiles(release *ReleaseSpec) ([]string, error) {
18951903
values := []interface{}{}
18961904
for _, v := range release.Values {
18971905
switch typedValue := v.(type) {
@@ -1918,12 +1926,14 @@ func (st *HelmState) namespaceAndValuesFlags(helm helmexec.Interface, release *R
19181926
return nil, err
19191927
}
19201928

1921-
for _, f := range generatedFiles {
1922-
flags = append(flags, "--values", f)
1923-
}
1924-
19251929
release.generatedValues = append(release.generatedValues, generatedFiles...)
19261930

1931+
return generatedFiles, nil
1932+
}
1933+
1934+
func (st *HelmState) generateSecretValuesFiles(helm helmexec.Interface, release *ReleaseSpec, workerIndex int) ([]string, error) {
1935+
var generatedFiles []string
1936+
19271937
for _, value := range release.Secrets {
19281938
paths, skip, err := st.storage().resolveFile(release.MissingFileHandler, "secrets", release.ValuesPathPrefix+value)
19291939
if err != nil {
@@ -1944,9 +1954,45 @@ func (st *HelmState) namespaceAndValuesFlags(helm helmexec.Interface, release *R
19441954
return nil, err
19451955
}
19461956

1947-
release.generatedValues = append(release.generatedValues, valfile)
1948-
flags = append(flags, "--values", valfile)
1957+
generatedFiles = append(generatedFiles, valfile)
1958+
}
1959+
1960+
release.generatedValues = append(release.generatedValues, generatedFiles...)
1961+
1962+
return generatedFiles, nil
1963+
}
1964+
1965+
func (st *HelmState) generateValuesFiles(helm helmexec.Interface, release *ReleaseSpec, workerIndex int) ([]string, error) {
1966+
valuesFiles, err := st.generateVanillaValuesFiles(release)
1967+
if err != nil {
1968+
return nil, err
1969+
}
1970+
1971+
secretValuesFiles, err := st.generateSecretValuesFiles(helm, release, workerIndex)
1972+
if err != nil {
1973+
return nil, err
1974+
}
1975+
1976+
files := append(valuesFiles, secretValuesFiles...)
1977+
1978+
return files, nil
1979+
}
1980+
1981+
func (st *HelmState) namespaceAndValuesFlags(helm helmexec.Interface, release *ReleaseSpec, workerIndex int) ([]string, error) {
1982+
flags := []string{}
1983+
if release.Namespace != "" {
1984+
flags = append(flags, "--namespace", release.Namespace)
19491985
}
1986+
1987+
generatedFiles, err := st.generateValuesFiles(helm, release, workerIndex)
1988+
if err != nil {
1989+
return nil, err
1990+
}
1991+
1992+
for _, f := range generatedFiles {
1993+
flags = append(flags, "--values", f)
1994+
}
1995+
19501996
if len(release.SetValues) > 0 {
19511997
for _, set := range release.SetValues {
19521998
if set.Value != "" {

test/advanced/helmfile.yaml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
repositories:
2+
- name: incubator
3+
url: https://kubernetes-charts-incubator.storage.googleapis.com
4+
5+
releases:
6+
- name: kustomapp
7+
chart: ./kustomapp
8+
values:
9+
- namePrefix: kustomapp-
10+
- name: raw1
11+
chart: incubator/raw
12+
values:
13+
- resources:
14+
- apiVersion: v1
15+
kind: ConfigMap
16+
metadata:
17+
name: raw1
18+
namespace: default
19+
data:
20+
foo: FOO
21+
strategicMergePatches:
22+
- apiVersion: v1
23+
kind: ConfigMap
24+
metadata:
25+
name: raw1
26+
namespace: default
27+
data:
28+
bar: BAR
29+
- name: raw2
30+
chart: incubator/raw
31+
values:
32+
- resources:
33+
- apiVersion: v1
34+
kind: ConfigMap
35+
metadata:
36+
name: raw2
37+
namespace: default
38+
data:
39+
foo: FOO
40+
jsonPatches:
41+
- target:
42+
version: v1
43+
kind: ConfigMap
44+
name: raw2
45+
namespace: default
46+
patch:
47+
- op: replace
48+
path: /data/baz
49+
value: "BAZ"

test/advanced/kustomapp/all.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: kustomapp
5+
namespace: default
6+
data:
7+
kustomappfoo: FOO
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
resources:
2+
- all.yaml

test/advanced/kustomapp2/all.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: kustomapp2
5+
namespace: default
6+
data:
7+
kustomappfoo: FOO
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
resources:
2+
- all.yaml

0 commit comments

Comments
 (0)