From f838622f606733d3fda48298df9e6e883c189040 Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Sun, 14 Mar 2021 11:44:50 +0300 Subject: [PATCH 01/21] feat(Dockerfile): bump helm version --- Dockerfile.helm3 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile.helm3 b/Dockerfile.helm3 index 6515e82b..c7b6efb9 100644 --- a/Dockerfile.helm3 +++ b/Dockerfile.helm3 @@ -11,10 +11,10 @@ FROM alpine:3.11 RUN apk add --no-cache ca-certificates git bash curl jq -ARG HELM_VERSION="v3.5.0" +ARG HELM_VERSION="v3.5.3" ARG HELM_LOCATION="https://get.helm.sh" ARG HELM_FILENAME="helm-${HELM_VERSION}-linux-amd64.tar.gz" -ARG HELM_SHA256="3fff0354d5fba4c73ebd5db59a59db72f8a5bbe1117a0b355b0c2983e98db95b" +ARG HELM_SHA256="2170a1a644a9e0b863f00c17b761ce33d4323da64fc74562a3a6df2abbf6cd70" RUN set -x && \ wget ${HELM_LOCATION}/${HELM_FILENAME} && \ echo Verifying ${HELM_FILENAME}... && \ From c6cf4ace7f8e2cb3b2226e7c076217b6815552fb Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Sun, 14 Mar 2021 12:09:39 +0300 Subject: [PATCH 02/21] fix(Makefile): static-linux mod --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 8d2f6c30..936595ea 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ cross: .PHONY: cross static-linux: - env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GOFLAGS=-mod=vendor go build -o "dist/helmfile_linux_amd64" -ldflags '-X github.com/roboll/helmfile/pkg/app/version.Version=${TAG}' ${TARGETS} + env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GOFLAGS=-mod=readonly go build -o "dist/helmfile_linux_amd64" -ldflags '-X github.com/roboll/helmfile/pkg/app/version.Version=${TAG}' ${TARGETS} .PHONY: static-linux install: @@ -63,7 +63,6 @@ run: image push: image docker push quay.io/${ORG}/helmfile:${TAG} - image/helm3: docker build -f Dockerfile.helm3 -t quay.io/${ORG}/helmfile:helm3-${TAG} . From 1d7f2d2d11ed575e248d50137ef4be5bb90cbe1a Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Sun, 14 Mar 2021 12:10:12 +0300 Subject: [PATCH 03/21] feat(Dockerfile): pin helm-secrets version --- Dockerfile.helm3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.helm3 b/Dockerfile.helm3 index c7b6efb9..8b3157ec 100644 --- a/Dockerfile.helm3 +++ b/Dockerfile.helm3 @@ -46,7 +46,7 @@ RUN set -x && \ mv kustomize /usr/local/bin/kustomize RUN helm plugin install https://github.com/databus23/helm-diff --version v3.1.3 && \ - helm plugin install https://github.com/jkroepke/helm-secrets && \ + helm plugin install https://github.com/jkroepke/helm-secrets --version v3.5.0 && \ helm plugin install https://github.com/hypnoglow/helm-s3.git && \ helm plugin install https://github.com/aslafy-z/helm-git.git From e339847d6e234ccc75a29a3e86afb3e3447e9711 Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Sun, 14 Mar 2021 12:27:25 +0300 Subject: [PATCH 04/21] test: sync HELM_VERSION and KUSTOMIZE_VERSION for tests --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3031c756..d97b2896 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -153,7 +153,7 @@ jobs: - run: name: Install helm environment: - HELM_VERSION: v3.4.2 + HELM_VERSION: v3.5.3 command: | HELM_FILENAME="helm-${HELM_VERSION}-linux-amd64.tar.gz" curl -Lo ${HELM_FILENAME} "https://get.helm.sh/${HELM_FILENAME}" @@ -163,7 +163,7 @@ jobs: - run: name: Install kustomize environment: - KUSTOMIZE_VERSION: v3.6.1 + KUSTOMIZE_VERSION: v3.8.8 command: | KUSTOMIZE_FILENAME="kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz" curl -Lo ${KUSTOMIZE_FILENAME} "https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2F${KUSTOMIZE_VERSION}/${KUSTOMIZE_FILENAME}" From 2f6da13a15464b66528febc165055e5a821db6d4 Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Mon, 15 Mar 2021 14:15:37 +0300 Subject: [PATCH 05/21] test: vagrant for integration tests --- .circleci/Makefile | 51 ++++++++++++++++++++++++++++++++++++++++++++++ .gitignore | 3 +++ Vagrantfile | 19 +++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 .circleci/Makefile create mode 100644 Vagrantfile diff --git a/.circleci/Makefile b/.circleci/Makefile new file mode 100644 index 00000000..34383640 --- /dev/null +++ b/.circleci/Makefile @@ -0,0 +1,51 @@ +HELM_VERSION ?= v3.5.3 +KUSTOMIZE_VERSION ?= v3.8.8 +K8S_VERSION ?= v1.13.12 +MINIKUBE_VERSION ?= v0.30.0 + +# --- +CHANGE_MINIKUBE_NONE_USER ?= true +MINIKUBE_WANTUPDATENOTIFICATION ?= false +MINIKUBE_WANTREPORTERRORPROMPT ?= false + +tmp := $(shell mktemp -d) +HELM_FILENAME := helm-${HELM_VERSION}-linux-amd64.tar.gz +KUSTOMIZE_FILENAME := kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz + + +all: helm kustomize minikube/destroy minikube + +helm: + curl -sSLo $(tmp)/${HELM_FILENAME} "https://get.helm.sh/${HELM_FILENAME}" + tar zxf $(tmp)/${HELM_FILENAME} --directory ${tmp} linux-amd64/helm + chmod +x ${tmp}/linux-amd64/helm + sudo mv ${tmp}/linux-amd64/helm /usr/local/bin/ +.PHONY: helm + +kustomize: + curl -sSLo $(tmp)/${KUSTOMIZE_FILENAME} "https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2F${KUSTOMIZE_VERSION}/${KUSTOMIZE_FILENAME}" + tar zxf $(tmp)/${KUSTOMIZE_FILENAME} --directory ${tmp} kustomize + chmod +x ${tmp}/kustomize + sudo mv ${tmp}/kustomize /usr/local/bin/ +.PHONY: kustomize + +minikube/destroy: + sudo -E minikube delete || true + sudo -E rm -rf /etc/kubernetes || true + sudo -E rm -rf $$HOME/.minikube/* || true +.PHONY: minikube/destroy +.EXPORT_ALL_VARIABLES: minikube/destroy + +minikube: + curl -sSLo ${tmp}/kubectl https://storage.googleapis.com/kubernetes-release/release/${K8S_VERSION}/bin/linux/amd64/kubectl + chmod +x ${tmp}/kubectl && sudo mv ${tmp}/kubectl /usr/local/bin/ + curl -sSLo ${tmp}/minikube https://storage.googleapis.com/minikube/releases/${MINIKUBE_VERSION}/minikube-linux-amd64 + chmod +x ${tmp}/minikube && sudo mv ${tmp}/minikube /usr/local/bin/ + sudo -E minikube delete || true + sudo -E rm -rf /etc/kubernetes || true + sudo -E rm -rf $$HOME/.minikube/* || true + sudo -E minikube start --vm-driver=none --kubernetes-version=${K8S_VERSION} + sudo -E minikube update-context + kubectl wait node/minikube --for=condition=Ready +.PHONY: minikube +.EXPORT_ALL_VARIABLES: minikube diff --git a/.gitignore b/.gitignore index 583077f4..95c56475 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,8 @@ dist/ .idea/ helmfile helmfile.lock +diff-yamls test/integration/tmp vendor/ +*.log +.vagrant/ diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 00000000..69368c69 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,19 @@ +Vagrant.configure("2") do |config| + config.vm.box = "ubuntu/xenial64" + config.vm.hostname = "minikube.box" + config.vm.provision :shell, privileged: false, + inline: <<-EOS + set -e + sudo apt-get update + sudo apt-get install -y make docker.io=18.09.7-* + sudo systemctl start docker + sudo usermod -G docker $USER + cd /vagrant/.circleci + make all + EOS + + config.vm.provider "virtualbox" do |v| + v.memory = 2048 + v.cpus = 2 + end +end From 5ed5edc4cb8084f9d7733052d78a1195359317b6 Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Mon, 15 Mar 2021 14:16:30 +0300 Subject: [PATCH 06/21] fix: gitignore *.lock --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 95c56475..f48f6df5 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ test/integration/tmp vendor/ *.log .vagrant/ +*.lock From f21a4837e0955f3ae0dca4d06b83dc74a4b4b17a Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Mon, 15 Mar 2021 14:16:49 +0300 Subject: [PATCH 07/21] test: reusable integration test --- test/integration/run.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/integration/run.sh b/test/integration/run.sh index 63e42dc9..788faeff 100755 --- a/test/integration/run.sh +++ b/test/integration/run.sh @@ -56,7 +56,8 @@ else info "Using Helm version: $(helm version --short | grep -o v.*$)" fi info "Using Kustomize version: $(kustomize version --short | grep -o 'v[^ ]+')" -${helm} plugin install https://github.com/databus23/helm-diff --version v3.0.0-rc.7 +${helm} plugin ls | grep diff || ${helm} plugin install https://github.com/databus23/helm-diff --version v3.1.3 +${helm} plugin ls | grep secrets || ${helm} plugin install https://github.com/jkroepke/helm-secrets --version v3.5.0 ${kubectl} get namespace ${test_ns} &> /dev/null && warn "Namespace ${test_ns} exists, from a previous test run?" $kubectl create namespace ${test_ns} || fail "Could not create namespace ${test_ns}" trap "{ $kubectl delete namespace ${test_ns}; }" EXIT # remove namespace whenever we exit this script From c23223278895912cfb3b407ecacb8290251fe4f8 Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Mon, 15 Mar 2021 14:37:45 +0300 Subject: [PATCH 08/21] ci: verify new integration tests --- .circleci/config.yml | 71 +++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d97b2896..bc107d7e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -137,10 +137,10 @@ jobs: integration_tests_helm3: machine: image: circleci/classic:201808-01 - environment: - CHANGE_MINIKUBE_NONE_USER: true - MINIKUBE_WANTUPDATENOTIFICATION: false - MINIKUBE_WANTREPORTERRORPROMPT: false + # environment: + # CHANGE_MINIKUBE_NONE_USER: true + # MINIKUBE_WANTUPDATENOTIFICATION: false + # MINIKUBE_WANTREPORTERRORPROMPT: false steps: - checkout - run: mkdir ~/build @@ -152,40 +152,43 @@ jobs: cp ~/build/diff-yamls ~/project/diff-yamls - run: name: Install helm - environment: - HELM_VERSION: v3.5.3 - command: | - HELM_FILENAME="helm-${HELM_VERSION}-linux-amd64.tar.gz" - curl -Lo ${HELM_FILENAME} "https://get.helm.sh/${HELM_FILENAME}" - tar zxf ${HELM_FILENAME} linux-amd64/helm - chmod +x linux-amd64/helm - sudo mv linux-amd64/helm /usr/local/bin/ + command: cd .circleci; make helm + # environment: + # HELM_VERSION: v3.5.3 + # command: | + # HELM_FILENAME="helm-${HELM_VERSION}-linux-amd64.tar.gz" + # curl -Lo ${HELM_FILENAME} "https://get.helm.sh/${HELM_FILENAME}" + # tar zxf ${HELM_FILENAME} linux-amd64/helm + # chmod +x linux-amd64/helm + # sudo mv linux-amd64/helm /usr/local/bin/ - run: name: Install kustomize - environment: - KUSTOMIZE_VERSION: v3.8.8 - command: | - KUSTOMIZE_FILENAME="kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz" - curl -Lo ${KUSTOMIZE_FILENAME} "https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2F${KUSTOMIZE_VERSION}/${KUSTOMIZE_FILENAME}" - tar zxf ${KUSTOMIZE_FILENAME} kustomize - chmod +x kustomize - sudo mv kustomize /usr/local/bin/ + command: cd .circleci; make kustomize + # environment: + # KUSTOMIZE_VERSION: v3.8.8 + # command: | + # KUSTOMIZE_FILENAME="kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz" + # curl -Lo ${KUSTOMIZE_FILENAME} "https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2F${KUSTOMIZE_VERSION}/${KUSTOMIZE_FILENAME}" + # tar zxf ${KUSTOMIZE_FILENAME} kustomize + # chmod +x kustomize + # sudo mv kustomize /usr/local/bin/ - run: name: Deploy minikube - environment: - CHANGE_MINIKUBE_NONE_USER: true - K8S_VERSION: v1.12.3 - MINIKUBE_VERSION: v0.30.0 - command: | - curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/${K8S_VERSION}/bin/linux/amd64/kubectl - chmod +x kubectl && sudo mv kubectl /usr/local/bin/ - curl -Lo minikube https://storage.googleapis.com/minikube/releases/${MINIKUBE_VERSION}/minikube-linux-amd64 - chmod +x minikube && sudo mv minikube /usr/local/bin/ - sudo -E minikube start --vm-driver=none --kubernetes-version=${K8S_VERSION} - sudo -E minikube update-context - - run: - name: Wait for nodes to become ready - command: JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}'; until kubectl get nodes -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True"; do sleep 1; done + command: cd .circleci; make minikube + # environment: + # CHANGE_MINIKUBE_NONE_USER: true + # K8S_VERSION: v1.12.3 + # MINIKUBE_VERSION: v0.30.0 + # command: | + # curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/${K8S_VERSION}/bin/linux/amd64/kubectl + # chmod +x kubectl && sudo mv kubectl /usr/local/bin/ + # curl -Lo minikube https://storage.googleapis.com/minikube/releases/${MINIKUBE_VERSION}/minikube-linux-amd64 + # chmod +x minikube && sudo mv minikube /usr/local/bin/ + # sudo -E minikube start --vm-driver=none --kubernetes-version=${K8S_VERSION} + # sudo -E minikube update-context + # - run: + # name: Wait for nodes to become ready + # command: JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}'; until kubectl get nodes -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True"; do sleep 1; done - run: name: Execute integration tests command: | From e1c8f520e4234e3f47b8bac0d014a4d463332a7b Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Mon, 15 Mar 2021 14:50:01 +0300 Subject: [PATCH 09/21] test: fix helm2 integration tests --- test/integration/run.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/integration/run.sh b/test/integration/run.sh index 788faeff..c390622a 100755 --- a/test/integration/run.sh +++ b/test/integration/run.sh @@ -50,14 +50,15 @@ if helm version --client 2>/dev/null | grep '"v2\.'; then helm_major_version=2 info "Using Helm version: $(helm version --short --client | grep -o v.*$)" ${helm} init --stable-repo-url https://charts.helm.sh/stable --wait --override spec.template.spec.automountServiceAccountToken=true + ${helm} plugin ls | grep diff || ${helm} plugin install https://github.com/databus23/helm-diff --version v2.11.0+5 # helm v3 else helm_major_version=3 info "Using Helm version: $(helm version --short | grep -o v.*$)" + ${helm} plugin ls | grep diff || ${helm} plugin install https://github.com/databus23/helm-diff --version v3.1.3 + ${helm} plugin ls | grep secrets || ${helm} plugin install https://github.com/jkroepke/helm-secrets --version v3.5.0 fi info "Using Kustomize version: $(kustomize version --short | grep -o 'v[^ ]+')" -${helm} plugin ls | grep diff || ${helm} plugin install https://github.com/databus23/helm-diff --version v3.1.3 -${helm} plugin ls | grep secrets || ${helm} plugin install https://github.com/jkroepke/helm-secrets --version v3.5.0 ${kubectl} get namespace ${test_ns} &> /dev/null && warn "Namespace ${test_ns} exists, from a previous test run?" $kubectl create namespace ${test_ns} || fail "Could not create namespace ${test_ns}" trap "{ $kubectl delete namespace ${test_ns}; }" EXIT # remove namespace whenever we exit this script From 001cd9fb6ac57a6d7e7def32643bc704dbd50c25 Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Mon, 15 Mar 2021 14:50:38 +0300 Subject: [PATCH 10/21] ci: simplify integration tests ci code --- .circleci/config.yml | 78 +++----------------------------------------- 1 file changed, 5 insertions(+), 73 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bc107d7e..07b78832 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -79,10 +79,6 @@ jobs: integration_tests: machine: image: circleci/classic:201808-01 - environment: - CHANGE_MINIKUBE_NONE_USER: true - MINIKUBE_WANTUPDATENOTIFICATION: false - MINIKUBE_WANTREPORTERRORPROMPT: false steps: - checkout - run: mkdir ~/build @@ -102,32 +98,8 @@ jobs: tar zxf ${HELM_FILENAME} linux-amd64/helm chmod +x linux-amd64/helm sudo mv linux-amd64/helm /usr/local/bin/ - - run: - name: Install kustomize - environment: - KUSTOMIZE_VERSION: v3.6.1 - command: | - KUSTOMIZE_FILENAME="kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz" - curl -Lo ${KUSTOMIZE_FILENAME} "https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2F${KUSTOMIZE_VERSION}/${KUSTOMIZE_FILENAME}" - tar zxf ${KUSTOMIZE_FILENAME} kustomize - chmod +x kustomize - sudo mv kustomize /usr/local/bin/ - - run: - name: Deploy minikube - environment: - CHANGE_MINIKUBE_NONE_USER: true - K8S_VERSION: v1.12.3 - MINIKUBE_VERSION: v0.30.0 - command: | - curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/${K8S_VERSION}/bin/linux/amd64/kubectl - chmod +x kubectl && sudo mv kubectl /usr/local/bin/ - curl -Lo minikube https://storage.googleapis.com/minikube/releases/${MINIKUBE_VERSION}/minikube-linux-amd64 - chmod +x minikube && sudo mv minikube /usr/local/bin/ - sudo -E minikube start --vm-driver=none --kubernetes-version=${K8S_VERSION} - sudo -E minikube update-context - - run: - name: Wait for nodes to become ready - command: JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}'; until kubectl get nodes -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True"; do sleep 1; done + - run: make -C .circleci kustomize + - run: make -C .circleci minikube - run: name: Execute integration tests command: | @@ -137,10 +109,6 @@ jobs: integration_tests_helm3: machine: image: circleci/classic:201808-01 - # environment: - # CHANGE_MINIKUBE_NONE_USER: true - # MINIKUBE_WANTUPDATENOTIFICATION: false - # MINIKUBE_WANTREPORTERRORPROMPT: false steps: - checkout - run: mkdir ~/build @@ -150,45 +118,9 @@ jobs: command: | cp ~/build/helmfile ~/project/helmfile cp ~/build/diff-yamls ~/project/diff-yamls - - run: - name: Install helm - command: cd .circleci; make helm - # environment: - # HELM_VERSION: v3.5.3 - # command: | - # HELM_FILENAME="helm-${HELM_VERSION}-linux-amd64.tar.gz" - # curl -Lo ${HELM_FILENAME} "https://get.helm.sh/${HELM_FILENAME}" - # tar zxf ${HELM_FILENAME} linux-amd64/helm - # chmod +x linux-amd64/helm - # sudo mv linux-amd64/helm /usr/local/bin/ - - run: - name: Install kustomize - command: cd .circleci; make kustomize - # environment: - # KUSTOMIZE_VERSION: v3.8.8 - # command: | - # KUSTOMIZE_FILENAME="kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz" - # curl -Lo ${KUSTOMIZE_FILENAME} "https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2F${KUSTOMIZE_VERSION}/${KUSTOMIZE_FILENAME}" - # tar zxf ${KUSTOMIZE_FILENAME} kustomize - # chmod +x kustomize - # sudo mv kustomize /usr/local/bin/ - - run: - name: Deploy minikube - command: cd .circleci; make minikube - # environment: - # CHANGE_MINIKUBE_NONE_USER: true - # K8S_VERSION: v1.12.3 - # MINIKUBE_VERSION: v0.30.0 - # command: | - # curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/${K8S_VERSION}/bin/linux/amd64/kubectl - # chmod +x kubectl && sudo mv kubectl /usr/local/bin/ - # curl -Lo minikube https://storage.googleapis.com/minikube/releases/${MINIKUBE_VERSION}/minikube-linux-amd64 - # chmod +x minikube && sudo mv minikube /usr/local/bin/ - # sudo -E minikube start --vm-driver=none --kubernetes-version=${K8S_VERSION} - # sudo -E minikube update-context - # - run: - # name: Wait for nodes to become ready - # command: JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}'; until kubectl get nodes -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True"; do sleep 1; done + - run: make -C .circleci helm + - run: make -C .circleci kustomize + - run: make -C .circleci minikube - run: name: Execute integration tests command: | From b2a207d3b5ed3dc1a88d809ad1aab142eb68ad32 Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Mon, 15 Mar 2021 22:33:57 +0300 Subject: [PATCH 11/21] ci: simplify integration tests ci code for helm2 --- .circleci/Makefile | 9 +++++++++ .circleci/config.yml | 20 +++++++------------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/.circleci/Makefile b/.circleci/Makefile index 34383640..5712b02e 100644 --- a/.circleci/Makefile +++ b/.circleci/Makefile @@ -1,4 +1,5 @@ HELM_VERSION ?= v3.5.3 +HELM2_VERSION ?= v2.17.0 KUSTOMIZE_VERSION ?= v3.8.8 K8S_VERSION ?= v1.13.12 MINIKUBE_VERSION ?= v0.30.0 @@ -10,6 +11,7 @@ MINIKUBE_WANTREPORTERRORPROMPT ?= false tmp := $(shell mktemp -d) HELM_FILENAME := helm-${HELM_VERSION}-linux-amd64.tar.gz +HELM2_FILENAME := helm-${HELM2_VERSION}-linux-amd64.tar.gz KUSTOMIZE_FILENAME := kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz @@ -22,6 +24,13 @@ helm: sudo mv ${tmp}/linux-amd64/helm /usr/local/bin/ .PHONY: helm +helm2: + curl -sSLo $(tmp)/${HELM2_FILENAME} "https://kubernetes-helm.storage.googleapis.com/${HELM2_FILENAME}" + tar zxf $(tmp)/${HELM2_FILENAME} --directory ${tmp} linux-amd64/helm + chmod +x ${tmp}/linux-amd64/helm + sudo mv ${tmp}/linux-amd64/helm /usr/local/bin/ +.PHONY: helm2 + kustomize: curl -sSLo $(tmp)/${KUSTOMIZE_FILENAME} "https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2F${KUSTOMIZE_VERSION}/${KUSTOMIZE_FILENAME}" tar zxf $(tmp)/${KUSTOMIZE_FILENAME} --directory ${tmp} kustomize diff --git a/.circleci/config.yml b/.circleci/config.yml index 07b78832..f1164397 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -88,22 +88,14 @@ jobs: command: | cp ~/build/helmfile ~/project/helmfile cp ~/build/diff-yamls ~/project/diff-yamls - - run: - name: Install helm - environment: - HELM_VERSION: v2.17.0 - command: | - HELM_FILENAME="helm-${HELM_VERSION}-linux-amd64.tar.gz" - curl -Lo ${HELM_FILENAME} "https://kubernetes-helm.storage.googleapis.com/${HELM_FILENAME}" - tar zxf ${HELM_FILENAME} linux-amd64/helm - chmod +x linux-amd64/helm - sudo mv linux-amd64/helm /usr/local/bin/ + - run: make -C .circleci helm2 - run: make -C .circleci kustomize - run: make -C .circleci minikube - run: name: Execute integration tests + environment: + TERM: "xterm" command: | - export TERM=xterm make integration integration_tests_helm3: @@ -123,9 +115,11 @@ jobs: - run: make -C .circleci minikube - run: name: Execute integration tests + environment: + HELMFILE_HELM3: "1" + TERM: "xterm" command: | - export TERM=xterm - HELMFILE_HELM3=1 make integration + make integration # GITHUB_TOKEN env var must be setup in circleci console From bacd9dae216a8a500c596cbb2f154e5721021cad Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Mon, 15 Mar 2021 22:37:32 +0300 Subject: [PATCH 12/21] test: add vault and sops for integration secret testing --- .circleci/Makefile | 19 ++++++++++++++++++- .circleci/config.yml | 2 ++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.circleci/Makefile b/.circleci/Makefile index 5712b02e..43d361e7 100644 --- a/.circleci/Makefile +++ b/.circleci/Makefile @@ -3,19 +3,23 @@ HELM2_VERSION ?= v2.17.0 KUSTOMIZE_VERSION ?= v3.8.8 K8S_VERSION ?= v1.13.12 MINIKUBE_VERSION ?= v0.30.0 +SOPS_VERSION ?= v3.6.1 # --- CHANGE_MINIKUBE_NONE_USER ?= true MINIKUBE_WANTUPDATENOTIFICATION ?= false MINIKUBE_WANTREPORTERRORPROMPT ?= false +VAULT_ADDR := http://127.0.0.1:8200 +VAULT_TOKEN := toor + tmp := $(shell mktemp -d) HELM_FILENAME := helm-${HELM_VERSION}-linux-amd64.tar.gz HELM2_FILENAME := helm-${HELM2_VERSION}-linux-amd64.tar.gz KUSTOMIZE_FILENAME := kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz -all: helm kustomize minikube/destroy minikube +all: vault sops helm kustomize minikube/destroy minikube helm: curl -sSLo $(tmp)/${HELM_FILENAME} "https://get.helm.sh/${HELM_FILENAME}" @@ -58,3 +62,16 @@ minikube: kubectl wait node/minikube --for=condition=Ready .PHONY: minikube .EXPORT_ALL_VARIABLES: minikube + +vault: + docker kill $$(docker ps -a --filter "name=vault" -q) + docker run -d -p8200:8200 --rm --name vault vault:1.2.0 server -dev -dev-root-token-id=toor + docker run --rm --network="host" -e VAULT_ADDR=$$VAULT_ADDR -e VAULT_TOKEN=$$VAULT_TOKEN vault:1.2.0 secrets enable -path=sops transit + docker run --rm --network="host" -e VAULT_ADDR=$$VAULT_ADDR -e VAULT_TOKEN=$$VAULT_TOKEN vault:1.2.0 write sops/keys/key type=rsa-4096 +.PHONY: vault + +sops: + curl -sSLo $(tmp)/sops "https://github.com/mozilla/sops/releases/download/${SOPS_VERSION}/sops-${SOPS_VERSION}.linux" + chmod +x $(tmp)/sops + sudo mv ${tmp}/sops /usr/local/bin/ +.PHONY: sops diff --git a/.circleci/config.yml b/.circleci/config.yml index f1164397..f946fbc4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -111,6 +111,8 @@ jobs: cp ~/build/helmfile ~/project/helmfile cp ~/build/diff-yamls ~/project/diff-yamls - run: make -C .circleci helm + - run: make -C .circleci vault + - run: make -C .circleci sops - run: make -C .circleci kustomize - run: make -C .circleci minikube - run: From 4d0bf2d9077d80b9b0f4b8e9d715c9060929e0c7 Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Mon, 15 Mar 2021 22:38:43 +0300 Subject: [PATCH 13/21] test: add secrets integration tests --- test/integration/default.values.yaml | 3 + test/integration/env-1.secrets.yaml | 2 + test/integration/env-2.secrets.yaml | 2 + test/integration/run.sh | 151 ++++++++++++++++----------- test/integration/secretssops.yaml | 30 ++++++ 5 files changed, 125 insertions(+), 63 deletions(-) create mode 100644 test/integration/default.values.yaml create mode 100644 test/integration/env-1.secrets.yaml create mode 100644 test/integration/env-2.secrets.yaml create mode 100644 test/integration/secretssops.yaml diff --git a/test/integration/default.values.yaml b/test/integration/default.values.yaml new file mode 100644 index 00000000..ad149437 --- /dev/null +++ b/test/integration/default.values.yaml @@ -0,0 +1,3 @@ +key_1: value +key_2: value +key_shared: value diff --git a/test/integration/env-1.secrets.yaml b/test/integration/env-1.secrets.yaml new file mode 100644 index 00000000..07430a23 --- /dev/null +++ b/test/integration/env-1.secrets.yaml @@ -0,0 +1,2 @@ +key_1: value_1 +key_shared: value_1 diff --git a/test/integration/env-2.secrets.yaml b/test/integration/env-2.secrets.yaml new file mode 100644 index 00000000..81357adf --- /dev/null +++ b/test/integration/env-2.secrets.yaml @@ -0,0 +1,2 @@ +key_2: value_2 +key_shared: value_2 diff --git a/test/integration/run.sh b/test/integration/run.sh index c390622a..9b2ffc20 100755 --- a/test/integration/run.sh +++ b/test/integration/run.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +# vim: set tabstop=4 shiftwidth=4 # IMPORTS ----------------------------------------------------------------------------------------------------------- @@ -47,16 +48,15 @@ set -e info "Using namespace: ${test_ns}" # helm v2 if helm version --client 2>/dev/null | grep '"v2\.'; then - helm_major_version=2 - info "Using Helm version: $(helm version --short --client | grep -o v.*$)" - ${helm} init --stable-repo-url https://charts.helm.sh/stable --wait --override spec.template.spec.automountServiceAccountToken=true - ${helm} plugin ls | grep diff || ${helm} plugin install https://github.com/databus23/helm-diff --version v2.11.0+5 -# helm v3 -else - helm_major_version=3 - info "Using Helm version: $(helm version --short | grep -o v.*$)" - ${helm} plugin ls | grep diff || ${helm} plugin install https://github.com/databus23/helm-diff --version v3.1.3 - ${helm} plugin ls | grep secrets || ${helm} plugin install https://github.com/jkroepke/helm-secrets --version v3.5.0 + helm_major_version=2 + info "Using Helm version: $(helm version --short --client | grep -o v.*$)" + ${helm} init --stable-repo-url https://charts.helm.sh/stable --wait --override spec.template.spec.automountServiceAccountToken=true + ${helm} plugin ls | grep diff || ${helm} plugin install https://github.com/databus23/helm-diff --version v2.11.0+5 +else # helm v3 + helm_major_version=3 + info "Using Helm version: $(helm version --short | grep -o v.*$)" + ${helm} plugin ls | grep diff || ${helm} plugin install https://github.com/databus23/helm-diff --version v3.1.3 + # ${helm} plugin ls | grep secrets || ${helm} plugin install https://github.com/jkroepke/helm-secrets --version v3.5.0 fi info "Using Kustomize version: $(kustomize version --short | grep -o 'v[^ ]+')" ${kubectl} get namespace ${test_ns} &> /dev/null && warn "Namespace ${test_ns} exists, from a previous test run?" @@ -66,69 +66,94 @@ trap "{ $kubectl delete namespace ${test_ns}; }" EXIT # remove namespace wheneve # TEST CASES---------------------------------------------------------------------------------------------------------- -test_start "happypath - simple rollout of httpbin chart" - -info "Diffing ${dir}/happypath.yaml" -bash -c "${helmfile} -f ${dir}/happypath.yaml diff --detailed-exitcode; code="'$?'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile diff" - -info "Diffing ${dir}/happypath.yaml without color" -bash -c "${helmfile} -f ${dir}/happypath.yaml --no-color diff --detailed-exitcode; code="'$?'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile diff" - -info "Diffing ${dir}/happypath.yaml with limited context" -bash -c "${helmfile} -f ${dir}/happypath.yaml diff --context 3 --detailed-exitcode; code="'$?'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile diff" - -info "Templating ${dir}/happypath.yaml" -rm -rf ${dir}/tmp -${helmfile} -f ${dir}/happypath.yaml --debug template --output-dir tmp -code=$? -[ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile template: ${code}" -for output in $(ls -d ${dir}/tmp/*); do - # e.g. test/integration/tmp/happypath-877c0dd4-helmx/helmx - for release_dir in $(ls -d ${output}/*); do - release_name=$(basename ${release_dir}) - golden_dir=${dir}/templates-golden/v${helm_major_version}/${release_name} - info "Comparing template output ${release_dir}/templates with ${golden_dir}" - ./diff-yamls ${golden_dir} ${release_dir}/templates || fail "unexpected diff in template result for ${release_name}" - done -done +# test_start "happypath - simple rollout of httpbin chart" + +# info "Diffing ${dir}/happypath.yaml" +# bash -c "${helmfile} -f ${dir}/happypath.yaml diff --detailed-exitcode; code="'$?'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile diff" + +# info "Diffing ${dir}/happypath.yaml without color" +# bash -c "${helmfile} -f ${dir}/happypath.yaml --no-color diff --detailed-exitcode; code="'$?'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile diff" + +# info "Diffing ${dir}/happypath.yaml with limited context" +# bash -c "${helmfile} -f ${dir}/happypath.yaml diff --context 3 --detailed-exitcode; code="'$?'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile diff" + +# info "Templating ${dir}/happypath.yaml" +# rm -rf ${dir}/tmp +# ${helmfile} -f ${dir}/happypath.yaml --debug template --output-dir tmp +# code=$? +# [ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile template: ${code}" +# for output in $(ls -d ${dir}/tmp/*); do +# # e.g. test/integration/tmp/happypath-877c0dd4-helmx/helmx +# for release_dir in $(ls -d ${output}/*); do +# release_name=$(basename ${release_dir}) +# golden_dir=${dir}/templates-golden/v${helm_major_version}/${release_name} +# info "Comparing template output ${release_dir}/templates with ${golden_dir}" +# ./diff-yamls ${golden_dir} ${release_dir}/templates || fail "unexpected diff in template result for ${release_name}" +# done +# done + +# info "Applying ${dir}/happypath.yaml" +# bash -c "${helmfile} -f ${dir}/happypath.yaml apply --detailed-exitcode; code="'$?'"; echo Code: "'$code'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile apply" + +# info "Syncing ${dir}/happypath.yaml" +# ${helmfile} -f ${dir}/happypath.yaml sync +# wait_deploy_ready httpbin-httpbin +# retry 5 "curl --fail $(minikube service --url --namespace=${test_ns} httpbin-httpbin)/status/200" +# [ ${retry_result} -eq 0 ] || fail "httpbin failed to return 200 OK" -info "Applying ${dir}/happypath.yaml" -bash -c "${helmfile} -f ${dir}/happypath.yaml apply --detailed-exitcode; code="'$?'"; echo Code: "'$code'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile apply" +# info "Applying ${dir}/happypath.yaml" +# ${helmfile} -f ${dir}/happypath.yaml apply --detailed-exitcode +# code=$? +# [ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile apply: want 0, got ${code}" -info "Syncing ${dir}/happypath.yaml" -${helmfile} -f ${dir}/happypath.yaml sync -wait_deploy_ready httpbin-httpbin -retry 5 "curl --fail $(minikube service --url --namespace=${test_ns} httpbin-httpbin)/status/200" -[ ${retry_result} -eq 0 ] || fail "httpbin failed to return 200 OK" +# info "Locking dependencies" +# ${helmfile} -f ${dir}/happypath.yaml deps +# code=$? +# [ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile deps: ${code}" -info "Applying ${dir}/happypath.yaml" -${helmfile} -f ${dir}/happypath.yaml apply --detailed-exitcode -code=$? -[ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile apply: want 0, got ${code}" +# info "Applying ${dir}/happypath.yaml with locked dependencies" +# ${helmfile} -f ${dir}/happypath.yaml apply +# code=$? +# [ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile apply: ${code}" +# ${helm} list --namespace=${test_ns} || fail "unable to list releases" -info "Locking dependencies" -${helmfile} -f ${dir}/happypath.yaml deps -code=$? -[ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile deps: ${code}" +# info "Deleting release" +# ${helmfile} -f ${dir}/happypath.yaml delete +# ${helm} status --namespace=${test_ns} httpbin &> /dev/null && fail "release should not exist anymore after a delete" -info "Applying ${dir}/happypath.yaml with locked dependencies" -${helmfile} -f ${dir}/happypath.yaml apply -code=$? -[ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile apply: ${code}" -${helm} list --namespace=${test_ns} || fail "unable to list releases" +# info "Ensuring \"helmfile delete\" doesn't fail when no releases installed" +# ${helmfile} -f ${dir}/happypath.yaml delete || fail "\"helmfile delete\" shouldn't fail when there are no installed releases" -info "Deleting release" -${helmfile} -f ${dir}/happypath.yaml delete -${helm} status --namespace=${test_ns} httpbin &> /dev/null && fail "release should not exist anymore after a delete" +# info "Ensuring \"helmfile template\" output does contain only YAML docs" +# (${helmfile} -f ${dir}/happypath.yaml template | kubectl apply -f -) || fail "\"helmfile template | kubectl apply -f -\" shouldn't fail" -info "Ensuring \"helmfile delete\" doesn't fail when no releases installed" -${helmfile} -f ${dir}/happypath.yaml delete || fail "\"helmfile delete\" shouldn't fail when there are no installed releases" +# test_pass "happypath" -info "Ensuring \"helmfile template\" output does contain only YAML docs" -(${helmfile} -f ${dir}/happypath.yaml template | kubectl apply -f -) || fail "\"helmfile template | kubectl apply -f -\" shouldn't fail" +if [[ helm_major_version -eq 3 ]]; then + export VAULT_ADDR=http://127.0.0.1:8200 + export VAULT_TOKEN=toor + sops="sops --hc-vault-transit $VAULT_ADDR/v1/sops/keys/key" -test_pass "happypath" + test_start "secretssops" + info "Ensure helm-secrets is not installed" + ${helm} plugin rm secrets + + info "Ensure helmfile fails when no helm-secrets is installed" + ${helmfile} -f ${dir}/secretssops.yaml -e direct build && fail "\"helmfile build\" should fail without secrets plugin" + + info "Ensure helm-secrets is installed" + ${helm} plugin install https://github.com/jkroepke/helm-secrets --version v3.5.0 + + info "Encrypt secrets" + ${sops} -e ${dir}/env-1.secrets.yaml > ${dir}/tmp/env-1.secrets.sops.yaml || fail "${sops} failed" + ${sops} -e ${dir}/env-2.secrets.yaml > ${dir}/tmp/env-2.secrets.sops.yaml || fail "${sops} failed" + + info "Ensure helmfile succeed when helm-secrets is installed" + ${helmfile} -f ${dir}/secretssops.yaml -e direct build || fail "\"helmfile build\" shouldn't fail" + + test_pass "secretssops" +fi # ALL DONE ----------------------------------------------------------------------------------------------------------- diff --git a/test/integration/secretssops.yaml b/test/integration/secretssops.yaml new file mode 100644 index 00000000..2539fab7 --- /dev/null +++ b/test/integration/secretssops.yaml @@ -0,0 +1,30 @@ +environments: + direct: + values: + - default.values.yaml + secrets: + - tmp/env-1.secrets.sops.yaml + - tmp/env-2.secrets.sops.yaml + reverse: + values: + - default.values.yaml + secrets: + - tmp/env-2.secrets.sops.yaml + - tmp/env-1.secrets.sops.yaml +--- +repositories: + - name: center + url: https://repo.chartcenter.io + +helmDefaults: + kubeContext: minikube + +releases: + + - name: raw + chart: center/incubator/raw + version: 0.2.3 + values: + - mysecret: {{ .Environment.Values.key_1 }} + - mysecret: {{ .Environment.Values.key_2 }} + - mysecret: {{ .Environment.Values.key_shared }} From 5d6a71c3455b70a402d0d9481be819ea5c7223cc Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Mon, 15 Mar 2021 22:45:18 +0300 Subject: [PATCH 14/21] test: fix vault provisioning code --- .circleci/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/Makefile b/.circleci/Makefile index 43d361e7..c4f5057f 100644 --- a/.circleci/Makefile +++ b/.circleci/Makefile @@ -64,7 +64,7 @@ minikube: .EXPORT_ALL_VARIABLES: minikube vault: - docker kill $$(docker ps -a --filter "name=vault" -q) + docker kill $$(docker ps -a --filter "name=vault" -q) || true docker run -d -p8200:8200 --rm --name vault vault:1.2.0 server -dev -dev-root-token-id=toor docker run --rm --network="host" -e VAULT_ADDR=$$VAULT_ADDR -e VAULT_TOKEN=$$VAULT_TOKEN vault:1.2.0 secrets enable -path=sops transit docker run --rm --network="host" -e VAULT_ADDR=$$VAULT_ADDR -e VAULT_TOKEN=$$VAULT_TOKEN vault:1.2.0 write sops/keys/key type=rsa-4096 From 5a93ad79d7cf564651ab815b7e9f099cf080d582 Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Mon, 15 Mar 2021 23:03:40 +0300 Subject: [PATCH 15/21] test: ensure bash -eo pipefail (as in circleci) --- test/integration/run.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/integration/run.sh b/test/integration/run.sh index 9b2ffc20..68c073be 100755 --- a/test/integration/run.sh +++ b/test/integration/run.sh @@ -1,6 +1,9 @@ #!/usr/bin/env bash # vim: set tabstop=4 shiftwidth=4 +set -e +set -o pipefail + # IMPORTS ----------------------------------------------------------------------------------------------------------- # determine working directory to use to relative paths irrespective of starting directory @@ -137,10 +140,10 @@ if [[ helm_major_version -eq 3 ]]; then test_start "secretssops" info "Ensure helm-secrets is not installed" - ${helm} plugin rm secrets + ${helm} plugin rm secrets || true info "Ensure helmfile fails when no helm-secrets is installed" - ${helmfile} -f ${dir}/secretssops.yaml -e direct build && fail "\"helmfile build\" should fail without secrets plugin" + ${helmfile} -f ${dir}/secretssops.yaml -e direct build; code="$?"; echo Code: "$code"; [ "${code}" -ne 0 ] || fail "\"helmfile build\" should fail without secrets plugin" info "Ensure helm-secrets is installed" ${helm} plugin install https://github.com/jkroepke/helm-secrets --version v3.5.0 From bd919d3aec3335d7c68bbe538cde2a581f4c1e7e Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Mon, 15 Mar 2021 23:12:29 +0300 Subject: [PATCH 16/21] test: fix "Ensure helmfile fails when no helm-secrets is installed" test --- test/integration/run.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/integration/run.sh b/test/integration/run.sh index 68c073be..3e83cc97 100755 --- a/test/integration/run.sh +++ b/test/integration/run.sh @@ -139,6 +139,10 @@ if [[ helm_major_version -eq 3 ]]; then test_start "secretssops" + info "Encrypt secrets" + ${sops} -e ${dir}/env-1.secrets.yaml > ${dir}/tmp/env-1.secrets.sops.yaml || fail "${sops} failed at ${dir}/env-1.secrets.yaml" + ${sops} -e ${dir}/env-2.secrets.yaml > ${dir}/tmp/env-2.secrets.sops.yaml || fail "${sops} failed at ${dir}/env-2.secrets.yaml" + info "Ensure helm-secrets is not installed" ${helm} plugin rm secrets || true @@ -148,10 +152,6 @@ if [[ helm_major_version -eq 3 ]]; then info "Ensure helm-secrets is installed" ${helm} plugin install https://github.com/jkroepke/helm-secrets --version v3.5.0 - info "Encrypt secrets" - ${sops} -e ${dir}/env-1.secrets.yaml > ${dir}/tmp/env-1.secrets.sops.yaml || fail "${sops} failed" - ${sops} -e ${dir}/env-2.secrets.yaml > ${dir}/tmp/env-2.secrets.sops.yaml || fail "${sops} failed" - info "Ensure helmfile succeed when helm-secrets is installed" ${helmfile} -f ${dir}/secretssops.yaml -e direct build || fail "\"helmfile build\" shouldn't fail" From 8b0c4eeac0852a7ffde33db76124796de715fe14 Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Mon, 15 Mar 2021 23:12:29 +0300 Subject: [PATCH 17/21] test: fix "Ensure helmfile fails when no helm-secrets is installed" test --- test/integration/run.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/integration/run.sh b/test/integration/run.sh index 68c073be..32bde369 100755 --- a/test/integration/run.sh +++ b/test/integration/run.sh @@ -136,9 +136,14 @@ if [[ helm_major_version -eq 3 ]]; then export VAULT_ADDR=http://127.0.0.1:8200 export VAULT_TOKEN=toor sops="sops --hc-vault-transit $VAULT_ADDR/v1/sops/keys/key" + mkdir -p ${dir}/tmp test_start "secretssops" + info "Encrypt secrets" + ${sops} -e ${dir}/env-1.secrets.yaml > ${dir}/tmp/env-1.secrets.sops.yaml || fail "${sops} failed at ${dir}/env-1.secrets.yaml" + ${sops} -e ${dir}/env-2.secrets.yaml > ${dir}/tmp/env-2.secrets.sops.yaml || fail "${sops} failed at ${dir}/env-2.secrets.yaml" + info "Ensure helm-secrets is not installed" ${helm} plugin rm secrets || true @@ -148,10 +153,6 @@ if [[ helm_major_version -eq 3 ]]; then info "Ensure helm-secrets is installed" ${helm} plugin install https://github.com/jkroepke/helm-secrets --version v3.5.0 - info "Encrypt secrets" - ${sops} -e ${dir}/env-1.secrets.yaml > ${dir}/tmp/env-1.secrets.sops.yaml || fail "${sops} failed" - ${sops} -e ${dir}/env-2.secrets.yaml > ${dir}/tmp/env-2.secrets.sops.yaml || fail "${sops} failed" - info "Ensure helmfile succeed when helm-secrets is installed" ${helmfile} -f ${dir}/secretssops.yaml -e direct build || fail "\"helmfile build\" shouldn't fail" From d60ab5a16cc9e3803222dcca5bf57c07e8dc97d5 Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Tue, 16 Mar 2021 11:09:58 +0300 Subject: [PATCH 18/21] fix: fixed secrets decryption failed issue --- pkg/helmexec/exec.go | 7 +++++++ test/integration/run.sh | 15 +++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/pkg/helmexec/exec.go b/pkg/helmexec/exec.go index 1c12b599..132c6edd 100644 --- a/pkg/helmexec/exec.go +++ b/pkg/helmexec/exec.go @@ -19,6 +19,7 @@ import ( type decryptedSecret struct { mutex sync.RWMutex bytes []byte + err error } type execer struct { @@ -268,6 +269,7 @@ func (helm *execer) DecryptSecret(context HelmContext, name string, flags ...str out, err := helm.exec(append(append(preArgs, "secrets", "dec", absPath), flags...), env) helm.info(out) if err != nil { + secret.err = err return "", err } @@ -280,6 +282,7 @@ func (helm *execer) DecryptSecret(context HelmContext, name string, flags ...str secretBytes, err := ioutil.ReadFile(decFilename) if err != nil { + secret.err = err return "", err } secret.bytes = secretBytes @@ -295,6 +298,10 @@ func (helm *execer) DecryptSecret(context HelmContext, name string, flags ...str secret.mutex.RLock() helm.decryptedSecretMutex.Unlock() defer secret.mutex.RUnlock() + + if secret.err != nil { + return "", secret.err + } } tempFile := helm.writeTempFile diff --git a/test/integration/run.sh b/test/integration/run.sh index 32bde369..71b17523 100755 --- a/test/integration/run.sh +++ b/test/integration/run.sh @@ -138,17 +138,24 @@ if [[ helm_major_version -eq 3 ]]; then sops="sops --hc-vault-transit $VAULT_ADDR/v1/sops/keys/key" mkdir -p ${dir}/tmp - test_start "secretssops" - info "Encrypt secrets" ${sops} -e ${dir}/env-1.secrets.yaml > ${dir}/tmp/env-1.secrets.sops.yaml || fail "${sops} failed at ${dir}/env-1.secrets.yaml" ${sops} -e ${dir}/env-2.secrets.yaml > ${dir}/tmp/env-2.secrets.sops.yaml || fail "${sops} failed at ${dir}/env-2.secrets.yaml" + test_start "secretssops.1 - should fail without secrets plugin" + info "Ensure helm-secrets is not installed" ${helm} plugin rm secrets || true info "Ensure helmfile fails when no helm-secrets is installed" - ${helmfile} -f ${dir}/secretssops.yaml -e direct build; code="$?"; echo Code: "$code"; [ "${code}" -ne 0 ] || fail "\"helmfile build\" should fail without secrets plugin" + unset code + ${helmfile} -f ${dir}/secretssops.yaml -e direct build || code="$?"; code="${code:-0}" + echo Code: "${code}" + [ "${code}" -ne 0 ] || fail "\"helmfile build\" should fail without secrets plugin" + + test_pass "secretssops.1" + + test_start "secretssops.2 - should succeed with secrets plugin" info "Ensure helm-secrets is installed" ${helm} plugin install https://github.com/jkroepke/helm-secrets --version v3.5.0 @@ -156,7 +163,7 @@ if [[ helm_major_version -eq 3 ]]; then info "Ensure helmfile succeed when helm-secrets is installed" ${helmfile} -f ${dir}/secretssops.yaml -e direct build || fail "\"helmfile build\" shouldn't fail" - test_pass "secretssops" + test_pass "secretssops.2" fi # ALL DONE ----------------------------------------------------------------------------------------------------------- From 645adefba1c047a1b3e5a6dba016f3ee7079bdf8 Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Tue, 16 Mar 2021 11:47:25 +0300 Subject: [PATCH 19/21] test: return all tests --- test/integration/run.sh | 124 ++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/test/integration/run.sh b/test/integration/run.sh index 71b17523..12ac7c56 100755 --- a/test/integration/run.sh +++ b/test/integration/run.sh @@ -69,68 +69,68 @@ trap "{ $kubectl delete namespace ${test_ns}; }" EXIT # remove namespace wheneve # TEST CASES---------------------------------------------------------------------------------------------------------- -# test_start "happypath - simple rollout of httpbin chart" - -# info "Diffing ${dir}/happypath.yaml" -# bash -c "${helmfile} -f ${dir}/happypath.yaml diff --detailed-exitcode; code="'$?'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile diff" - -# info "Diffing ${dir}/happypath.yaml without color" -# bash -c "${helmfile} -f ${dir}/happypath.yaml --no-color diff --detailed-exitcode; code="'$?'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile diff" - -# info "Diffing ${dir}/happypath.yaml with limited context" -# bash -c "${helmfile} -f ${dir}/happypath.yaml diff --context 3 --detailed-exitcode; code="'$?'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile diff" - -# info "Templating ${dir}/happypath.yaml" -# rm -rf ${dir}/tmp -# ${helmfile} -f ${dir}/happypath.yaml --debug template --output-dir tmp -# code=$? -# [ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile template: ${code}" -# for output in $(ls -d ${dir}/tmp/*); do -# # e.g. test/integration/tmp/happypath-877c0dd4-helmx/helmx -# for release_dir in $(ls -d ${output}/*); do -# release_name=$(basename ${release_dir}) -# golden_dir=${dir}/templates-golden/v${helm_major_version}/${release_name} -# info "Comparing template output ${release_dir}/templates with ${golden_dir}" -# ./diff-yamls ${golden_dir} ${release_dir}/templates || fail "unexpected diff in template result for ${release_name}" -# done -# done - -# info "Applying ${dir}/happypath.yaml" -# bash -c "${helmfile} -f ${dir}/happypath.yaml apply --detailed-exitcode; code="'$?'"; echo Code: "'$code'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile apply" - -# info "Syncing ${dir}/happypath.yaml" -# ${helmfile} -f ${dir}/happypath.yaml sync -# wait_deploy_ready httpbin-httpbin -# retry 5 "curl --fail $(minikube service --url --namespace=${test_ns} httpbin-httpbin)/status/200" -# [ ${retry_result} -eq 0 ] || fail "httpbin failed to return 200 OK" - -# info "Applying ${dir}/happypath.yaml" -# ${helmfile} -f ${dir}/happypath.yaml apply --detailed-exitcode -# code=$? -# [ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile apply: want 0, got ${code}" - -# info "Locking dependencies" -# ${helmfile} -f ${dir}/happypath.yaml deps -# code=$? -# [ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile deps: ${code}" - -# info "Applying ${dir}/happypath.yaml with locked dependencies" -# ${helmfile} -f ${dir}/happypath.yaml apply -# code=$? -# [ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile apply: ${code}" -# ${helm} list --namespace=${test_ns} || fail "unable to list releases" - -# info "Deleting release" -# ${helmfile} -f ${dir}/happypath.yaml delete -# ${helm} status --namespace=${test_ns} httpbin &> /dev/null && fail "release should not exist anymore after a delete" - -# info "Ensuring \"helmfile delete\" doesn't fail when no releases installed" -# ${helmfile} -f ${dir}/happypath.yaml delete || fail "\"helmfile delete\" shouldn't fail when there are no installed releases" - -# info "Ensuring \"helmfile template\" output does contain only YAML docs" -# (${helmfile} -f ${dir}/happypath.yaml template | kubectl apply -f -) || fail "\"helmfile template | kubectl apply -f -\" shouldn't fail" - -# test_pass "happypath" +test_start "happypath - simple rollout of httpbin chart" + +info "Diffing ${dir}/happypath.yaml" +bash -c "${helmfile} -f ${dir}/happypath.yaml diff --detailed-exitcode; code="'$?'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile diff" + +info "Diffing ${dir}/happypath.yaml without color" +bash -c "${helmfile} -f ${dir}/happypath.yaml --no-color diff --detailed-exitcode; code="'$?'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile diff" + +info "Diffing ${dir}/happypath.yaml with limited context" +bash -c "${helmfile} -f ${dir}/happypath.yaml diff --context 3 --detailed-exitcode; code="'$?'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile diff" + +info "Templating ${dir}/happypath.yaml" +rm -rf ${dir}/tmp +${helmfile} -f ${dir}/happypath.yaml --debug template --output-dir tmp +code=$? +[ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile template: ${code}" +for output in $(ls -d ${dir}/tmp/*); do + # e.g. test/integration/tmp/happypath-877c0dd4-helmx/helmx + for release_dir in $(ls -d ${output}/*); do + release_name=$(basename ${release_dir}) + golden_dir=${dir}/templates-golden/v${helm_major_version}/${release_name} + info "Comparing template output ${release_dir}/templates with ${golden_dir}" + ./diff-yamls ${golden_dir} ${release_dir}/templates || fail "unexpected diff in template result for ${release_name}" + done +done + +info "Applying ${dir}/happypath.yaml" +bash -c "${helmfile} -f ${dir}/happypath.yaml apply --detailed-exitcode; code="'$?'"; echo Code: "'$code'"; [ "'${code}'" -eq 2 ]" || fail "unexpected exit code returned by helmfile apply" + +info "Syncing ${dir}/happypath.yaml" +${helmfile} -f ${dir}/happypath.yaml sync +wait_deploy_ready httpbin-httpbin +retry 5 "curl --fail $(minikube service --url --namespace=${test_ns} httpbin-httpbin)/status/200" +[ ${retry_result} -eq 0 ] || fail "httpbin failed to return 200 OK" + +info "Applying ${dir}/happypath.yaml" +${helmfile} -f ${dir}/happypath.yaml apply --detailed-exitcode +code=$? +[ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile apply: want 0, got ${code}" + +info "Locking dependencies" +${helmfile} -f ${dir}/happypath.yaml deps +code=$? +[ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile deps: ${code}" + +info "Applying ${dir}/happypath.yaml with locked dependencies" +${helmfile} -f ${dir}/happypath.yaml apply +code=$? +[ ${code} -eq 0 ] || fail "unexpected exit code returned by helmfile apply: ${code}" +${helm} list --namespace=${test_ns} || fail "unable to list releases" + +info "Deleting release" +${helmfile} -f ${dir}/happypath.yaml delete +${helm} status --namespace=${test_ns} httpbin &> /dev/null && fail "release should not exist anymore after a delete" + +info "Ensuring \"helmfile delete\" doesn't fail when no releases installed" +${helmfile} -f ${dir}/happypath.yaml delete || fail "\"helmfile delete\" shouldn't fail when there are no installed releases" + +info "Ensuring \"helmfile template\" output does contain only YAML docs" +(${helmfile} -f ${dir}/happypath.yaml template | kubectl apply -f -) || fail "\"helmfile template | kubectl apply -f -\" shouldn't fail" + +test_pass "happypath" if [[ helm_major_version -eq 3 ]]; then export VAULT_ADDR=http://127.0.0.1:8200 From b94db61788f5bff1355cfcf3d804970d49ea1fec Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Tue, 16 Mar 2021 11:47:46 +0300 Subject: [PATCH 20/21] feat: make integration/vagrant --- Makefile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Makefile b/Makefile index 936595ea..8ebc3285 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,13 @@ integration: bash test/integration/run.sh .PHONY: integration +integration/vagrant: + $(MAKE) build GOOS=linux GOARCH=amd64 + $(MAKE) build-test-tools GOOS=linux GOARCH=amd64 + vagrant up + vagrant ssh -c 'HELMFILE_HELM3=1 make -C /vagrant integration' +.PHONY: integration/vagrant + cross: env CGO_ENABLED=0 gox -os 'windows darwin linux' -arch '386 amd64 arm64' -osarch '!darwin/arm64 !darwin/386' -output "dist/{{.Dir}}_{{.OS}}_{{.Arch}}" -ldflags '-X github.com/roboll/helmfile/pkg/app/version.Version=${TAG}' ${TARGETS} .PHONY: cross From 82a82b4460f26af90b316855055cec8307548126 Mon Sep 17 00:00:00 2001 From: Andrey Tuzhilin Date: Tue, 16 Mar 2021 12:07:56 +0300 Subject: [PATCH 21/21] test: fix DecryptSecret output --- pkg/helmexec/exec_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/helmexec/exec_test.go b/pkg/helmexec/exec_test.go index 7de18115..318e0b08 100644 --- a/pkg/helmexec/exec_test.go +++ b/pkg/helmexec/exec_test.go @@ -3,7 +3,6 @@ package helmexec import ( "bytes" "fmt" - "github.com/google/go-cmp/cmp" "io" "os" "path" @@ -11,6 +10,8 @@ import ( "reflect" "testing" + "github.com/google/go-cmp/cmp" + "github.com/Masterminds/semver/v3" "go.uber.org/zap" ) @@ -282,8 +283,7 @@ Decrypting secret %s/secretName exec: helm --kube-context dev secrets dec %s/secretName Preparing to decrypt secret %s/secretName Found secret in cache %s/secretName -Decrypted %s/secretName into path/to/temp/file -`, cwd, cwd, cwd, cwd, cwd, cwd) +`, cwd, cwd, cwd, cwd, cwd) if d := cmp.Diff(expected, buffer.String()); d != "" { t.Errorf("helmexec.DecryptSecret(): want (-), got (+):\n%s", d) }