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