fix: split client.sls into distinct, dedicated SLS files

Additionally export a `constants` dict from the `map.jinja` to handle
any shared or verbose constants — such as file paths, environment
variables, etc… — and make the individual SLS files more concise. Also,
fix a minor logic issue introduced in commit c42a332 that would not
reference the kubectl configuration managed by this formula if the
kubectl binary is not installed by the formula.

Fixes salt-formulas/salt-formula-helm#8
diff --git a/README.rst b/README.rst
index b3e830f..91bb364 100644
--- a/README.rst
+++ b/README.rst
@@ -18,14 +18,9 @@
 _The following examples demonstrate configuring the formula for different
 use cases._
 
-Enable formula, install helm client on node and tiller on Kubernetes (assuming
-already configured kubectl config or local cluster endpoint):
-
-.. code-block:: yaml
-
-    helm:
-      client:
-        enabled: true
+The default pillar configuration will install the helm client on the target 
+node, and Tiller to the Kubernetes cluster (assuming kubectl config or local 
+cluster endpoint have already been configured.
 
 Change version of helm being downloaded and installed:
 
diff --git a/helm/client.sls b/helm/client.sls
deleted file mode 100644
index 5ed5d92..0000000
--- a/helm/client.sls
+++ /dev/null
@@ -1,232 +0,0 @@
-{%- from "helm/map.jinja" import client with context %}
-{%- if client.enabled %}
-
-{%- set helm_tmp = "/tmp/helm-v" + client.version %}
-{%- set helm_bin = "/usr/bin/helm-v" + client.version %}
-{%- set kubectl_bin = "/usr/bin/kubectl" %}
-{%- set kube_config = "/srv/helm/kubeconfig.yaml" %}
-
-{%- set gce_service_token = None %}
-{%- set gce_env_var = "" %}
-{%- set gce_state_arg = "" %}
-{%- set gce_require = "" %}
-{%- if client.kubectl.install and 
-       "gce_service_token" in client.kubectl.config %}
-{%- set gce_service_token = client.kubectl.config.gce_service_token %}
-{%- set gce_service_token_path = "/srv/helm/gce_token.json" %}
-{%- set gce_env_var = "- GOOGLE_APPLICATION_CREDENTIALS: \"{}\"".format(gce_service_token_path) %}
-{%- set gce_state_arg = "- gce_service_token: \"{}\"".format(gce_service_token_path) %}
-{%- set gce_require = "- file: \"{}\"".format(gce_service_token_path) %}
-{%- endif %}
-
-{%- set helm_home = "/srv/helm/home" %}
-{%- if "host" in client.tiller %}
-{%- set helm_run = "helm --host '{}'".format(client.tiller.host) %}
-{%- set tiller_arg = "- tiller_host: \"{}\"".format(client.tiller.host) %}
-{%- else %}
-{%- set helm_run = "helm --tiller-namespace '{}'".format(client.tiller.namespace) %}
-{%- set tiller_arg = "- tiller_namespace: \"{}\"".format(client.tiller.namespace) %}
-{%- endif %}
-
-{{ helm_tmp }}:
-  file.directory:
-    - user: root
-    - group: root
-  archive.extracted:
-    - source: https://storage.googleapis.com/kubernetes-helm/helm-v{{ client.version }}-linux-amd64.tar.gz
-    - source_hash: {{ client.download_hash }}
-    - archive_format: tar
-    {%- if grains['saltversioninfo'] < [2016, 11] %}
-    - tar_options: v
-    {%- else %}
-    - options: v
-    {%- endif %}
-    - if_missing: {{ helm_tmp }}/linux-amd64/helm
-    - require:
-      - file: {{ helm_tmp }}
-
-{{ helm_bin }}:
-  file.managed:
-    - source: {{ helm_tmp }}/linux-amd64/helm
-    - mode: 555
-    - user: root
-    - group: root
-    - require:
-      - archive: {{ helm_tmp }}
-
-/usr/bin/helm:
-  file.symlink:
-    - target: helm-v{{ client.version }}
-    - require:
-      - file: {{ helm_bin }}
-
-prepare_client:
-  cmd.run:
-    - name: {{ helm_run }} init --client-only
-    - env:
-      - HELM_HOME: {{ helm_home }}
-    - unless: test -d {{ helm_home }}
-    - require:
-      - file: /usr/bin/helm
-
-{%- if client.kubectl.install %}
-{{ kube_config }}:
-  file.managed:
-    - source: salt://helm/files/kubeconfig.yaml.j2
-    - mode: 400
-    - user: root
-    - group: root
-    - template: jinja
-
-{%- if gce_service_token %}
-{{ gce_service_token_path }}:
-  file.managed:
-    - source: salt://helm/files/gce_token.json.j2
-    - mode: 400
-    - user: root
-    - group: root
-    - template: jinja
-    - context:
-        content: {{ gce_service_token }}
-{%- endif %}{# gce_service_token #}
-
-extract_kubectl:
-  archive.extracted:
-    - name: {{ helm_tmp }}/kubectl/v{{ client.kubectl.version }}
-    - source: https://dl.k8s.io/v{{ client.kubectl.version }}/kubernetes-client-linux-amd64.tar.gz
-    - source_hash: {{ client.kubectl.download_hash }}
-    - archive_format: tar
-    {%- if grains['saltversioninfo'] < [2016, 11] %}
-    - tar_options: v
-    {%- else %}
-    - options: v
-    {%- endif %}
-    - if_missing: {{ helm_tmp }}/kubectl/v{{ client.kubectl.version }}
-    - require:
-      - file: {{ helm_tmp }}
-
-{{ kubectl_bin }}:
-  file.managed:
-    - source: {{ helm_tmp }}/kubectl/v{{ client.kubectl.version }}/kubernetes/client/bin/kubectl
-    - mode: 555
-    - user: root
-    - group: root
-    - require:
-      - archive: extract_kubectl
-{%- endif %}{# client.kubectl.install #}
-
-helm_env_home_param:
-   environ.setenv:
-   - name: HELM_HOME
-   - value: {{ helm_home }}
-   - update_minion: True
-
-helm_env_kubeconfig_param:
-   environ.setenv:
-   - name: KUBECONFIG
-   - value: {{ kube_config }}
-   - update_minion: True
-   - require:
-     - environ: helm_env_home_param
-
-{%- if client.tiller.install %}
-install_tiller:
-  cmd.run:
-    - name: {{ helm_run }} init --upgrade
-    - env:
-      - HELM_HOME: {{ helm_home }}
-      {%- if client.kubectl.install %}
-      - KUBECONFIG: {{ kube_config }}
-      {%- endif %}
-      {{ gce_env_var }}
-    - unless: "{{ helm_run }} version --server --short | grep -E 'Server: v{{ client.version }}(\\+|$)'"
-    - require:
-      - cmd: prepare_client
-      {%- if client.kubectl.install %}
-      - file: {{ kube_config }}
-      - environ: helm_env_kubeconfig_param
-      {%- endif %}
-      {{ gce_require }}
-
-wait_for_tiller:
-  cmd.run:
-    - name: while ! {{ helm_run }} list; do sleep 3; done
-    - timeout: 30
-    - env:
-      - HELM_HOME: {{ helm_home }}
-      {%- if client.kubectl.install %}
-      - KUBECONFIG: {{ kube_config }}
-      {%- endif %}
-      {{ gce_env_var }}
-    {%- if client.kubectl.install or gce_require != "" %}
-    - require:
-      {%- if client.kubectl.install %}
-      - file: {{ kube_config }}
-      {%- endif %}
-      {{ gce_require }}
-    {%- endif %}
-    - onchanges:
-      - cmd: install_tiller
-{%- endif %}
-
-{%- if "repos" in client %}
-{%- for repo_name, repo_url in client.repos.items() %}
-ensure_{{ repo_name }}_repo:
-  cmd.run:
-    - name: {{ helm_run }} repo add {{ repo_name }} {{ repo_url }}
-    - env:
-      - HELM_HOME: {{ helm_home }}
-    - unless: {{ helm_run }} repo list | grep '^{{ repo_name }}[[:space:]]{{ repo_url|replace(".", "\.") }}'
-    - require:
-      - cmd: prepare_client
-{%- endfor %}
-{%- endif %}{# "repos" in client #}
-
-{%- if "releases" in client %}
-{%- for release_id, release in client.releases.items() %}
-{%- set release_name = release.get('name', release_id) %}
-{%- set namespace = release.get('namespace', 'default') %}
-{%- if release.get('enabled', True) %}
-ensure_{{ release_id }}_release:
-  helm_release.present:
-    - name: {{ release_name }}
-    - chart_name: {{ release['chart'] }}
-    - namespace: {{ namespace }}
-    {% if client.kubectl.install %}
-    - kube_config: {{ kube_config }}
-    {% endif %}
-    {{ tiller_arg }}
-    {{ gce_state_arg }}
-    {%- if release.get('version') %}
-    - version: {{ release['version'] }}
-    {%- endif %}
-    {%- if release.get('values') %}
-    - values:
-        {{ release['values']|yaml(False)|indent(8) }}
-    {%- endif %}
-    - require:
-{%- if client.tiller.install %}
-      - cmd: wait_for_tiller
-{%- endif %}
-      {{ gce_require }}
-{%- else %}{# not release.enabled #}
-absent_{{ release_id }}_release:
-  helm_release.absent:
-    - name: {{ release_name }}
-    - namespace: {{ namespace }}
-    {% if client.kubectl.install %}
-    - kube_config: {{ kube_config }}
-    {% endif %}
-    {{ tiller_arg }}
-    {{ gce_state_arg }}
-    - require:
-{%- if client.tiller.install %}
-      - cmd: wait_for_tiller
-{%- endif %}
-      {{ gce_require }}
-      - cmd: prepare_client
-{%- endif %}{# release.enabled #}
-{%- endfor %}{# release_id, release in client.releases #}
-{%- endif %}{# "releases" in client #}
-
-{%- endif %}
diff --git a/helm/client_installed.sls b/helm/client_installed.sls
new file mode 100644
index 0000000..c632b52
--- /dev/null
+++ b/helm/client_installed.sls
@@ -0,0 +1,45 @@
+{%- from slspath + "/map.jinja" import config, constants with context %}
+
+include:
+  - .kubectl_installed
+
+{{ constants.helm.tmp }}:
+  file.directory:
+    - user: root
+    - group: root
+  archive.extracted:
+    - source: https://storage.googleapis.com/kubernetes-helm/helm-v{{ config.version }}-linux-amd64.tar.gz
+    - source_hash: {{ config.download_hash }}
+    - archive_format: tar
+    {%- if grains['saltversioninfo'] < [2016, 11] %}
+    - tar_options: v
+    {%- else %}
+    - options: v
+    {%- endif %}
+    - if_missing: {{ constants.helm.tmp }}/linux-amd64/helm
+    - require:
+      - file: {{ constants.helm.tmp }}
+
+{{ constants.helm.bin }}:
+  file.managed:
+    - source: {{ constants.helm.tmp }}/linux-amd64/helm
+    - mode: 555
+    - user: root
+    - group: root
+    - require:
+      - archive: {{ constants.helm.tmp }}
+
+/usr/bin/helm:
+  file.symlink:
+    - target: helm-v{{ config.version }}
+    - require:
+      - file: {{ constants.helm.bin }}
+
+prepare_client:
+  cmd.run:
+    - name: {{ constants.helm.cmd }} init --client-only
+    - env:
+      - HELM_HOME: {{ constants.helm.home }}
+    - unless: test -d {{ constants.helm.home }}
+    - require:
+      - file: {{ constants.helm.bin }}
diff --git a/helm/init.sls b/helm/init.sls
index 28c9200..8bf21e6 100644
--- a/helm/init.sls
+++ b/helm/init.sls
@@ -1,6 +1,4 @@
 {%- if pillar.helm is defined %}
 include:
-{%- if pillar.helm.client is defined %}
-- helm.client
-{%- endif %}
+  - .releases_managed
 {%- endif %}
diff --git a/helm/kubectl_configured.sls b/helm/kubectl_configured.sls
new file mode 100644
index 0000000..fbe2c48
--- /dev/null
+++ b/helm/kubectl_configured.sls
@@ -0,0 +1,32 @@
+{%- from slspath + "/map.jinja" import config, constants with context %}
+
+include:
+  - .kubectl_installed
+
+{{ constants.kubectl.config }}:
+  file.managed:
+    - source: salt://helm/files/kubeconfig.yaml.j2
+    - mode: 400
+    - user: root
+    - group: root
+    - template: jinja
+    {%- if config.kubectl.install %}
+    - require:
+        - sls: {{ slspath }}.kubectl_installed
+    {%- endif %}
+
+{%- if config.kubectl.config.gce_service_token %}
+{{ constants.gce_service_token_path }}:
+  file.managed:
+    - source: salt://helm/files/gce_token.json.j2
+    - mode: 400
+    - user: root
+    - group: root
+    - template: jinja
+    - context:
+        content: {{ config.kubectl.config.gce_service_token }}
+    {%- if config.kubectl.install %}
+    - require:
+        - sls: {{ slspath }}.kubectl_installed
+    {%- endif %}
+{%- endif %}{# gce_service_token #}
\ No newline at end of file
diff --git a/helm/kubectl_installed.sls b/helm/kubectl_installed.sls
new file mode 100644
index 0000000..298c8e9
--- /dev/null
+++ b/helm/kubectl_installed.sls
@@ -0,0 +1,27 @@
+{%- from slspath + "/map.jinja" import config, constants with context %}
+
+{%- if config.kubectl.install %}
+extract_kubectl:
+  archive.extracted:
+    - name: {{ constants.helm.tmp }}/kubectl/v{{ config.kubectl.version }}
+    - source: https://dl.k8s.io/v{{ config.kubectl.version }}/kubernetes-client-linux-amd64.tar.gz
+    - source_hash: {{ config.kubectl.download_hash }}
+    - archive_format: tar
+    {%- if grains['saltversioninfo'] < [2016, 11] %}
+    - tar_options: v
+    {%- else %}
+    - options: v
+    {%- endif %}
+    - if_missing: {{ constants.helm.tmp }}/kubectl/v{{ config.kubectl.version }}
+    - require:
+      - file: {{ constants.helm.tmp }}
+
+{{ constants.kubectl.bin }}:
+  file.managed:
+    - source: {{ constants.helm.tmp }}/kubectl/v{{ config.kubectl.version }}/kubernetes/client/bin/kubectl
+    - mode: 555
+    - user: root
+    - group: root
+    - require:
+      - archive: extract_kubectl
+{%- endif %}
\ No newline at end of file
diff --git a/helm/map.jinja b/helm/map.jinja
index 5eef827..3c8e70c 100644
--- a/helm/map.jinja
+++ b/helm/map.jinja
@@ -1,4 +1,3 @@
-
 {%- set source_engine = salt['pillar.get']('helm:client:source:engine') %}
 
 {%- load_yaml as base_defaults %}
@@ -29,18 +28,64 @@
 {%- load_yaml as base_config %}
 helm:
   client:
-    enabled: true
     version: 2.6.2
     download_hash: sha256=ba807d6017b612a0c63c093a954c7d63918d3e324bdba335d67b7948439dbca8
+    # TODO: add parameter for binary installation flavor
+    #
+    # flavor: linux-amd64
     tiller:
       install: true
       namespace: kube-system
     kubectl:
-      install: true
+      install: false
       version: 1.6.7
       download_hash: sha256=54947ef84181e89f9dbacedd54717cbed5cc7f9c36cb37bc8afc9097648e2c91
-      config: {}
+      config:
+        gce_service_token: 
 {%- endload %}
 
 {%- set config = salt['pillar.get']('helm:client', base_config.helm.client, merge=true) %}
-{%- set client = salt['grains.filter_by'](base_defaults, merge=config) %}
\ No newline at end of file
+{%- set client = salt['grains.filter_by'](base_defaults, merge=config) %}
+
+
+{%- set constants = {
+    "helm": {
+      "home": "/srv/helm/helm",
+      "bin": "/usr/bin/helm-v" + config.version,
+      "tmp": "/tmp/helm-v" + config.version,
+      "cmd": "helm --tiller-namespace '{}'".format(config.tiller.namespace),
+      "tiller_arg": "- tiller_namespace: \"{}\"".format(config.tiller.namespace),
+      "gce_state_arg": "",
+    },
+    "tiller": {
+      "gce_env_var": "",
+    },
+    "kubectl": {
+      "bin": "/usr/bin/kubectl",
+      "config": "/srv/helm/kubeconfig.yaml",
+      "gce_service_token_path": "/srv/helm/gce_token.json",
+    }
+  } 
+%}
+
+{%- if "host" in config.tiller %}
+{%- do constants.update({
+     "helm": {
+       "cmd": "helm --host '{}'".format(config.tiller.host),
+       "tiller_arg": "- tiller_host: \"{}\"".format(config.tiller.host)
+     }
+   })
+%}
+{%- endif %}
+
+{%- if config.kubectl.config.gce_service_token %}
+{%- do constants.update({
+     "helm": {
+       "gce_state_arg": "- gce_service_token: \"{}\"".format(constants.gce_service_token_path),
+     },
+     "tiller": {
+       "gce_env_var": "- GOOGLE_APPLICATION_CREDENTIALS: \"{}\"".format(gce_service_token_path)
+     }
+   })
+%}
+{%- endif %}
\ No newline at end of file
diff --git a/helm/releases_managed.sls b/helm/releases_managed.sls
new file mode 100644
index 0000000..152e09c
--- /dev/null
+++ b/helm/releases_managed.sls
@@ -0,0 +1,62 @@
+{%- from slspath + "/map.jinja" import config, constants with context %}
+
+include:
+  - .client_installed
+  - .tiller_installed
+  - .kubectl_configured
+  - .repos_synchronized
+
+{%- if "releases" in config %}
+{%- for release_id, release in config.releases.items() %}
+{%- set release_name = release.get('name', release_id) %}
+{%- set namespace = release.get('namespace', 'default') %}
+
+{%- if release.get('enabled', True) %}
+ensure_{{ release_id }}_release:
+  helm_release.present:
+    - name: {{ release_name }}
+    - chart_name: {{ release['chart'] }}
+    - namespace: {{ namespace }}
+    - kube_config: {{ constants.kubectl.config }}
+    {{ constants.helm.tiller_arg }}
+    {{ constants.helm.gce_state_arg }}
+    {%- if release.get('version') %}
+    - version: {{ release['version'] }}
+    {%- endif %}
+    {%- if release.get('values') %}
+    - values:
+        {{ release['values']|yaml(False)|indent(8) }}
+    {%- endif %}
+    - require:
+      {%- if config.tiller.install %}
+      - sls: {{ slspath }}.tiller_installed
+      {%- endif %}
+      - sls: {{ slspath }}.client_installed
+      - sls: {{ slspath }}.kubectl_configured
+      # 
+      # note: intentionally don't fail if one or more repos fail to synchronize,
+      # since there should be a local repo cache anyways.
+      # 
+
+{%- else %}{# not release.enabled #}
+absent_{{ release_id }}_release:
+  helm_release.absent:
+    - name: {{ release_name }}
+    - namespace: {{ namespace }}
+    - kube_config: {{ constants.kubectl.config }}
+    {{ constants.helm.tiller_arg }}
+    {{ constants.helm.gce_state_arg }}
+    - require:
+      {%- if config.tiller.install %}
+      - sls: {{ slspath }}.tiller_installed
+      {%- endif %}
+      - sls: {{ slspath }}.client_installed
+      - sls: {{ slspath }}.kubectl_configured
+      # 
+      # note: intentionally don't fail if one or more repos fail to synchronize,
+      # since there should be a local repo cache anyways.
+      # 
+
+{%- endif %}{# release.enabled #}
+{%- endfor %}{# release_id, release in client.releases #}
+{%- endif %}{# "releases" in client #}
diff --git a/helm/repos_synchronized.sls b/helm/repos_synchronized.sls
new file mode 100644
index 0000000..f4c3f91
--- /dev/null
+++ b/helm/repos_synchronized.sls
@@ -0,0 +1,17 @@
+{%- from slspath + "/map.jinja" import config, constants with context %}
+
+include:
+  - .client_installed
+
+{%- if "repos" in config %}
+{%- for repo_name, repo_url in config.repos.items() %}
+ensure_{{ repo_name }}_repo:
+  cmd.run:
+    - name: {{ constants.helm.cmd }} repo add {{ repo_name }} {{ repo_url }}
+    - env:
+      - HELM_HOME: {{ constants.helm.home }}
+    - unless: {{ constants.helm.cmd }} repo list | grep '^{{ repo_name }} {{ repo_url|replace(".", "\.") }}'
+    - require:
+      - sls: {{ slspath }}.client_installed
+{%- endfor %}
+{%- endif %}{# "repos" in client #}
diff --git a/helm/tiller_installed.sls b/helm/tiller_installed.sls
new file mode 100644
index 0000000..673349d
--- /dev/null
+++ b/helm/tiller_installed.sls
@@ -0,0 +1,33 @@
+{%- from slspath + "/map.jinja" import config, constants with context %}
+
+include:
+  - .client_installed
+  - .kubectl_configured
+
+{%- if config.tiller.install %}
+install_tiller:
+  cmd.run:
+    - name: {{ constants.helm.cmd }} init --upgrade
+    - env:
+      - HELM_HOME: {{ constants.helm.home }}
+      - KUBECONFIG: {{ constants.kubectl.config }}
+      {{ constants.tiller.gce_env_var }}
+    - unless: "{{ constants.helm.cmd }} version --server --short | grep -E 'Server: v{{ config.version }}(\\+|$)'"
+    - require:
+      - sls: {{ slspath }}.client_installed
+      - sls: {{ slspath }}.kubectl_configured
+
+wait_for_tiller:
+  cmd.run:
+    - name: while ! {{ constants.helm.cmd }} list; do sleep 3; done
+    - timeout: 30
+    - env:
+      - HELM_HOME: {{ constants.helm.home }}
+      - KUBECONFIG: {{ constants.kubectl.config }}
+      {{ constants.tiller.gce_env_var }}
+    - require:
+      - sls: {{ slspath }}.client_installed
+      - sls: {{ slspath }}.kubectl_configured
+    - onchanges:
+      - cmd: install_tiller
+{%- endif %}
\ No newline at end of file
diff --git a/metadata/service/client.yml b/metadata/service/client.yml
index b46a69a..0bef9e4 100644
--- a/metadata/service/client.yml
+++ b/metadata/service/client.yml
@@ -5,7 +5,6 @@
 parameters:
   helm:
     client:
-      enabled: true
       version: 2.4.2
       download_hash: sha256=96f74ff04ec7eb38e5f53aba73132bfe4d6b81168f20574dad25a9bcaceec81b
       tiller:
diff --git a/pillar.example b/pillar.example
index 156b411..6ad80a9 100644
--- a/pillar.example
+++ b/pillar.example
@@ -24,13 +24,6 @@
     # ```
     # 
     # download_hash: sha256=ba807d6017b612a0c63c093a954c7d63918d3e324bdba335d67b7948439dbca8
-    
-    #
-    # Whether the helm client should be enabled for the target minion or not
-    # 
-    # TODO: this should be removed.
-    #
-    enabled: true
 
     #
     # Configurations to manage the cluster's Tiller installation