travisghansen / argo-cd-helmfile

Integration between argo-cd and helmfile
MIT License
223 stars 55 forks source link

Helmfile custom values.yaml #2

Closed janavenkat closed 3 years ago

janavenkat commented 4 years ago

Currently am facing issues when am trying to use the custom values

here is my helmfile

repositories:
  - name: stable
    url: https://kubernetes-charts.storage.googleapis.com/

releases:
  - name: test-helmfile1
    namespace: default
    chart: stable/docker-registry
    values:
      -  ../pizza-docker/values.yaml

my directory structure

image

Application manifest:

My docker image already have helmfile and argo-cd-helmfile.sh in this path /usr/local/bin

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: test
spec:
  destination:
    namespace: default
    server: 'https://kubernetes.default.svc'
  source:
    path: argocd-helm/papertrail/test
    repoURL: 'git@github.com:xx/xx-demo.git'
    targetRevision: HEAD
    plugin:
      name: helmfile
      env:
        - name: KUBE_VERSION
          value: '1.16'
        - name: HELMFILE_HELMFILE
          value: helmfile.yaml
  project: default

It doesn't work for me. do you have any clue?

and my logs here

ComparisonError
rpc error: code = Unknown desc = `argo-cd-helmfile.sh init` failed exit status 2: + [[ -z init ]] ++ basename /usr/local/bin/argo-cd-helmfile.sh + SCRIPT_NAME=argo-cd-helmfile.sh + [[ -n '' ]] + [[ -n '' ]] + [[ -n '' ]] + phase=init + export HELM_HOME=/tmp/__argo-cd-helmfile.sh__/apps/test + HELM_HOME=/tmp/__argo-cd-helmfile.sh__/apps/test + export HELMFILE_HELMFILE_HELMFILED=/tmp/git@github.com_xx-demo/argocd-helm/papertrail/test/.__argo-cd-helmfile.sh__helmfile.d + HELMFILE_HELMFILE_HELMFILED=/tmp/git@github.com_xxx-demo/argocd-helm/papertrail/test/.__argo-cd-helmfile.sh__helmfile.d + [[ ! -d /tmp/__argo-cd-helmfile.sh__/bin ]] + [[ -n '' ]] ++ which helm + helm=/usr/local/bin/helm + [[ -n '' ]] ++ which helmfile + [[ -n /usr/local/bin/helmfile ]] ++ which helmfile + helmfile=/usr/local/bin/helmfile + helmfile='/usr/local/bin/helmfile --helm-binary /usr/local/bin/helm --no-color --allow-no-matching-release' + [[ -n default ]] + helmfile='/usr/local/bin/helmfile --helm-binary /usr/local/bin/helm --no-color --allow-no-matching-release --namespace default' + [[ -n '' ]] + [[ -v HELMFILE_HELMFILE ]] + helmfile='/usr/local/bin/helmfile --helm-binary /usr/local/bin/helm --no-color --allow-no-matching-release --namespace default -f /tmp/git@github.com_xx_xx-demo/argocd-helm/papertrail/test/.__argo-cd-helmfile.sh__helmfile.d' + HELMFILE_HELMFILE_STRATEGY=REPLACE ++ /usr/local/bin/helm version --short --client ++ cut -d ' ' -f2 + helm_full_version=v3.2.0+ge11b7ce ++ echo v3.2.0+ge11b7ce ++ cut -d . -f1 ++ sed 's/[^0-9]//g' + helm_major_version=3 + export HOME=/tmp/__argo-cd-helmfile.sh__/apps/test + HOME=/tmp/__argo-cd-helmfile.sh__/apps/test ++ /usr/local/bin/helm version --short --client + echoerr v3.2.0+ge11b7ce + printf '%s\n' v3.2.0+ge11b7ce v3.2.0+ge11b7ce ++ /usr/local/bin/helmfile --helm-binary /usr/local/bin/helm --no-color --allow-no-matching-release --namespace default -f /tmp/git@github.com_xxx_xx-demo/argocd-helm/papertrail/test/.__argo-cd-helmfile.sh__helmfile.d --version /usr/local/bin/helmfile: line 1: syntax error near unexpected token `<' /usr/local/bin/helmfile: line 1: `<html><body>You are being <a href="https://github-production-release-asset-2e65be.s3.amazonaws.com/74499101/19b3258b9457abdad?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Credential=&amp;X-Amz-Expires=300&amp;X-Amz-Signature=ced665cfe6a1abee27e24f8ff3a3ge091d&amp;X-Amz-SignedHeaders=host&amp;actor_id=0&amp;repo_id=74499101&amp;response-content-disposition=attachment%3B%20filename%3Dhelmfile_linux_amd64&amp;response-content-type=application%2Foctet-stream">redirected</a>.</body></html>' + echoerr '' + printf '%s\n' '' + case $phase in + echoerr 'starting init' + printf '%s\n' 'starting init' starting init + [[ ! -d /tmp/__argo-cd-helmfile.sh__/apps/test ]] + [[ -v HELMFILE_HELMFILE ]] + rm -rf /tmp/git@github.com_xx-demo/argocd-helm/papertrail/test/.__argo-cd-helmfile.sh__helmfile.d + mkdir -p /tmp/git@github.com_xxxs-demo/argocd-helm/papertrail/test/.__argo-cd-helmfile.sh__helmfile.d + case "${HELMFILE_HELMFILE_STRATEGY}" in + echo helmfile.yaml + [[ ! -d .__argo-cd-helmfile.sh__helmfile.d ]] + [[ 3 -eq 2 ]] + [[ 3 -eq 3 ]] + export HELMFILE_HELM3=1 + HELMFILE_HELM3=1 + /usr/local/bin/helmfile --helm-binary /usr/local/bin/helm --no-color --allow-no-matching-release --namespace default -f /tmp/git@github.com_xxx-demo/argocd-helm/papertrail/test/.__argo-cd-helmfile.sh__helmfile.d repos /usr/local/bin/helmfile: line 1: syntax error near unexpected token `<' /usr/local/bin/helmfile: line 1: `<html><body>You are being <a href="https://github-production-release-asset-2e6de5be.s3.amazonaws.com/7401/19b32580-317f-11eae-9dr4-79b94575bdad?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Credential=equest&amp;X-Amz-Date=20200805T120846Z&amp;X-Amz-Expires=300&amp;X-Amz-Signature=ced665f845bd4adddeec6a1abee27e24f8ff3a3091d&amp;X-Amz-SignedHeaders=host&amp;actor_id=0&amp;repo_id=74499101&amp;response-content-disposition=attachment%3B%20filename%3Dhelmfile_linux_amd64&amp;response-content-type=application%2Foctet-stream">redirected</a>.</body></html>'
2 minutes ago (Wed Aug 05 2020 15:24:31 GMT+0200)

actually values.yaml is location in different path

and also tried the structure like this

image

and also like this

image

both didn't worked

and also HELMFILE_HELMFILE variable not working

travisghansen commented 4 years ago

There appear to be a couple issues at least. The HELMFILE_HELMFILE is actually meant to be the content of a helmfile, not a location. It effectively let’s you store a helmfile in argocd alone without needing a git repo.

In your case, remove the variable completely from the app.

Next, it appears it’s trying to download the helmfile binary. Are you sure the deployment has the binary? And that it’s marked as executable?

Let’s start with those. Especially the env var. Remove it completely and let me know what you see.

janavenkat commented 4 years ago

There appear to be a couple issues at least. The HELMFILE_HELMFILE is actually meant to be the content of a helmfile, not a location. It effectively let’s you store a helmfile in argocd alone without needing a git repo.

In your case, remove the variable completely from the app.

Next, it appears it’s trying to download the helmfile binary. Are you sure the deployment has the binary? And that it’s marked as executable?

Let’s start with those. Especially the env var. Remove it completely and let me know what you see.

Awesome thanks for noting. Made a mistake in my docker now its works well. Am working helmfile with helmsecrets if it goes well in will prepare a PR how to do that

travisghansen commented 4 years ago

Awesome! Note you can use the env var to arbitrarily add a helmfile as well.

janavenkat commented 4 years ago

@travisghansen thanks for the support. I already installed the helm secrets plugin but I do see an error from the script any idea?

Fetching stable/docker-registry Decrypting secret /tmp/git@github.com_s-demo/argocd-helm/papertrail/test/pizza/secrets.yaml in ./helmfile.yaml: helm exited with status 1: Error: unknown command "secrets" for "helm" Run 'helm --help' for usage.

Full log:

rpc error: code = Unknown desc = `argo-cd-helmfile.sh generate` failed exit status 1: + [[ -z generate ]] ++ basename /usr/local/bin/argo-cd-helmfile.sh + SCRIPT_NAME=argo-cd-helmfile.sh + [[ -n '' ]] + [[ -n '' ]] + [[ -n '' ]] + phase=generate + export HELM_HOME=/tmp/__argo-cd-helmfile.sh__/apps/test + HELM_HOME=/tmp/__argo-cd-helmfile.sh__/apps/test + export HELMFILE_HELMFILE_HELMFILED=/tmp/git@github.com_xxx_eks-demo/argocd-helm/papertrail/test/.__argo-cd-helmfile.sh__helmfile.d + HELMFILE_HELMFILE_HELMFILED=/tmp/git@github.com_xxx_eks-demo/argocd-helm/papertrail/test/.__argo-cd-helmfile.sh__helmfile.d + [[ ! -d /tmp/__argo-cd-helmfile.sh__/bin ]] + [[ -n '' ]] ++ which helm + helm=/usr/local/bin/helm + [[ -n '' ]] ++ which helmfile + [[ -n /usr/local/bin/helmfile ]] ++ which helmfile + helmfile=/usr/local/bin/helmfile + helmfile='/usr/local/bin/helmfile --helm-binary /usr/local/bin/helm --no-color --allow-no-matching-release' + [[ -n default ]] + helmfile='/usr/local/bin/helmfile --helm-binary /usr/local/bin/helm --no-color --allow-no-matching-release --namespace default' + [[ -n '' ]] + [[ -v HELMFILE_HELMFILE ]] ++ /usr/local/bin/helm version --short --client ++ cut -d ' ' -f2 + helm_full_version=v3.2.0+ge11b7ce ++ echo v3.2.0+ge11b7ce ++ sed 's/[^0-9]//g' ++ cut -d . -f1 + helm_major_version=3 + export HOME=/tmp/__argo-cd-helmfile.sh__/apps/test + HOME=/tmp/__argo-cd-helmfile.sh__/apps/test ++ /usr/local/bin/helm version --short --client + echoerr v3.2.0+ge11b7ce + printf '%s\n' v3.2.0+ge11b7ce v3.2.0+ge11b7ce ++ /usr/local/bin/helmfile --helm-binary /usr/local/bin/helm --no-color --allow-no-matching-release --namespace default --version + echoerr 'helmfile version v0.98.2' + printf '%s\n' 'helmfile version v0.98.2' helmfile version v0.98.2 + case $phase in + echoerr 'starting generate' + printf '%s\n' 'starting generate' starting generate + INTERNAL_HELMFILE_TEMPLATE_OPTIONS= + INTERNAL_HELM_TEMPLATE_OPTIONS= + [[ 3 -eq 2 ]] + [[ 3 -eq 3 ]] + [[ -n v1,apiregistration.k8s.io/v1,apiregistration.k8s.io/v1beta1,extensions/v1beta1,apps/v1,events.k8s.io/v1beta1,authentication.k8s.io/v1,authentication.k8s.io/v1beta1,authorization.k8s.io/v1,authorization.k8s.io/v1beta1,autoscaling/v1,autoscaling/v2beta1,autoscaling/v2beta2,batch/v1,batch/v1beta1,certificates.k8s.io/v1beta1,networking.k8s.io/v1,networking.k8s.io/v1beta1,policy/v1beta1,rbac.authorization.k8s.io/v1,rbac.authorization.k8s.io/v1beta1,storage.k8s.io/v1,storage.k8s.io/v1beta1,admissionregistration.k8s.io/v1,admissionregistration.k8s.io/v1beta1,apiextensions.k8s.io/v1,apiextensions.k8s.io/v1beta1,scheduling.k8s.io/v1,scheduling.k8s.io/v1beta1,coordination.k8s.io/v1,coordination.k8s.io/v1beta1,node.k8s.io/v1beta1,comcast.github.io/v1,monitoring.coreos.com/v1,velero.io/v1,argoproj.io/v1alpha1,crd.k8s.amazonaws.com/v1alpha1,custom.metrics.k8s.io/v1beta1,external.metrics.k8s.io/v1beta1,metrics.k8s.io/v1beta1 ]] + INTERNAL_HELM_TEMPLATE_OPTIONS=' --api-versions=v1,apiregistration.k8s.io/v1,apiregistration.k8s.io/v1beta1,extensions/v1beta1,apps/v1,events.k8s.io/v1beta1,authentication.k8s.io/v1,authentication.k8s.io/v1beta1,authorization.k8s.io/v1,authorization.k8s.io/v1beta1,autoscaling/v1,autoscaling/v2beta1,autoscaling/v2beta2,batch/v1,batch/v1beta1,certificates.k8s.io/v1beta1,networking.k8s.io/v1,networking.k8s.io/v1beta1,policy/v1beta1,rbac.authorization.k8s.io/v1,rbac.authorization.k8s.io/v1beta1,storage.k8s.io/v1,storage.k8s.io/v1beta1,admissionregistration.k8s.io/v1,admissionregistration.k8s.io/v1beta1,apiextensions.k8s.io/v1,apiextensions.k8s.io/v1beta1,scheduling.k8s.io/v1,scheduling.k8s.io/v1beta1,coordination.k8s.io/v1,coordination.k8s.io/v1beta1,node.k8s.io/v1beta1,comcast.github.io/v1,monitoring.coreos.com/v1,velero.io/v1,argoproj.io/v1alpha1,crd.k8s.amazonaws.com/v1alpha1,custom.metrics.k8s.io/v1beta1,external.metrics.k8s.io/v1beta1,metrics.k8s.io/v1beta1' + /usr/local/bin/helmfile --helm-binary /usr/local/bin/helm --no-color --allow-no-matching-release --namespace default template --skip-deps --args ' --api-versions=v1,apiregistration.k8s.io/v1,apiregistration.k8s.io/v1beta1,extensions/v1beta1,apps/v1,events.k8s.io/v1beta1,authentication.k8s.io/v1,authentication.k8s.io/v1beta1,authorization.k8s.io/v1,authorization.k8s.io/v1beta1,autoscaling/v1,autoscaling/v2beta1,autoscaling/v2beta2,batch/v1,batch/v1beta1,certificates.k8s.io/v1beta1,networking.k8s.io/v1,networking.k8s.io/v1beta1,policy/v1beta1,rbac.authorization.k8s.io/v1,rbac.authorization.k8s.io/v1beta1,storage.k8s.io/v1,storage.k8s.io/v1beta1,admissionregistration.k8s.io/v1,admissionregistration.k8s.io/v1beta1,apiextensions.k8s.io/v1,apiextensions.k8s.io/v1beta1,scheduling.k8s.io/v1,scheduling.k8s.io/v1beta1,coordination.k8s.io/v1,coordination.k8s.io/v1beta1,node.k8s.io/v1beta1,comcast.github.io/v1,monitoring.coreos.com/v1,velero.io/v1,argoproj.io/v1alpha1,crd.k8s.amazonaws.com/v1alpha1,custom.metrics.k8s.io/v1beta1,external.metrics.k8s.io/v1beta1,metrics.k8s.io/v1beta1 ' Fetching stable/docker-registry Decrypting secret /tmp/git@github.com_xxx_eks-demo/argocd-helm/papertrail/test/pizza/secrets.yaml in ./helmfile.yaml: helm exited with status 1: Error: unknown command "secrets" for "helm" Run 'helm --help' for usage.
janavenkat commented 4 years ago

for your reference how secrets is used in helmfile https://github.com/roboll/helmfile/tree/v0.92.1#secrets

travisghansen commented 4 years ago

So from what I can tell, you need to actually install the secrets plugin first.

https://github.com/zendesk/helm-secrets#using-helm-plugin-manager--23x

In init container probably makes the most sense for this. Install the plugin and probably need to import the key somehow as well.

janavenkat commented 4 years ago

Just now with my college managed to fix the issue actually the script tries to create the separate home dir so there is no plugin available. What we did like this

Moved the HOME dir to here

export HELM_HOME="/tmp/__${SCRIPT_NAME}__/apps/${ARGOCD_APP_NAME}"
export HELMFILE_HELMFILE_HELMFILED="${PWD}/.__${SCRIPT_NAME}__helmfile.d"
export HOME="${HELM_HOME}"

and then we modfied the script to install the plugin so here,

if [[ "${HELMFILE_BINARY}" ]]; then
  helmfile="${HELMFILE_BINARY}"
else
  if [[ $(which helmfile) ]]; then
    helmfile="$(which helmfile)"
    output=$(helm plugin install https://github.com/futuresimple/helm-secrets || true)
    if [ $? -ne 0 ]; then
        echo ":x: Failed installing plugin"
        echo "$output"
        exit 1;
    fi
    output1=$(helm2 init --client-only  || true ; helm plugin install https://github.com/futuresimple/helm-secrets  || true)
    if [ $? -ne 0 ]; then
        echo ":x: Failed installing helm2 plugin"
        echo "$output1"
        exit 1;
    fi
  else

Actually we're not logging the plugin error if we did that validation gets failed in ArgoCD.

Actually this fix works :)

Any idea to improve the script welcome :) @travisghansen

Whole script

#!/bin/bash

## specially handled ENV vars
# HELM_BINARY - custom path to helm binary
# HELM_TEMPLATE_OPTIONS - helm template --help
# HELMFILE_BINARY - custom path to helmfile binary
# HELMFILE_GLOBAL_OPTIONS - helmfile --help
# HELMFILE_TEMPLATE_OPTIONS - helmfile template --help
# HELMFILE_HELMFILE - a complete helmfile.yaml (ignores standard helmfile.yaml and helmfile.d if present based on strategy)
# HELMFILE_HELMFILE_STRATEGY - REPLACE or INCLUDE

# NOTE: only 1 -f value/file/dir is used by helmfile, while you can specific -f multiple times
# only the last one matters and all previous -f arguments are irrelevant

# NOTE: helmfile pukes if both helmfile.yaml and helmfile.d are present (and -f isn't explicity used)

## standard build environment
## https://argoproj.github.io/argo-cd/user-guide/build-environment/
# ARGOCD_APP_NAME - name of application
# ARGOCD_APP_NAMESPACE - destination application namespace.
# ARGOCD_APP_REVISION - the resolved revision, e.g. f913b6cbf58aa5ae5ca1f8a2b149477aebcbd9d8
# ARGOCD_APP_SOURCE_PATH - the path of the app within the repo
# ARGOCD_APP_SOURCE_REPO_URL the repo's URL
# ARGOCD_APP_SOURCE_TARGET_REVISION - the target revision from the spec, e.g. master.

# each manifest generation cycle calls git reset/clean before (between init and generate it is NOT ran)
# init is called before every manifest generation
# it can be used to download dependencies, etc, etc

# does not have "v" in front
# KUBE_VERSION="<major>.<minor>"
# KUBE_API_VERSIONS="v1,apps/v1,..."

set -e
set -x

echoerr() { printf "%s\n" "$*" >&2; }

# https://unix.stackexchange.com/questions/294835/replace-environment-variables-in-a-file-with-their-actual-values
variable_expansion() {
  # prefer envsubst if available, fallback to perl
  if [[ $(which envsubst) ]]; then
    echo -n "${@}" | envsubst
  else
    echo -n "${@}" | perl -pe 's/\$(\{)?([a-zA-Z_]\w*)(?(1)\})/$ENV{$2}/g'
  fi
}

# exit immediately if no phase is passed in
if [[ -z "${1}" ]]; then
  echoerr "invalid invocation"
  exit 1
fi

SCRIPT_NAME=$(basename "${0}")

# expand nested variables
if [[ "${HELMFILE_GLOBAL_OPTIONS}" ]]; then
  HELMFILE_GLOBAL_OPTIONS=$(variable_expansion "${HELMFILE_GLOBAL_OPTIONS}")
fi

if [[ "${HELMFILE_TEMPLATE_OPTIONS}" ]]; then
  HELMFILE_TEMPLATE_OPTIONS=$(variable_expansion "${HELMFILE_TEMPLATE_OPTIONS}")
fi

if [[ "${HELM_TEMPLATE_OPTIONS}" ]]; then
  HELM_TEMPLATE_OPTIONS=$(variable_expansion "${HELM_TEMPLATE_OPTIONS}")
fi

phase=$1

# setup the env
# HELM_HOME is deprecated with helm-v3, uses XDG dirs
export HELM_HOME="/tmp/__${SCRIPT_NAME}__/apps/${ARGOCD_APP_NAME}"
export HELMFILE_HELMFILE_HELMFILED="${PWD}/.__${SCRIPT_NAME}__helmfile.d"
export HOME="${HELM_HOME}"

if [[ ! -d "/tmp/__${SCRIPT_NAME}__/bin" ]]; then
  mkdir -p "/tmp/__${SCRIPT_NAME}__/bin"
fi

# set binary paths and base options
if [[ "${HELM_BINARY}" ]]; then
  helm="${HELM_BINARY}"
else
  helm="$(which helm)"
fi

if [[ "${HELMFILE_BINARY}" ]]; then
  helmfile="${HELMFILE_BINARY}"
else
  if [[ $(which helmfile) ]]; then
    helmfile="$(which helmfile)"
    output=$(helm plugin install https://github.com/futuresimple/helm-secrets || true)
    if [ $? -ne 0 ]; then
        echo ":x: Failed installing plugin"
        echo "$output"
        exit 1;
    fi
    output1=$(helm2 init --client-only  || true ; helm plugin install https://github.com/futuresimple/helm-secrets  || true)
    if [ $? -ne 0 ]; then
        echo ":x: Failed installing helm2 plugin"
        echo "$output1"
        exit 1;
    fi
  else
    LOCAL_HELMFILE_BINARY="/tmp/__${SCRIPT_NAME}__/bin/helmfile"
    if [[ ! -x "${LOCAL_HELMFILE_BINARY}" ]]; then
      wget -O "${LOCAL_HELMFILE_BINARY}" "https://github.com/roboll/helmfile/releases/download/v0.98.2/helmfile_linux_amd64"
      chmod +x "${LOCAL_HELMFILE_BINARY}"
    fi
    helmfile="${LOCAL_HELMFILE_BINARY}"
  fi
fi

helmfile="${helmfile} --helm-binary ${helm} --no-color --allow-no-matching-release"

if [[ "${ARGOCD_APP_NAMESPACE}" ]]; then
  helmfile="${helmfile} --namespace ${ARGOCD_APP_NAMESPACE}"
fi

if [[ "${HELMFILE_GLOBAL_OPTIONS}" ]]; then
  helmfile="${helmfile} ${HELMFILE_GLOBAL_OPTIONS}"
fi

if [[ -v HELMFILE_HELMFILE ]]; then
  helmfile="${helmfile} -f ${HELMFILE_HELMFILE_HELMFILED}"
  HELMFILE_HELMFILE_STRATEGY=${HELMFILE_HELMFILE_STRATEGY:=REPLACE}
fi

# these should work for both v2 and v3
helm_full_version=$(${helm} version --short --client | cut -d " " -f2)
helm_major_version=$(echo "${helm_full_version}" | cut -d "." -f1 | sed 's/[^0-9]//g')

# set home variable to ensure apps do NOT overlap settings/repos/etc
#export HOME="${HELM_HOME}"

echoerr "$(${helm} version --short --client)"
echoerr "$(${helmfile} --version)"

case $phase in
  "init")
    echoerr "starting init"

    # ensure dir(s)
    # rm -rf "${HELM_HOME}"
    if [[ ! -d "${HELM_HOME}" ]]; then
      mkdir -p "${HELM_HOME}"
    fi

    if [[ -v HELMFILE_HELMFILE ]]; then
      rm -rf "${HELMFILE_HELMFILE_HELMFILED}"
      mkdir -p "${HELMFILE_HELMFILE_HELMFILED}"

      case "${HELMFILE_HELMFILE_STRATEGY}" in
        "INCLUDE")
          if [[ -f "helmfile.yaml" && -d "helmfile.d" ]]; then
            echoerr "configuration conlict error: you can have either helmfile.yaml or helmfile.d, but not both"
          fi

          if [[ -f "helmfile.yaml" ]]; then
            cp -a "helmfile.yaml" "${HELMFILE_HELMFILE_HELMFILED}/"
          fi

          if [[ -d "helmfile.d" ]]; then
            cp -ar "helmfile.d/"* "${HELMFILE_HELMFILE_HELMFILED}/"
          fi
          ;;
        "REPLACE") ;;

        *)
          echoerr "invalid \$HELMFILE_HELMFILE_STRATEGY: ${HELMFILE_HELMFILE_STRATEGY}"
          exit 1
          ;;
      esac

      # ensure custom file is processed last
      echo "${HELMFILE_HELMFILE}" >"${HELMFILE_HELMFILE_HELMFILED}/ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ__argocd__helmfile__.yaml"
    fi

    if [[ ! -d ".__${SCRIPT_NAME}__helmfile.d" ]]; then
      mkdir -p "${HELM_HOME}"
    fi

    if [[ ${helm_major_version} -eq 2 ]]; then
      ${helm} init --client-only
    fi

    if [[ ${helm_major_version} -eq 3 ]]; then
      # https://github.com/roboll/helmfile/issues/1015#issuecomment-563488649
      export HELMFILE_HELM3="1"
    fi

    # https://github.com/roboll/helmfile/issues/1064
    ${helmfile} repos
    ;;

  "generate")
    echoerr "starting generate"

    INTERNAL_HELMFILE_TEMPLATE_OPTIONS=
    INTERNAL_HELM_TEMPLATE_OPTIONS=

    # helmfile args
    # --environment default, -e default       specify the environment name. defaults to default
    # --namespace value, -n value             Set namespace. Uses the namespace set in the context by default, and is available in templates as {{ .Namespace }}
    # --selector value, -l value              Only run using the releases that match labels. Labels can take the form of foo=bar or foo!=bar.
    #                                         A release must match all labels in a group in order to be used. Multiple groups can be specified at once.
    #                                         --selector tier=frontend,tier!=proxy --selector tier=backend. Will match all frontend, non-proxy releases AND all backend releases.
    #                                         The name of a release can be used as a label. --selector name=myrelease
    # --allow-no-matching-release             Do not exit with an error code if the provided selector has no matching releases.

    # apply custom args passed from helmfile down to helm
    # https://github.com/helm/helm/pull/7054/files (--is-upgrade added to v3)
    # --args --kube-version=1.16,--api-versions=foo
    #
    # v2
    # --is-upgrade               set .Release.IsUpgrade instead of .Release.IsInstall
    # --kube-version string      kubernetes version used as Capabilities.KubeVersion.Major/Minor (default "1.9")
    # v3
    # -a, --api-versions stringArray   Kubernetes api versions used for Capabilities.APIVersions
    # --no-hooks                   prevent hooks from running during install
    # --skip-crds                  if set, no CRDs will be installed. By default, CRDs are installed if not already present

    if [[ ${helm_major_version} -eq 2 && "${KUBE_VERSION}" ]]; then
      INTERNAL_HELM_TEMPLATE_OPTIONS="${INTERNAL_HELM_TEMPLATE_OPTIONS} --kube-version=${KUBE_VERSION}"
    fi

    if [[ ${helm_major_version} -eq 3 && "${KUBE_API_VERSIONS}" ]]; then
      INTERNAL_HELM_TEMPLATE_OPTIONS="${INTERNAL_HELM_TEMPLATE_OPTIONS} --api-versions=${KUBE_API_VERSIONS}"
    fi

    ${helmfile} \
      template \
      --skip-deps ${INTERNAL_HELMFILE_TEMPLATE_OPTIONS} \
      --args "${INTERNAL_HELM_TEMPLATE_OPTIONS} ${HELM_TEMPLATE_OPTIONS}" \
      ${HELMFILE_TEMPLATE_OPTIONS}
    ;;

  *)
    echoerr "invalid invocation"
    exit 1
    ;;
esac
travisghansen commented 4 years ago

Cool I’ll have a look. How are you importing the key? Did you get it to fully work end to end with your use case?

janavenkat commented 4 years ago

No need to imported the key, Encrypted file is stored in git and helmfile will decrypt the secret during template. We just need to give AWS User KMS permission for the pod repo-server.

travisghansen commented 4 years ago

Hmm. Let me understand the key side a little better.

In the interim, maybe we should allow an env var that allows arbitrary commands to be executed...but perhaps the security implications of that are too high. In which case a new dedicated feature as you have done would be appropriate.

In any case, I think it’s generally a great feature and should be supported by the script.

janavenkat commented 4 years ago

Hmm. Let me understand the key side a little better.

In the interim, maybe we should allow an env var that allows arbitrary commands to be executed...but perhaps the security implications of that are too high. In which case a new dedicated feature as you have done would be appropriate.

In any case, I think it’s generally a great feature and should be supported by the script.

Yeah indeed. If you need any help from my side let me know

janavenkat commented 4 years ago

@travisghansen is it possible to set the custom helmfile name?

janavenkat commented 4 years ago

@travisghansen found another issue. It's not template the correct chart versions its always uses the latest chart version.

Ex: helmfile

repositories:
  - name: stable
    url: https://kubernetes-charts.storage.googleapis.com/

releases:
  - name: test-helmfile1
    namespace: default
    chart: stable/docker-registry
    version: 1.9.2

Actually I want to use chart version 1.9.2 but its using the latest version 1.9.4

from helmfile side its work's fine but something is wrong with the script

travisghansen commented 4 years ago

Custom helmfile name? Are you referring to the ability to add a helmfile via the env var? What’s the use case for changing the name of it?

Regarding using the incorrect version I’m not sure how that would be possible. If anything it’s a bug in helmfile as all the script does is execute helmfile. Did you attempt to use template vs install to ensure it was using the right versions?

janavenkat commented 4 years ago

You can check the default behavior like this

helmfile.yaml

releases:
  - name: test-helmfile1
    namespace: default
    chart: stable/docker-registry
    version: 1.9.2

Am here using helm3 binary

helmfile --helm-binary helm3 template

Output should use 1.9.2 version

example:

kind: ConfigMap
metadata:
  name: test-helmfile1-docker-registry-config
  labels:
    app: docker-registry
    chart: docker-registry-1.9.2
    heritage: Helm
    release: test-helmfile1

Create same one with the script in ArgoCD

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: test
spec:
  destination:
    namespace: default
    server: 'https://kubernetes.default.svc'
  source:
    path: argocd-helm/papertrail/test
    repoURL: 'git@github.com:xxx/xx-demo.git'
    targetRevision: HEAD
    plugin:
      name: helmfile
  project: default

ArgoCD Picks the latest version I think as we using template in that we should pass the parameter version

travisghansen commented 4 years ago

That's pretty strange. Which versions of helm and helmfile are you using? I'll try it out..

janavenkat commented 4 years ago

In ArgoCD its uses

helm2 
and
helmfile version v0.125.4
travisghansen commented 4 years ago

What version of helm2? Do you know?

janavenkat commented 4 years ago

not sure am using ArgoCD 1.6.1

janavenkat commented 4 years ago

@travisghansen actually helm 2 its not having the argument for--versionin the template but helm 3 does. I solved the issue by using helm 3 using this variable HELM_BINARY

travisghansen commented 4 years ago

That’s really strange. Helm 2 does support specifying a specific version of the chart..I’m wondering if it’s a bug introduced in helmfile somehow...

janavenkat commented 4 years ago

@travisghansen can you provide the possibility to pass the custom helmfile name

travisghansen commented 4 years ago

What’s the use-case for the custom name? Are you referring to the env var that supplies the full content of a helmfile?

janavenkat commented 4 years ago

my use case is different I would like to pass the custom helmfile name

travisghansen commented 4 years ago

Oh, maybe I understand better. You have a repo with with several helmfiles in a flat directory and you want to selectively pick which file to use on a per argo-cd app basis?

janavenkat commented 4 years ago

to reproduce the --version issue

Helmfile.yaml

helmDefaults:
  kubeContext: eks-ticketswap-pizza

repositories:
  - name: bitnami
    url: https://charts.bitnami.com/bitnami

releases:
  - name: external-dns
    namespace: kube-system
    chart: bitnami/external-dns
    version: 3.2.5

Using Helm 3 as binary helmfile --helm-binary helm3 template

Output

Adding repo bitnami https://charts.bitnami.com/bitnami
"bitnami" has been added to your repositories

Templating release=external-dns, chart=bitnami/external-dns
---
# Source: external-dns/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: external-dns
  labels:
    app.kubernetes.io/name: external-dns
    helm.sh/chart: external-dns-3.2.5
    app.kubernetes.io/instance: external-dns
    app.kubernetes.io/managed-by: Helm
---
# Source: external-dns/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: external-dns
  labels:
    app.kubernetes.io/name: external-dns
    helm.sh/chart: external-dns-3.2.5
    app.kubernetes.io/instance: external-dns
    app.kubernetes.io/managed-by: Helm
rules:
 xxx
---
# Source: external-dns/templates/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: external-dns
  labels:
    app.kubernetes.io/name: external-dns
    helm.sh/chart: external-dns-3.2.5
    app.kubernetes.io/instance: external-dns
    app.kubernetes.io/managed-by: Helm
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: external-dns
subjects:
  - kind: ServiceAccount
    name: external-dns
    namespace: kube-system
---
# Source: external-dns/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: external-dns
  labels:
    app.kubernetes.io/name: external-dns
    helm.sh/chart: external-dns-3.2.5
    app.kubernetes.io/instance: external-dns
    app.kubernetes.io/managed-by: Helm
spec:
  ports:
    - name: http
      port: 7979
      protocol: TCP
      targetPort: http
  selector:
    app.kubernetes.io/name: external-dns
    app.kubernetes.io/instance: external-dns
  type: ClusterIP
---
# Source: external-dns/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: external-dns
  labels:
    app.kubernetes.io/name: external-dns
    helm.sh/chart: external-dns-3.2.5
    app.kubernetes.io/instance: external-dns
    app.kubernetes.io/managed-by: Helm
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: external-dns
      app.kubernetes.io/instance: external-dns
  template:
    metadata:
      labels:
        app.kubernetes.io/name: external-dns
        helm.sh/chart: external-dns-3.2.5
        app.kubernetes.io/instance: external-dns
        app.kubernetes.io/managed-by: Helm
      annotations:
    spec:
      securityContext:
        fsGroup: 1001
        runAsUser: 1001
      serviceAccountName: external-dns
      containers:
        - name: external-dns
          image: "docker.io/bitnami/external-dns:0.7.2-debian-10-r46"
          imagePullPolicy: "IfNotPresent"
xxx

Using Helm 2 as binary helmfile --helm-binary helm template

Adding repo bitnami https://charts.bitnami.com/bitnami
"bitnami" has been added to your repositories

Fetching bitnami/external-dns
Templating release=external-dns, chart=/var/folders/hq/3d1k5z_905j20hszf5_0z9tm0000gn/T/162799306/kube-system/external-dns/bitnami/external-dns/3.2.5/external-dns
in ./helmfile.yaml: command "/usr/local/bin/helm" exited with non-zero status:

PATH:
  /usr/local/bin/helm

ARGS:
  0: helm (4 bytes)
  1: --kube-context (14 bytes)
xxxxxx
  3: template (8 bytes)
  4: /var/folders/hq/3d1k5z_905j20hszf5_0z9tm0000gn/T/162799306/kube-system/external-dns/bitnami/external-dns/3.2.5/external-dns (123 bytes)
  5: --name (6 bytes)
  6: external-dns (12 bytes)
  7: --version (9 bytes)
  8: 3.2.5 (5 bytes)
  9: --namespace (11 bytes)
  10: kube-system (11 bytes)
  11: --values (8 bytes)
  12: /var/folders/hq/3d1k5z_905j20hszf5_0z9tm0000gn/T/values991617953 (64 bytes)
  13: --values (8 bytes)
  14: /var/folders/hq/3d1k5z_905j20hszf5_0z9tm0000gn/T/values983934092 (64 bytes)
  15: --values (8 bytes)
  16: /var/folders/hq/3d1k5z_905j20hszf5_0z9tm0000gn/T/values043776635 (64 bytes)
  17: --values (8 bytes)
  18: /var/folders/hq/3d1k5z_905j20hszf5_0z9tm0000gn/T/values110668190 (64 bytes)

ERROR:
  exit status 1

EXIT STATUS
  1

STDERR:
  Error: unknown flag: --version

COMBINED OUTPUT:
  Error: unknown flag: --version
janavenkat commented 4 years ago

Oh, maybe I understand better. You have a repo with with several helmfiles in a flat directory and you want to selectively pick which file to use on a per argo-cd app basis?

Yeah exactly

travisghansen commented 4 years ago

I’ll try out your example...that seems really crazy to me. What version of helm2 is it?

It should already support setting a custom file like that. Try to add —file to the HELMFILE_GLOBAL_OPTIONS env var and see if it works.

travisghansen commented 3 years ago

Arbitrary scripts are allowed by helmfile itself. I have therefore gone ahead and allowed arbitrary scripts to be executed by this plugin as well along with better support for helm plugins generally.

https://github.com/travisghansen/argo-cd-helmfile/commit/0bff2e3f07ac967f33649608ff42f95326639ee4