diff --git a/Dockerfile b/Dockerfile index 371afe1..7faa815 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,21 @@ -FROM linkyard/alpine-helm:2.16.6 +FROM alpine/helm:2.14.3 LABEL maintainer "mario.siegenthaler@linkyard.ch" RUN apk add --update --upgrade --no-cache jq bash curl git gettext libintl ENV KUBERNETES_VERSION 1.16.9 +ENV HELMFILE_LATEST_VERSION=0.114.0 RUN curl -L -o /usr/local/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/v${KUBERNETES_VERSION}/bin/linux/amd64/kubectl; \ - chmod +x /usr/local/bin/kubectl - -ADD assets /opt/resource -RUN chmod +x /opt/resource/* + chmod +x /usr/local/bin/kubectl && \ + curl -L -o /usr/local/bin/helmfile https://github.com/roboll/helmfile/releases/download/v${HELMFILE_LATEST_VERSION}/helmfile_linux_amd64 && \ + chmod +x /usr/local/bin/helmfile RUN mkdir -p "$(helm home)/plugins" RUN helm plugin install https://github.com/databus23/helm-diff && \ - helm plugin install https://github.com/rimusz/helm-tiller + helm plugin install https://github.com/rimusz/helm-tiller && \ + helm plugin install https://github.com/fairfaxmedia/helm-git + +ADD assets /opt/resource +RUN chmod +x /opt/resource/* ENTRYPOINT [ "/bin/bash" ] diff --git a/README.md b/README.md index 29292b3..0c79cc8 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,19 @@ on the cluster. * `wait`: *Optional.* Allows deploy task to sleep for X seconds before continuing to next task. Allows pods to restart and become stable, useful where dependency between pods exists. (Default: 0) * `kubeconfig_path`: *Optional.* File containing a kubeconfig. Overrides source configuration for cluster, token, and admin config. +*For Helmfile* + +Params are under the `helmfile` key. +* `enable`: *Optional.* Enable helmfile support. (Default: false) +* `action`: *Optional.* Helmfile command. (Default: apply) +* `file`: *Optional.* Helmfile file. (Default: helmfile.yaml) +* `directory`: *Optional.* The directory name where the helmfile is located. For `helmfile.d` support this is the parent directory. (Default: .) +* `environment`: *Optional.* Helmfile environment name. +* `state_values_file`: *Optional.* Helmfile state value file option. +* `state_values_set`: *Optional.* Helmfile state values set option. +* `selector`: *Optional.* Helmfile selector option. +* `env_vars`: *Optional.* Environment variables to be set before executing helmfile command. + ## Example ### Out @@ -137,3 +150,16 @@ jobs: path: version/image_tag # Read value from version/number type: string # Make sure it's interpreted as a string by Helm (not a number) ``` + +Add to job to use helmfile: + +```yaml +jobs: + # ... + plan: + - put: myapp-helm + params: + helmfile: + enable: true + directory: branch # Parent directory containing the helmfile.d +``` diff --git a/assets/out b/assets/out index f391e64..a7d059a 100755 --- a/assets/out +++ b/assets/out @@ -48,10 +48,23 @@ wait=$(jq -r '.params.wait // 0' < $payload) check_is_ready=$(jq -r '.params.check_is_ready // "false"' < $payload) kubeconfig_namespace=$(jq -r '.source.kubeconfig_namespace // "false"' < $payload) +# helmfile params +hf_enable=$(jq -r '.params.helmfile.enable // "false"' < $payload) +hf_action=$(jq -r '.params.helmfile.action // "apply"' < $payload) +hf_directory=$(jq -r '.params.helmfile.directory // "."' < $payload) +hf_file=$(jq -r '.params.helmfile.file // "helmfile.yaml"' < $payload) +hf_environment=$(jq -r '.params.helmfile.environment // ""' < $payload) +hf_state_values_file=$(jq -r '.params.helmfile.state_values_file // ""' < $payload) +hf_state_values_set=$(jq -r '.params.helmfile.state_values_set // ""' < $payload) +hf_selector=$(jq -r '.params.helmfile.selector // ""' < $payload) +hf_env_vars=$(jq -r '.params.helmfile.env_vars // ""' < $payload) + if [ -z "$chart" ]; then - if [[ "$test" == "false" && "$delete" == "false" ]]; then - echo "invalid payload (missing chart)" - exit 1 + if [ "$hf_enable" = "false" ]; then + if [[ "$test" == "false" && "$delete" == "false" ]]; then + echo "invalid payload (missing chart)" + exit 1 + fi fi fi if [ -f "$source/$namespace_file" ]; then @@ -292,6 +305,66 @@ wait_ready_notice() { fi } +helmfile_action() { + echo "Executing Helmfile function" + echo "hf_enable: ${hf_enable}" + echo "hf_action: ${hf_action}" + echo "hf_directory: ${hf_directory}" + echo "hf_file: ${hf_file}" + echo "hf_environment: ${hf_environment}" + echo "hf_state_values_file: ${hf_state_values_file}" + echo "hf_selector: ${hf_selector}" + echo "hf_env_vars: ${hf_env_vars}" + + if [ -n "$hf_env_vars" ]; then + IFS=' ' read -r -a envvars <<< "${hf_env_vars}" + export "${envvars[@]}" + fi + + apply_args=() + + if [ -n "$hf_directory" ]; then + cd /tmp/build/put/$hf_directory + fi + + if [ ! -d "helmfile.d" ]; then + if [ -n "$hf_file" ]; then + apply_args+=("--file" "$hf_file") + fi + fi + + if [ -n "$hf_environment" ]; then + apply_args+=("--environment" "$hf_environment") + fi + + if [ -n "$namespace" ]; then + apply_args+=("--namespace" "$namespace") + fi + + if [ -n "$hf_state_values_file" ]; then + apply_args+=("--state-values-file" "$hf_state_values_file") + fi + + if [ -n "$hf_state_values_set" ]; then + apply_args+=("--state-values-set" "$hf_state_values_set") + fi + + if [ -n "$hf_selector" ]; then + apply_args+=("--selector" "$hf_selector") + fi + + apply_args+=("$hf_action") + + if [ -n "$values" ]; then + apply_args+=("--values" "$values") + fi + + apply_args+=("--suppress-secrets") + + echo "Arguments: ${apply_args[@]}" + + helmfile "${apply_args[@]}" | tee $logfile +} if [ "$delete" = true ]; then helm_delete @@ -301,12 +374,25 @@ elif [ "$test" = true ]; then helm_test result="$(jq -n "{version:{release:\"$release\", tested: \"true\"}, metadata: [{name: \"release\", value: \"$release\"}]}")" echo "$result" | jq -s add >&3 +elif [ "$hf_enable" = "true" ]; then + helmfile_action + + if [ "$release" = "" ]; then + release=$(${helm_bin} ls -qrd --tiller-namespace $tiller_namespace --max 20 | head -1) + fi + deployed=$(current_deployed "$release") + revision=$(echo $deployed | awk '{ print $1 }') + chart=$(echo $deployed | awk '{ print $8 }') + echo "Deployed revision $revision of $release" + wait_ready_notice + result="$(jq -n "{version:{release:\"$release\", revision:\"$revision\"}, metadata: [{name: \"release\", value: \"$release\"},{name: \"revision\", value: \"$revision\"},{name: \"chart\", value: \"$chart\"}]}")" + echo "$result" | jq -s add >&3 else echo "Installing $release" helm_upgrade if [ "$release" = "" ]; then - release=$(helm ls -qrd --tiller-namespace $tiller_namespace --max 20 | head -1) + release=$(${helm_bin} ls -qrd --tiller-namespace $tiller_namespace --max 20 | head -1) fi deployed=$(current_deployed "$release") revision=$(echo $deployed | awk '{ print $1 }')