mirror of
https://github.com/helmfile/helmfile.git
synced 2026-10-22 16:37:08 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2579a876a6 | ||
|
|
6b3277ce71 | ||
|
|
27425bc4d2 | ||
|
|
05add478c1 | ||
|
|
757e748e3f | ||
|
|
e6f1db128c | ||
|
|
5fb037c8e3 | ||
|
|
5abbdea059 | ||
|
|
9fab6851f0 | ||
|
|
c8ba676e19 | ||
|
|
fc75f25293 | ||
|
|
b044820607 | ||
|
|
0e1aeb43ce | ||
|
|
88adc56551 | ||
|
|
9cf6b59cd8 |
@@ -4,7 +4,7 @@ jobs:
|
||||
|
||||
build:
|
||||
docker:
|
||||
- image: circleci/golang:1.13.4
|
||||
- image: circleci/golang:1.13.7
|
||||
environment:
|
||||
GOPATH: /go
|
||||
working_directory: /home/circleci/workspace/helmfile
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
- .
|
||||
image:
|
||||
docker:
|
||||
- image: circleci/golang:1.13.4
|
||||
- image: circleci/golang:1.13.7
|
||||
working_directory: /home/circleci/workspace/helmfile
|
||||
steps:
|
||||
- checkout
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
|
||||
image_helm3:
|
||||
docker:
|
||||
- image: circleci/golang:1.13.4
|
||||
- image: circleci/golang:1.13.7
|
||||
working_directory: /home/circleci/workspace/helmfile
|
||||
steps:
|
||||
- checkout
|
||||
@@ -62,7 +62,7 @@ jobs:
|
||||
environment:
|
||||
GOPATH: /go
|
||||
docker:
|
||||
- image: circleci/golang:1.13.4
|
||||
- image: circleci/golang:1.13.7
|
||||
working_directory: /home/circleci/workspace/helmfile
|
||||
steps:
|
||||
- checkout
|
||||
@@ -91,7 +91,7 @@ jobs:
|
||||
- run:
|
||||
name: Install helm
|
||||
environment:
|
||||
HELM_VERSION: v2.15.2
|
||||
HELM_VERSION: v2.16.1
|
||||
command: |
|
||||
HELM_FILENAME="helm-${HELM_VERSION}-linux-amd64.tar.gz"
|
||||
curl -Lo ${HELM_FILENAME} "https://kubernetes-helm.storage.googleapis.com/${HELM_FILENAME}"
|
||||
@@ -169,7 +169,7 @@ jobs:
|
||||
|
||||
release:
|
||||
docker:
|
||||
- image: circleci/golang:1.13.4
|
||||
- image: circleci/golang:1.13.7
|
||||
working_directory: /home/circleci/workspace/helmfile
|
||||
steps:
|
||||
- checkout
|
||||
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.13.4-alpine3.10 as builder
|
||||
FROM golang:1.13.7-alpine3.11 as builder
|
||||
|
||||
RUN apk add --no-cache make git
|
||||
WORKDIR /workspace/helmfile
|
||||
@@ -7,14 +7,14 @@ RUN make static-linux
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
FROM alpine:3.10
|
||||
FROM alpine:3.11
|
||||
|
||||
RUN apk add --no-cache ca-certificates git bash curl jq
|
||||
|
||||
ARG HELM_VERSION=v2.15.2
|
||||
ARG HELM_VERSION=v2.16.1
|
||||
ARG HELM_LOCATION="https://kubernetes-helm.storage.googleapis.com"
|
||||
ARG HELM_FILENAME="helm-${HELM_VERSION}-linux-amd64.tar.gz"
|
||||
ARG HELM_SHA256="a9d2db920bd4b3d824729bbe1ff3fa57ad27760487581af6e5d3156d1b3c2511"
|
||||
ARG HELM_SHA256="7eebaaa2da4734242bbcdced62cc32ba8c7164a18792c8acdf16c77abffce202"
|
||||
RUN wget ${HELM_LOCATION}/${HELM_FILENAME} && \
|
||||
echo Verifying ${HELM_FILENAME}... && \
|
||||
sha256sum ${HELM_FILENAME} | grep -q "${HELM_SHA256}" && \
|
||||
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.13.4-alpine3.10 as builder
|
||||
FROM golang:1.13.7-alpine3.11 as builder
|
||||
|
||||
RUN apk add --no-cache make git
|
||||
WORKDIR /workspace/helmfile
|
||||
@@ -7,14 +7,14 @@ RUN make static-linux
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
FROM alpine:3.10
|
||||
FROM alpine:3.11
|
||||
|
||||
RUN apk add --no-cache ca-certificates git bash curl jq
|
||||
|
||||
ARG HELM_VERSION=v3.0.1
|
||||
ARG HELM_VERSION=v3.1.0
|
||||
ARG HELM_LOCATION="https://get.helm.sh"
|
||||
ARG HELM_FILENAME="helm-${HELM_VERSION}-linux-amd64.tar.gz"
|
||||
ARG HELM_SHA256="6de3337bb7683fd62f915d156cfc13c1cf73dc183bd39f2fb4644498c7595805"
|
||||
ARG HELM_SHA256="f0fd9fe2b0e09dc9ed190239fce892a468cbb0a2a8fffb9fe846f893c8fd09de"
|
||||
RUN wget ${HELM_LOCATION}/${HELM_FILENAME} && \
|
||||
echo Verifying ${HELM_FILENAME}... && \
|
||||
sha256sum ${HELM_FILENAME} | grep -q "${HELM_SHA256}" && \
|
||||
|
||||
@@ -95,7 +95,6 @@ helmDefaults:
|
||||
# limit the maximum number of revisions saved per release. Use 0 for no limit (default 10)
|
||||
historyMax: 10
|
||||
|
||||
|
||||
# The desired states of Helm releases.
|
||||
#
|
||||
# Helmfile runs various helm commands to converge the current state in the live cluster to the desired state defined here.
|
||||
@@ -267,6 +266,18 @@ bases:
|
||||
- environments.yaml
|
||||
- defaults.yaml
|
||||
- templates.yaml
|
||||
|
||||
#
|
||||
# Advanced Configuration: API Capabilities
|
||||
#
|
||||
# 'helmfile template' renders releases locally without querying an actual cluster,
|
||||
# and in this case `.Capabilities.APIVersions` cannot be populated.
|
||||
# When a chart queries for a specific CRD, this can lead to unexpected results.
|
||||
#
|
||||
# Configure a fixed list of api versions to pass to 'helm template' via the --api-versions flag:
|
||||
apiVersions:
|
||||
- example/v1
|
||||
|
||||
```
|
||||
|
||||
## Templating
|
||||
|
||||
@@ -17,5 +17,6 @@ information to this file.
|
||||
| [transit](https://transit.app/) | production | [Blog post](https://medium.com/@naseem_60378/helmfile-its-like-a-helm-for-your-helm-74a908581599). | Montreal, Canada | March 2019 |
|
||||
| [uniqkey](https://uniqkey.eu/) | production | [Wiki Page](https://ocd-scm.github.io/ocd-meta/) | Copenhagen, Denmark | April 2019 |
|
||||
| [bitsofinfo](https://github.com/bitsofinfo/helmfile-deploy) | production | Used with [helmfile-deploy](https://github.com/bitsofinfo/helmfile-deploy) to manage releases for dozens of apps | USA | July 2019 |
|
||||
| [kloeckner-i](https://www.kloeckner-i.com/) | production | We are deploying our standard tools via helmfile to all our clusters. | Berlin, Germany | September 2019 |
|
||||
| [kloeckner-i](https://www.kloeckner-i.com/) | production | We are deploying our standard tools via helmfile to all our clusters. | Berlin, Germany | September 2019 |
|
||||
| [American Express](https://www.americanexpress.com) | proof-of-concept | Orchestration of both internal cluster workloads and local developer environments. | London, GB | January 2020 |
|
||||
<!-- TABLE_END -->
|
||||
|
||||
@@ -32,7 +32,7 @@ Now, you get `1` when there is no `eventApi.replicas` defined in environment val
|
||||
|
||||
## Release Template / Conventional Directory Structure
|
||||
|
||||
Introducing helmfile into a large-scale project that involes dozens of releases often results in a lot of repetitions in `helmfile.yaml` files.
|
||||
Introducing helmfile into a large-scale project that involves dozens of releases often results in a lot of repetitions in `helmfile.yaml` files.
|
||||
|
||||
The example below shows repetitions in `namespace`, `chart`, `values`, and `secrets`:
|
||||
|
||||
@@ -228,7 +228,7 @@ A work-around is to treat the state file as a go template and use `readFile` tem
|
||||
```yaml
|
||||
templates:
|
||||
metricbeat: &metricbeat
|
||||
- name: metricbeat
|
||||
name: metricbeat
|
||||
chart: stable/metricbeat
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "=> Building container"
|
||||
docker build \
|
||||
--tag "$IMAGE_NAME" \
|
||||
--file Dockerfile .
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
go()
|
||||
{
|
||||
docker run --rm -v "$(pwd):/workspace" -w /workspace golang:latest go $@;
|
||||
}
|
||||
|
||||
go get -u github.com/tcnksm/ghr github.com/mitchellh/gox
|
||||
go mod vendor
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "=> Fetch unshallow origin"
|
||||
git fetch --unshallow origin || true
|
||||
|
||||
echo "=> Tag image:"
|
||||
docker tag "${IMAGE_NAME}" "${DOCKER_REPO}:$(git describe --tags --abbrev=0 HEAD^)"
|
||||
docker tag "${IMAGE_NAME}" "${DOCKER_REPO}:$(git describe --tags --abbrev=0 HEAD)"
|
||||
|
||||
echo "=> Push images"
|
||||
docker push "${DOCKER_REPO}"
|
||||
@@ -338,6 +338,10 @@ func main() {
|
||||
Name: "suppress-secrets",
|
||||
Usage: "suppress secrets in the diff output. highly recommended to specify on CI/CD use-cases",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "suppress-diff",
|
||||
Usage: "suppress diff in the output. Usable in new installs",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "skip-deps",
|
||||
Usage: "skip running `helm repo update` and `helm dependency build`",
|
||||
@@ -538,6 +542,10 @@ func (c configImpl) SuppressSecrets() bool {
|
||||
return c.c.Bool("suppress-secrets")
|
||||
}
|
||||
|
||||
func (c configImpl) SuppressDiff() bool {
|
||||
return c.c.Bool("suppress-diff")
|
||||
}
|
||||
|
||||
// DeleteConfig
|
||||
|
||||
func (c configImpl) Purge() bool {
|
||||
|
||||
+6
-1
@@ -168,6 +168,11 @@ func (a *App) Destroy(c DestroyConfigProvider) error {
|
||||
}
|
||||
|
||||
func (a *App) Test(c TestConfigProvider) error {
|
||||
if c.Cleanup() && a.helmExecer.IsHelm3() {
|
||||
a.Logger.Warnf("warn: requested cleanup will not be applied. " +
|
||||
"To clean up test resources with Helm 3, you have to remove them manually " +
|
||||
"or set helm.sh/hook-delete-policy\n")
|
||||
}
|
||||
return a.ForEachStateFiltered(func(run *Run) []error {
|
||||
return run.Test(c)
|
||||
})
|
||||
@@ -696,7 +701,7 @@ func (a *App) apply(r *Run, c ApplyConfigProvider) (bool, []error) {
|
||||
|
||||
// TODO Better way to detect diff on only filtered releases
|
||||
{
|
||||
changedReleases, planningErrs = st.DiffReleases(helm, c.Values(), c.Concurrency(), detailedExitCode, c.SuppressSecrets(), false, diffOpts)
|
||||
changedReleases, planningErrs = st.DiffReleases(helm, c.Values(), c.Concurrency(), detailedExitCode, c.SuppressSecrets(), c.SuppressDiff(), false, diffOpts)
|
||||
|
||||
var err error
|
||||
deletingReleases, err = st.DetectReleasesToBeDeletedForSync(helm, st.Releases)
|
||||
|
||||
+94
-31
@@ -1895,6 +1895,7 @@ type applyConfig struct {
|
||||
set []string
|
||||
skipDeps bool
|
||||
suppressSecrets bool
|
||||
suppressDiff bool
|
||||
noColor bool
|
||||
context int
|
||||
concurrency int
|
||||
@@ -1922,6 +1923,10 @@ func (a applyConfig) SuppressSecrets() bool {
|
||||
return a.suppressSecrets
|
||||
}
|
||||
|
||||
func (a applyConfig) SuppressDiff() bool {
|
||||
return a.suppressDiff
|
||||
}
|
||||
|
||||
func (a applyConfig) NoColor() bool {
|
||||
return a.noColor
|
||||
}
|
||||
@@ -2004,7 +2009,7 @@ func (helm *mockHelmExec) UpdateRepo() error {
|
||||
func (helm *mockHelmExec) SyncRelease(context helmexec.HelmContext, name, chart string, flags ...string) error {
|
||||
return nil
|
||||
}
|
||||
func (helm *mockHelmExec) DiffRelease(context helmexec.HelmContext, name, chart string, flags ...string) error {
|
||||
func (helm *mockHelmExec) DiffRelease(context helmexec.HelmContext, name, chart string, suppressDiff bool, flags ...string) error {
|
||||
return nil
|
||||
}
|
||||
func (helm *mockHelmExec) ReleaseStatus(context helmexec.HelmContext, release string, flags ...string) error {
|
||||
@@ -2092,6 +2097,64 @@ releases:
|
||||
}
|
||||
}
|
||||
|
||||
func TestTemplate_ApiVersions(t *testing.T) {
|
||||
files := map[string]string{
|
||||
"/path/to/helmfile.yaml": `
|
||||
apiVersions:
|
||||
- helmfile.test/v1
|
||||
- helmfile.test/v2
|
||||
releases:
|
||||
- name: myrelease1
|
||||
chart: mychart1
|
||||
`,
|
||||
}
|
||||
|
||||
var helm = &mockHelmExec{}
|
||||
var wantReleases = []mockTemplates{
|
||||
{name: "myrelease1", chart: "mychart1", flags: []string{"--api-versions", "helmfile.test/v1", "--api-versions", "helmfile.test/v2", "--namespace", "testNamespace", "--output-dir", "output/subdir/helmfile-[a-z0-9]{8}-myrelease1"}},
|
||||
}
|
||||
|
||||
var buffer bytes.Buffer
|
||||
logger := helmexec.NewLogger(&buffer, "debug")
|
||||
|
||||
valsRuntime, err := vals.New(vals.Options{CacheSize: 32})
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error creating vals runtime: %v", err)
|
||||
}
|
||||
|
||||
app := appWithFs(&App{
|
||||
glob: filepath.Glob,
|
||||
abs: filepath.Abs,
|
||||
KubeContext: "default",
|
||||
Env: "default",
|
||||
Logger: logger,
|
||||
helmExecer: helm,
|
||||
Namespace: "testNamespace",
|
||||
valsRuntime: valsRuntime,
|
||||
}, files)
|
||||
app.Template(configImpl{})
|
||||
|
||||
for i := range wantReleases {
|
||||
if wantReleases[i].name != helm.templated[i].name {
|
||||
t.Errorf("name = [%v], want %v", helm.templated[i].name, wantReleases[i].name)
|
||||
}
|
||||
if !strings.Contains(helm.templated[i].chart, wantReleases[i].chart) {
|
||||
t.Errorf("chart = [%v], want %v", helm.templated[i].chart, wantReleases[i].chart)
|
||||
}
|
||||
for j := range wantReleases[i].flags {
|
||||
if j == 7 {
|
||||
matched, _ := regexp.Match(wantReleases[i].flags[j], []byte(helm.templated[i].flags[j]))
|
||||
if !matched {
|
||||
t.Errorf("HelmState.TemplateReleases() = [%v], want %v", helm.templated[i].flags[j], wantReleases[i].flags[j])
|
||||
}
|
||||
} else if wantReleases[i].flags[j] != helm.templated[i].flags[j] {
|
||||
t.Errorf("HelmState.TemplateReleases() = [%v], want %v", helm.templated[i].flags[j], wantReleases[i].flags[j])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestApply(t *testing.T) {
|
||||
testcases := []struct {
|
||||
name string
|
||||
@@ -2185,10 +2248,10 @@ releases:
|
||||
},
|
||||
lists: map[exectest.ListKey]string{
|
||||
// delete frontend-v1 and backend-v1
|
||||
exectest.ListKey{Filter: "^frontend-v1$", Flags: "--kube-contextdefault"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
exectest.ListKey{Filter: "^frontend-v1$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
frontend-v1 4 Fri Nov 1 08:40:07 2019 DEPLOYED backend-3.1.0 3.1.0 default
|
||||
`,
|
||||
exectest.ListKey{Filter: "^backend-v1$", Flags: "--kube-contextdefault"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
exectest.ListKey{Filter: "^backend-v1$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
backend-v1 4 Fri Nov 1 08:40:07 2019 DEPLOYED backend-3.1.0 3.1.0 default
|
||||
`,
|
||||
},
|
||||
@@ -2373,33 +2436,33 @@ processing releases in group 1/5: logging, front-proxy
|
||||
worker 1/1 started
|
||||
worker 1/1 finished
|
||||
worker 1/1 started
|
||||
getting deployed release version failed:unexpected list key: {^logging$ --kube-contextdefault}
|
||||
getting deployed release version failed:unexpected list key: {^front-proxy$ --kube-contextdefault}
|
||||
getting deployed release version failed:unexpected list key: {^logging$ --kube-contextdefault--deployed--failed--pending}
|
||||
getting deployed release version failed:unexpected list key: {^front-proxy$ --kube-contextdefault--deployed--failed--pending}
|
||||
worker 1/1 finished
|
||||
processing releases in group 2/5: database, servicemesh
|
||||
worker 1/1 started
|
||||
worker 1/1 finished
|
||||
worker 1/1 started
|
||||
getting deployed release version failed:unexpected list key: {^database$ --kube-contextdefault}
|
||||
getting deployed release version failed:unexpected list key: {^servicemesh$ --kube-contextdefault}
|
||||
getting deployed release version failed:unexpected list key: {^database$ --kube-contextdefault--deployed--failed--pending}
|
||||
getting deployed release version failed:unexpected list key: {^servicemesh$ --kube-contextdefault--deployed--failed--pending}
|
||||
worker 1/1 finished
|
||||
processing releases in group 3/5: anotherbackend
|
||||
worker 1/1 started
|
||||
worker 1/1 finished
|
||||
worker 1/1 started
|
||||
getting deployed release version failed:unexpected list key: {^anotherbackend$ --kube-contextdefault}
|
||||
getting deployed release version failed:unexpected list key: {^anotherbackend$ --kube-contextdefault--deployed--failed--pending}
|
||||
worker 1/1 finished
|
||||
processing releases in group 4/5: backend-v1, backend-v2
|
||||
worker 1/1 started
|
||||
worker 1/1 finished
|
||||
worker 1/1 started
|
||||
getting deployed release version failed:unexpected list key: {^backend-v2$ --kube-contextdefault}
|
||||
getting deployed release version failed:unexpected list key: {^backend-v2$ --kube-contextdefault--deployed--failed--pending}
|
||||
worker 1/1 finished
|
||||
processing releases in group 5/5: frontend-v1, frontend-v2, frontend-v3
|
||||
worker 1/1 started
|
||||
worker 1/1 finished
|
||||
worker 1/1 started
|
||||
getting deployed release version failed:unexpected list key: {^frontend-v3$ --kube-contextdefault}
|
||||
getting deployed release version failed:unexpected list key: {^frontend-v3$ --kube-contextdefault--deployed--failed--pending}
|
||||
worker 1/1 finished
|
||||
|
||||
UPDATED RELEASES:
|
||||
@@ -2441,8 +2504,8 @@ releases:
|
||||
exectest.DiffKey{Name: "bar", Chart: "mychart2", Flags: "--kube-contextdefault--detailed-exitcode"}: nil,
|
||||
},
|
||||
lists: map[exectest.ListKey]string{
|
||||
exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault"}: ``,
|
||||
exectest.ListKey{Filter: "^bar$", Flags: "--kube-contextdefault"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault--deployed--failed--pending"}: ``,
|
||||
exectest.ListKey{Filter: "^bar$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
bar 4 Fri Nov 1 08:40:07 2019 DEPLOYED mychart2-3.1.0 3.1.0 default
|
||||
`,
|
||||
},
|
||||
@@ -2534,14 +2597,14 @@ processing releases in group 1/2: baz, bar
|
||||
worker 1/1 started
|
||||
worker 1/1 finished
|
||||
worker 1/1 started
|
||||
getting deployed release version failed:unexpected list key: {^baz$ --kube-contextdefault}
|
||||
getting deployed release version failed:unexpected list key: {^bar$ --kube-contextdefault}
|
||||
getting deployed release version failed:unexpected list key: {^baz$ --kube-contextdefault--deployed--failed--pending}
|
||||
getting deployed release version failed:unexpected list key: {^bar$ --kube-contextdefault--deployed--failed--pending}
|
||||
worker 1/1 finished
|
||||
processing releases in group 2/2: foo
|
||||
worker 1/1 started
|
||||
worker 1/1 finished
|
||||
worker 1/1 started
|
||||
getting deployed release version failed:unexpected list key: {^foo$ --kube-contextdefault}
|
||||
getting deployed release version failed:unexpected list key: {^foo$ --kube-contextdefault--deployed--failed--pending}
|
||||
worker 1/1 finished
|
||||
|
||||
UPDATED RELEASES:
|
||||
@@ -2811,13 +2874,13 @@ processing releases in group 1/2: tns1/ns1/foo
|
||||
worker 1/1 started
|
||||
worker 1/1 finished
|
||||
worker 1/1 started
|
||||
getting deployed release version failed:unexpected list key: {^foo$ --tiller-namespacetns1--kube-contextdefault}
|
||||
getting deployed release version failed:unexpected list key: {^foo$ --tiller-namespacetns1--kube-contextdefault--deployed--failed--pending}
|
||||
worker 1/1 finished
|
||||
processing releases in group 2/2: tns2/ns2/bar
|
||||
worker 1/1 started
|
||||
worker 1/1 finished
|
||||
worker 1/1 started
|
||||
getting deployed release version failed:unexpected list key: {^bar$ --tiller-namespacetns2--kube-contextdefault}
|
||||
getting deployed release version failed:unexpected list key: {^bar$ --tiller-namespacetns2--kube-contextdefault--deployed--failed--pending}
|
||||
worker 1/1 finished
|
||||
|
||||
UPDATED RELEASES:
|
||||
@@ -2851,10 +2914,10 @@ releases:
|
||||
exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||
},
|
||||
lists: map[exectest.ListKey]string{
|
||||
exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
foo 4 Fri Nov 1 08:40:07 2019 DEPLOYED mychart1-3.1.0 3.1.0 default
|
||||
`,
|
||||
exectest.ListKey{Filter: "^bar$", Flags: "--kube-contextdefault"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
exectest.ListKey{Filter: "^bar$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
bar 4 Fri Nov 1 08:40:07 2019 DEPLOYED mychart2-3.1.0 3.1.0 default
|
||||
`,
|
||||
},
|
||||
@@ -2884,10 +2947,10 @@ releases:
|
||||
exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||
},
|
||||
lists: map[exectest.ListKey]string{
|
||||
exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
foo 4 Fri Nov 1 08:40:07 2019 DEPLOYED mychart1-3.1.0 3.1.0 default
|
||||
`,
|
||||
exectest.ListKey{Filter: "^bar$", Flags: "--kube-contextdefault"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
exectest.ListKey{Filter: "^bar$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
bar 4 Fri Nov 1 08:40:07 2019 DEPLOYED mychart2-3.1.0 3.1.0 default
|
||||
`,
|
||||
},
|
||||
@@ -2919,10 +2982,10 @@ releases:
|
||||
exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||
},
|
||||
lists: map[exectest.ListKey]string{
|
||||
exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
foo 4 Fri Nov 1 08:40:07 2019 DEPLOYED mychart1-3.1.0 3.1.0 default
|
||||
`,
|
||||
exectest.ListKey{Filter: "^bar$", Flags: "--kube-contextdefault"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
exectest.ListKey{Filter: "^bar$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
bar 4 Fri Nov 1 08:40:07 2019 DEPLOYED mychart2-3.1.0 3.1.0 default
|
||||
`,
|
||||
},
|
||||
@@ -2953,10 +3016,10 @@ releases:
|
||||
exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||
},
|
||||
lists: map[exectest.ListKey]string{
|
||||
exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
foo 4 Fri Nov 1 08:40:07 2019 DEPLOYED mychart1-3.1.0 3.1.0 default
|
||||
`,
|
||||
exectest.ListKey{Filter: "^bar$", Flags: "--kube-contextdefault"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
exectest.ListKey{Filter: "^bar$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
bar 4 Fri Nov 1 08:40:07 2019 DEPLOYED mychart2-3.1.0 3.1.0 default
|
||||
`,
|
||||
},
|
||||
@@ -2987,10 +3050,10 @@ releases:
|
||||
exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||
},
|
||||
lists: map[exectest.ListKey]string{
|
||||
exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
foo 4 Fri Nov 1 08:40:07 2019 DEPLOYED mychart1-3.1.0 3.1.0 default
|
||||
`,
|
||||
exectest.ListKey{Filter: "^bar$", Flags: "--kube-contextdefault"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
exectest.ListKey{Filter: "^bar$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
bar 4 Fri Nov 1 08:40:07 2019 DEPLOYED mychart2-3.1.0 3.1.0 default
|
||||
`,
|
||||
},
|
||||
@@ -3021,10 +3084,10 @@ releases:
|
||||
exectest.DiffKey{Name: "foo", Chart: "mychart1", Flags: "--kube-contextdefault--detailed-exitcode"}: helmexec.ExitError{Code: 2},
|
||||
},
|
||||
lists: map[exectest.ListKey]string{
|
||||
exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
exectest.ListKey{Filter: "^foo$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
foo 4 Fri Nov 1 08:40:07 2019 DEPLOYED mychart1-3.1.0 3.1.0 default
|
||||
`,
|
||||
exectest.ListKey{Filter: "^bar$", Flags: "--kube-contextdefault"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
exectest.ListKey{Filter: "^bar$", Flags: "--kube-contextdefault--deployed--failed--pending"}: `NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
|
||||
bar 4 Fri Nov 1 08:40:07 2019 DEPLOYED mychart2-3.1.0 3.1.0 default
|
||||
`,
|
||||
},
|
||||
@@ -3163,7 +3226,7 @@ processing releases in group 2/3: default/external-secrets
|
||||
worker 1/1 started
|
||||
worker 1/1 finished
|
||||
worker 1/1 started
|
||||
getting deployed release version failed:unexpected list key: {^external-secrets$ --kube-contextdefault}
|
||||
getting deployed release version failed:unexpected list key: {^external-secrets$ --kube-contextdefault--deployed--failed--pending}
|
||||
worker 1/1 finished
|
||||
processing releases in group 3/3: default/my-release
|
||||
1 release(s) matching app=test found in helmfile.yaml
|
||||
@@ -3171,7 +3234,7 @@ processing releases in group 3/3: default/my-release
|
||||
worker 1/1 started
|
||||
worker 1/1 finished
|
||||
worker 1/1 started
|
||||
getting deployed release version failed:unexpected list key: {^my-release$ --kube-contextdefault}
|
||||
getting deployed release version failed:unexpected list key: {^my-release$ --kube-contextdefault--deployed--failed--pending}
|
||||
worker 1/1 finished
|
||||
|
||||
UPDATED RELEASES:
|
||||
|
||||
@@ -41,6 +41,7 @@ type ApplyConfigProvider interface {
|
||||
SkipDeps() bool
|
||||
|
||||
SuppressSecrets() bool
|
||||
SuppressDiff() bool
|
||||
|
||||
NoColor() bool
|
||||
Context() int
|
||||
@@ -69,6 +70,7 @@ type DiffConfigProvider interface {
|
||||
SkipDeps() bool
|
||||
|
||||
SuppressSecrets() bool
|
||||
SuppressDiff() bool
|
||||
|
||||
DetailedExitcode() bool
|
||||
NoColor() bool
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@ func (r *Run) Diff(c DiffConfigProvider) []error {
|
||||
NoColor: c.NoColor(),
|
||||
Set: c.Set(),
|
||||
}
|
||||
_, errs := st.DiffReleases(helm, c.Values(), c.Concurrency(), c.DetailedExitcode(), c.SuppressSecrets(), true, opts)
|
||||
_, errs := st.DiffReleases(helm, c.Values(), c.Concurrency(), c.DetailedExitcode(), c.SuppressSecrets(), c.SuppressDiff(), true, opts)
|
||||
return errs
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ func (helm *Helm) SyncRelease(context helmexec.HelmContext, name, chart string,
|
||||
|
||||
return nil
|
||||
}
|
||||
func (helm *Helm) DiffRelease(context helmexec.HelmContext, name, chart string, flags ...string) error {
|
||||
func (helm *Helm) DiffRelease(context helmexec.HelmContext, name, chart string, suppressDiff bool, flags ...string) error {
|
||||
if helm.DiffMutex != nil {
|
||||
helm.DiffMutex.Lock()
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ func (helm *execer) TemplateRelease(name string, chart string, flags ...string)
|
||||
return err
|
||||
}
|
||||
|
||||
func (helm *execer) DiffRelease(context HelmContext, name, chart string, flags ...string) error {
|
||||
func (helm *execer) DiffRelease(context HelmContext, name, chart string, suppressDiff bool, flags ...string) error {
|
||||
helm.logger.Infof("Comparing release=%v, chart=%v", name, chart)
|
||||
preArgs := context.GetTillerlessArgs(helm)
|
||||
env := context.getTillerlessEnv()
|
||||
@@ -273,11 +273,13 @@ func (helm *execer) DiffRelease(context HelmContext, name, chart string, flags .
|
||||
switch e := err.(type) {
|
||||
case ExitError:
|
||||
if e.ExitStatus() == 2 {
|
||||
helm.write(out)
|
||||
if !(suppressDiff) {
|
||||
helm.write(out)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if !(suppressDiff) {
|
||||
helm.write(out)
|
||||
}
|
||||
return err
|
||||
|
||||
@@ -246,7 +246,7 @@ func Test_DiffRelease(t *testing.T) {
|
||||
var buffer bytes.Buffer
|
||||
logger := NewLogger(&buffer, "debug")
|
||||
helm := MockExecer(logger, "dev")
|
||||
helm.DiffRelease(HelmContext{}, "release", "chart", "--timeout 10", "--wait")
|
||||
helm.DiffRelease(HelmContext{}, "release", "chart", false, "--timeout 10", "--wait")
|
||||
expected := `Comparing release=release, chart=chart
|
||||
exec: helm diff upgrade --reset-values --allow-unreleased release chart --timeout 10 --wait --kube-context dev
|
||||
exec: helm diff upgrade --reset-values --allow-unreleased release chart --timeout 10 --wait --kube-context dev:
|
||||
@@ -256,7 +256,7 @@ exec: helm diff upgrade --reset-values --allow-unreleased release chart --timeou
|
||||
}
|
||||
|
||||
buffer.Reset()
|
||||
helm.DiffRelease(HelmContext{}, "release", "chart")
|
||||
helm.DiffRelease(HelmContext{}, "release", "chart", false)
|
||||
expected = `Comparing release=release, chart=chart
|
||||
exec: helm diff upgrade --reset-values --allow-unreleased release chart --kube-context dev
|
||||
exec: helm diff upgrade --reset-values --allow-unreleased release chart --kube-context dev:
|
||||
@@ -270,7 +270,7 @@ func Test_DiffReleaseTillerless(t *testing.T) {
|
||||
var buffer bytes.Buffer
|
||||
logger := NewLogger(&buffer, "debug")
|
||||
helm := MockExecer(logger, "dev")
|
||||
helm.DiffRelease(HelmContext{Tillerless: true}, "release", "chart", "--timeout 10", "--wait")
|
||||
helm.DiffRelease(HelmContext{Tillerless: true}, "release", "chart", false, "--timeout 10", "--wait")
|
||||
expected := `Comparing release=release, chart=chart
|
||||
exec: helm tiller run -- helm diff upgrade --reset-values --allow-unreleased release chart --timeout 10 --wait --kube-context dev
|
||||
exec: helm tiller run -- helm diff upgrade --reset-values --allow-unreleased release chart --timeout 10 --wait --kube-context dev:
|
||||
|
||||
@@ -10,7 +10,7 @@ type Interface interface {
|
||||
BuildDeps(name, chart string) error
|
||||
UpdateDeps(chart string) error
|
||||
SyncRelease(context HelmContext, name, chart string, flags ...string) error
|
||||
DiffRelease(context HelmContext, name, chart string, flags ...string) error
|
||||
DiffRelease(context HelmContext, name, chart string, suppressDiff bool, flags ...string) error
|
||||
TemplateRelease(name, chart string, flags ...string) error
|
||||
Fetch(chart string, flags ...string) error
|
||||
Lint(name, chart string, flags ...string) error
|
||||
|
||||
@@ -291,7 +291,7 @@ func (m *chartDependencyManager) Update(shell helmexec.DependencyUpdater, wd str
|
||||
|
||||
func (m *chartDependencyManager) updateHelm3(shell helmexec.DependencyUpdater, wd string, unresolved *UnresolvedDependencies) (*ResolvedDependencies, error) {
|
||||
// Generate `Chart.yaml` of the temporary local chart
|
||||
chartMetaContent := fmt.Sprintf("name: %s\nversion: 1.0.0\n", m.Name)
|
||||
chartMetaContent := fmt.Sprintf("name: %s\nversion: 1.0.0\napiVersion: v2\n", m.Name)
|
||||
|
||||
// Generate `requirements.yaml` of the temporary local chart from the helmfile state
|
||||
reqsContent, err := yaml.Marshal(unresolved.ToChartRequirements())
|
||||
|
||||
+25
-3
@@ -47,6 +47,7 @@ type HelmState struct {
|
||||
Repositories []RepositorySpec `yaml:"repositories,omitempty"`
|
||||
Releases []ReleaseSpec `yaml:"releases,omitempty"`
|
||||
Selectors []string `yaml:"-"`
|
||||
ApiVersions []string `yaml:"apiVersions,omitempty"`
|
||||
|
||||
Templates map[string]TemplateSpec `yaml:"templates"`
|
||||
|
||||
@@ -657,6 +658,7 @@ func (st *HelmState) listReleases(context helmexec.HelmContext, helm helmexec.In
|
||||
if helm.IsHelm3() && release.Namespace != "" {
|
||||
flags = append(flags, "--namespace", release.Namespace)
|
||||
}
|
||||
flags = append(flags, "--deployed", "--failed", "--pending")
|
||||
return helm.List(context, "^"+release.Name+"$", flags...)
|
||||
}
|
||||
|
||||
@@ -1092,7 +1094,7 @@ type DiffOpt interface{ Apply(*DiffOpts) }
|
||||
|
||||
// DiffReleases wrapper for executing helm diff on the releases
|
||||
// It returns releases that had any changes
|
||||
func (st *HelmState) DiffReleases(helm helmexec.Interface, additionalValues []string, workerLimit int, detailedExitCode, suppressSecrets bool, triggerCleanupEvents bool, opt ...DiffOpt) ([]ReleaseSpec, []error) {
|
||||
func (st *HelmState) DiffReleases(helm helmexec.Interface, additionalValues []string, workerLimit int, detailedExitCode, suppressSecrets bool, suppressDiff bool, triggerCleanupEvents bool, opt ...DiffOpt) ([]ReleaseSpec, []error) {
|
||||
opts := &DiffOpts{}
|
||||
for _, o := range opt {
|
||||
o.Apply(opts)
|
||||
@@ -1122,7 +1124,7 @@ func (st *HelmState) DiffReleases(helm helmexec.Interface, additionalValues []st
|
||||
for prep := range jobQueue {
|
||||
flags := prep.flags
|
||||
release := prep.release
|
||||
if err := helm.DiffRelease(st.createHelmContext(release, workerIndex), release.Name, normalizeChart(st.basePath, release.Chart), flags...); err != nil {
|
||||
if err := helm.DiffRelease(st.createHelmContext(release, workerIndex), release.Name, normalizeChart(st.basePath, release.Chart), suppressDiff, flags...); err != nil {
|
||||
switch e := err.(type) {
|
||||
case helmexec.ExitError:
|
||||
// Propagate any non-zero exit status from the external command like `helm` that is failed under the hood
|
||||
@@ -1165,6 +1167,9 @@ func (st *HelmState) ReleaseStatuses(helm helmexec.Interface, workerLimit int) [
|
||||
}
|
||||
|
||||
flags := []string{}
|
||||
if helm.IsHelm3() && release.Namespace != "" {
|
||||
flags = append(flags, "--namespace", release.Namespace)
|
||||
}
|
||||
flags = st.appendConnectionFlags(flags, &release)
|
||||
|
||||
return helm.ReleaseStatus(st.createHelmContext(&release, workerIndex), release.Name, flags...)
|
||||
@@ -1204,7 +1209,10 @@ func (st *HelmState) TestReleases(helm helmexec.Interface, cleanup bool, timeout
|
||||
}
|
||||
|
||||
flags := []string{}
|
||||
if cleanup {
|
||||
if helm.IsHelm3() && release.Namespace != "" {
|
||||
flags = append(flags, "--namespace", release.Namespace)
|
||||
}
|
||||
if cleanup && !helm.IsHelm3() {
|
||||
flags = append(flags, "--cleanup")
|
||||
}
|
||||
duration := strconv.Itoa(timeout)
|
||||
@@ -1419,6 +1427,11 @@ func (st *HelmState) BuildDeps(helm helmexec.Interface) []error {
|
||||
errs := []error{}
|
||||
|
||||
for _, release := range st.Releases {
|
||||
if len(release.Chart) == 0 {
|
||||
errs = append(errs, errors.New("chart is required for: "+release.Name))
|
||||
continue
|
||||
}
|
||||
|
||||
if isLocalChart(release.Chart) {
|
||||
if err := helm.BuildDeps(release.Name, normalizeChart(st.basePath, release.Chart)); err != nil {
|
||||
errs = append(errs, err)
|
||||
@@ -1590,6 +1603,8 @@ func (st *HelmState) flagsForTemplate(helm helmexec.Interface, release *ReleaseS
|
||||
return nil, err
|
||||
}
|
||||
|
||||
flags = st.appendApiVersionsFlags(flags)
|
||||
|
||||
common, err := st.namespaceAndValuesFlags(helm, release, workerIndex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1622,6 +1637,13 @@ func (st *HelmState) flagsForDiff(helm helmexec.Interface, release *ReleaseSpec,
|
||||
return append(flags, common...), nil
|
||||
}
|
||||
|
||||
func (st *HelmState) appendApiVersionsFlags(flags []string) []string {
|
||||
for _, a := range st.ApiVersions {
|
||||
flags = append(flags, "--api-versions", a)
|
||||
}
|
||||
return flags
|
||||
}
|
||||
|
||||
func (st *HelmState) isDevelopment(release *ReleaseSpec) bool {
|
||||
result := st.HelmDefaults.Devel
|
||||
if release.Devel != nil {
|
||||
|
||||
@@ -1168,7 +1168,7 @@ func TestHelmState_SyncReleasesAffectedRealeases(t *testing.T) {
|
||||
//simulate the release is already installed
|
||||
for i, release := range tt.releases {
|
||||
if tt.installed != nil && tt.installed[i] {
|
||||
helm.Lists[exectest.ListKey{Filter: "^" + release.Name + "$"}] = release.Name
|
||||
helm.Lists[exectest.ListKey{Filter: "^" + release.Name + "$", Flags: "--deployed--failed--pending"}] = release.Name
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1268,7 +1268,7 @@ func TestGetDeployedVersion(t *testing.T) {
|
||||
Lists: map[exectest.ListKey]string{},
|
||||
}
|
||||
//simulate the helm.list call result
|
||||
helm.Lists[exectest.ListKey{Filter: "^" + tt.release.Name + "$"}] = tt.listResult
|
||||
helm.Lists[exectest.ListKey{Filter: "^" + tt.release.Name + "$", Flags: "--deployed--failed--pending"}] = tt.listResult
|
||||
|
||||
affectedReleases := AffectedReleases{}
|
||||
state.SyncReleases(&affectedReleases, helm, []string{}, 1)
|
||||
@@ -1391,7 +1391,7 @@ func TestHelmState_DiffReleases(t *testing.T) {
|
||||
logger: logger,
|
||||
valsRuntime: valsRuntime,
|
||||
}
|
||||
_, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, false)
|
||||
_, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, false, false)
|
||||
if errs != nil && len(errs) > 0 {
|
||||
t.Errorf("unexpected error: %v", errs)
|
||||
}
|
||||
@@ -1556,7 +1556,7 @@ func TestHelmState_DiffReleasesCleanup(t *testing.T) {
|
||||
`,
|
||||
})
|
||||
state = injectFs(state, testfs)
|
||||
if _, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, false); errs != nil && len(errs) > 0 {
|
||||
if _, errs := state.DiffReleases(tt.helm, []string{}, 1, false, false, false, false); errs != nil && len(errs) > 0 {
|
||||
t.Errorf("unexpected errors: %v", errs)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user