diff --git a/Dockerfile b/Dockerfile index a107bf2..069e176 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,10 @@ FROM linkyard/alpine-helm:2.16.7 LABEL maintainer "mario.siegenthaler@linkyard.ch" -RUN apk add --update --upgrade --no-cache jq bash curl git gettext libintl +RUN apk add --update --upgrade --no-cache jq bash curl git gettext libintl python +RUN curl -sSL https://sdk.cloud.google.com | bash +ENV PATH $PATH:/root/google-cloud-sdk/bin ENV KUBERNETES_VERSION 1.16.9 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 diff --git a/README.md b/README.md index f7bf584..f8545ce 100644 --- a/README.md +++ b/README.md @@ -16,36 +16,44 @@ resource_types: ## Source Configuration -* `cluster_url`: *Optional.* URL to Kubernetes Master API service. Do not set when using the `kubeconfig_path` parameter, otherwise required. -* `cluster_ca`: *Optional.* Base64 encoded PEM. Required if `cluster_url` is https. -* `insecure_skip_tls_verify`: *Optional* Skips verifying the `cluster_ca`. (Default: false). Ignored unless `cluster_url` is https. Useful for self-signed certificates. It is not recommended to use blindly. -* `token`: *Optional.* Bearer token for Kubernetes. This, 'token_path' or `admin_key`/`admin_cert` are required if `cluster_url` is https. -* `token_path`: *Optional.* Path to file containing the bearer token for Kubernetes. This, 'token' or `admin_key`/`admin_cert` are required if `cluster_url` is https. -* `admin_key`: *Optional.* Base64 encoded PEM. Required if `cluster_url` is https and no `token` or 'token_path' is provided. -* `admin_cert`: *Optional.* Base64 encoded PEM. Required if `cluster_url` is https and no `token` or 'token_path' is provided. -* `release`: *Optional.* Name of the release (not a file, a string). (Default: autogenerated by helm) -* `namespace`: *Optional.* Kubernetes namespace the chart will be installed into. (Default: default) -* `tillerless`: *Optional.* Set to true to use tiller-less mode (Default: false). See . -* `tillerless_silent`: *Optional.* Set to `true` to make tiller-less mode silent (Default: true). Activating tillerless helm without making it silent **will make credentials to leak in the build output** when using `override_values` parameter with `hide: true`. -* `helm_init_server`: *Optional.* Installs helm into the cluster if not already installed. (Default: false). Not supported when using tillerless. -* `tiller_namespace`: *Optional.* Kubernetes namespace where tiller is running (or will be installed to). (Default: kube-system) -* `tiller_cert`: *Optional* Certificate for Tiller (only applies if tls_enabled and helm_init_server are true). -* `tiller_key`: *Optional* Key created for Tiller when doing a secure Tiller install (only applies if tls_enabled and helm_init_server are true). -* `tiller_service_account`: *Optional* Name of the service account that tiller will use (only applies if helm_init_server is true). -* `helm_ca`: *Optional* Private CA that is used to issue certificates for Tiller clients and servers (only applies if tls_enabled is true). -* `helm_cert`: *Optional* Certificate for Client (only applies if tls_enabled is true). -* `helm_key`: *Optional* Key created for Client when doing a secure Tiller install (only applies if tls_enabled is true). -* `tls_enabled`: *Optional* Uses TLS for all interactions with Tiller. (Default: false). Not supported when using tillerless. -* `helm_history_max`: *Optional.* Limits the maximum number of revisions. (Default: 0 = no limit) -* `helm_host`: *Optional* Address of Tiller. Skips helm discovery process. (only applies if `helm_init_server` is false). -* `repos`: *Optional.* Array of Helm repositories to initialize, each repository is defined as an object with properties `name`, `url` (required) username and password (optional). -* `plugins`: *Optional.* Array of Helm plugins to install, each defined as an object with properties `url` (required), `version` (optional). -* `stable_repo`: *Optional* Override default Helm stable repo . Useful if running helm deploys without internet access. -* `kubeconfig_namespace`: *Optional.* Use the kubeconfig context namespace as the helm namespace. (Default: false) -* `kubeconfig_tiller_namespace`: *Optional.* Use the kubeconfig context namespace as the tiller namespace. (Default: false) -* `tracing_enabled`: *Optional.* Enable extremely verbose tracing for this resource. Useful when developing the resource itself. May allow secrets to be displayed. (Default: false) -* `helm_init_wait`: *Optional.* When initializing the helm server, use the `--wait` option. (Default: false) -* `helm_setup_purge_all`: *Optional.* Delete and purge every helm release. Use with extreme caution. (Default: false) +- `gcloud_cluster_auth`: _Optional._ Set to true to use gcloud service account file for kubernetes cluster authentication. + +- `gcloud_service_account_key_file`: _Optional_ Manadatory if gcloud_cluster_auth is set to true. Pass gcloud service accon json contents as value. + +- `gcloud_project_name`: _Optional_ Manadatory if gcloud_cluster_auth is set to true. Pass gcloud project name where cluster is installed. + +- `gcloud_k8s_cluster_name`: _Optional_ Manadatory if gcloud_cluster_auth is set to true. Pass gcloud cluster name. + +- `gcloud_k8s_zone`: _Optional_ Manadatory if gcloud_cluster_auth is set to true. Pass gcloud kubernetes cluster zone. + +- `cluster_url`: _Optional._ URL to Kubernetes Master API service. Do not set when using the `kubeconfig_path` parameter, otherwise required. +- `cluster_ca`: _Optional._ Base64 encoded PEM. Required if `cluster_url` is https. +- `token`: _Optional._ Bearer token for Kubernetes. This, 'token_path' or `admin_key`/`admin_cert` are required if `cluster_url` is https. +- `token_path`: _Optional._ Path to file containing the bearer token for Kubernetes. This, 'token' or `admin_key`/`admin_cert` are required if `cluster_url` is https. +- `admin_key`: _Optional._ Base64 encoded PEM. Required if `cluster_url` is https and no `token` or 'token_path' is provided. +- `admin_cert`: _Optional._ Base64 encoded PEM. Required if `cluster_url` is https and no `token` or 'token_path' is provided. +- `release`: _Optional._ Name of the release (not a file, a string). (Default: autogenerated by helm) +- `namespace`: _Optional._ Kubernetes namespace the chart will be installed into. (Default: default) +- `tillerless`: _Optional._ Set to true to use tiller-less mode (Default: false). See . +- `helm_init_server`: _Optional._ Installs helm into the cluster if not already installed. (Default: false). Not supported when using tillerless. +- `tiller_namespace`: _Optional._ Kubernetes namespace where tiller is running (or will be installed to). (Default: kube-system) +- `tiller_cert`: _Optional_ Certificate for Tiller (only applies if tls_enabled and helm_init_server are true). +- `tiller_key`: _Optional_ Key created for Tiller when doing a secure Tiller install (only applies if tls_enabled and helm_init_server are true). +- `tiller_service_account`: _Optional_ Name of the service account that tiller will use (only applies if helm_init_server is true). +- `helm_ca`: _Optional_ Private CA that is used to issue certificates for Tiller clients and servers (only applies if tls_enabled is true). +- `helm_cert`: _Optional_ Certificate for Client (only applies if tls_enabled is true). +- `helm_key`: _Optional_ Key created for Client when doing a secure Tiller install (only applies if tls_enabled is true). +- `tls_enabled`: _Optional_ Uses TLS for all interactions with Tiller. (Default: false). Not supported when using tillerless. +- `helm_history_max`: _Optional._ Limits the maximum number of revisions. (Default: 0 = no limit) +- `helm_host`: _Optional_ Address of Tiller. Skips helm discovery process. (only applies if `helm_init_server` is false). +- `repos`: _Optional._ Array of Helm repositories to initialize, each repository is defined as an object with properties `name`, `url` (required) username and password (optional). +- `plugins`: _Optional._ Array of Helm plugins to install, each defined as an object with properties `url` (required), `version` (optional). +- `stable_repo`: _Optional_ Override default Helm stable repo . Useful if running helm deploys without internet access. +- `kubeconfig_namespace`: _Optional._ Use the kubeconfig context namespace as the helm namespace. (Default: false) +- `kubeconfig_tiller_namespace`: _Optional._ Use the kubeconfig context namespace as the tiller namespace. (Default: false) +- `tracing_enabled`: _Optional._ Enable extremely verbose tracing for this resource. Useful when developing the resource itself. May allow secrets to be displayed. (Default: false) +- `helm_init_wait`: _Optional._ When initializing the helm server, use the `--wait` option. (Default: false) +- `helm_setup_purge_all`: _Optional._ Delete and purge every helm release. Use with extreme caution. (Default: false) ## Behavior @@ -63,44 +71,41 @@ on the cluster. #### Parameters -* `chart`: *Required.* Either the file containing the helm chart to deploy (ends with .tgz), the path to a local directory containing the chart or the name of the chart from a repo (e.g. `stable/mysql`). -* `namespace`: *Optional.* Either a file containing the name of the namespace or the name of the namespace. (Default: taken from source configuration). -* `release`: *Optional.* Either a file containing the name of the release or the name of the release. (Default: taken from source configuration). -* `values`: *Optional.* File containing the values.yaml for the deployment. Supports setting multiple value files using an array. -* `override_values`: *Optional.* Array of values that can override those defined in values.yaml. Each entry in - the array is a map containing a key and a value or path. Value is set directly while path reads the contents of - the file in that path. A `hide: true` parameter ensures that the value is not logged and instead replaced with `***HIDDEN***`. - A `type: string` parameter makes sure Helm always treats the value as a string (uses the `--set-string` option to Helm; useful if the value varies - and may look like a number, eg. if it's a Git commit hash). - A `verbatim: true` parameter escapes backslashes so the value is passed as-is to the Helm chart (useful for `((credentials))`). - The default behaviour of backslashes in `--set` is to quote the next character so `val\ue` is treated as `value` by Helm. -* `token_path`: *Optional.* Path to file containing the bearer token for Kubernetes. This, 'token' or `admin_key`/`admin_cert` are required if `cluster_url` is https. -* `version`: *Optional* Chart version to deploy, can be a file or a value. Only applies if `chart` is not a file. -* `delete`: *Optional.* Deletes the release instead of installing it. Requires the `name`. (Default: false) -* `test`: *Optional.* Test the release instead of installing it. Requires the `release`. (Default: false) -* `purge`: *Optional.* Purge the release on delete. (Default: false) -* `replace`: *Optional.* Replace deleted release with same name. (Default: false) -* `force`: *Optional.* Force resource update through delete/recreate if needed. (Default: false) -* `devel`: *Optional.* Allow development versions of chart to be installed. This is useful when wanting to install pre-release - charts (i.e. 1.0.2-rc1) without having to specify a version. (Default: false) -* `debug`: *Optional.* Dry run the helm install with the debug flag which logs interpolated chart templates. (Default: false) -* `wait_until_ready`: *Optional.* Set to the number of seconds it should wait until all the resources in - the chart are ready. (Default: `0` which means don't wait). -* `check_is_ready`: *Optional.* Requires that `wait_until_ready` is set to Default. Applies --wait without timeout. (Default: false) -* `atomic`: *Optional.* This flag will cause failed installs to purge the release, and failed upgrades to rollback to the previous release. (Default: false) -* `recreate_pods`: *Optional.* This flag will cause all pods to be recreated when upgrading. (Default: false) -* `show_diff`: *Optional.* Show the diff that is applied if upgrading an existing successful release. Will not be used when `devel` is set. (Default: false) -* `exit_after_diff`: *Optional.* Show the diff but don't actually install/upgrade. (Default: false) -* `reuse_values`: *Optional.* When upgrading, reuse the last release's values. (Default: false) -* `reset_values`: *Optional.* When upgrading, reset the values to the ones built into the chart. (Default: false) -* `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. +- `chart`: _Required._ Either the file containing the helm chart to deploy (ends with .tgz), the path to a local directory containing the chart or the name of the chart from a repo (e.g. `stable/mysql`). +- `namespace`: _Optional._ Either a file containing the name of the namespace or the name of the namespace. (Default: taken from source configuration). +- `release`: _Optional._ Either a file containing the name of the release or the name of the release. (Default: taken from source configuration). +- `values`: _Optional._ File containing the values.yaml for the deployment. Supports setting multiple value files using an array. +- `override_values`: _Optional._ Array of values that can override those defined in values.yaml. Each entry in + the array is a map containing a key and a value or path. Value is set directly while path reads the contents of + the file in that path. A `hide: true` parameter ensures that the value is not logged and instead replaced with `***HIDDEN***`. + A `type: string` parameter makes sure Helm always treats the value as a string (uses the `--set-string` option to Helm; useful if the value varies + and may look like a number, eg. if it's a Git commit hash). +- `token_path`: _Optional._ Path to file containing the bearer token for Kubernetes. This, 'token' or `admin_key`/`admin_cert` are required if `cluster_url` is https. +- `version`: _Optional_ Chart version to deploy, can be a file or a value. Only applies if `chart` is not a file. +- `delete`: _Optional._ Deletes the release instead of installing it. Requires the `name`. (Default: false) +- `test`: _Optional._ Test the release instead of installing it. Requires the `release`. (Default: false) +- `purge`: _Optional._ Purge the release on delete. (Default: false) +- `replace`: _Optional._ Replace deleted release with same name. (Default: false) +- `force`: _Optional._ Force resource update through delete/recreate if needed. (Default: false) +- `devel`: _Optional._ Allow development versions of chart to be installed. This is useful when wanting to install pre-release + charts (i.e. 1.0.2-rc1) without having to specify a version. (Default: false) +- `debug`: _Optional._ Dry run the helm install with the debug flag which logs interpolated chart templates. (Default: false) +- `wait_until_ready`: _Optional._ Set to the number of seconds it should wait until all the resources in + the chart are ready. (Default: `0` which means don't wait). +- `check_is_ready`: _Optional._ Requires that `wait_until_ready` is set to Default. Applies --wait without timeout. (Default: false) +- `recreate_pods`: _Optional._ This flag will cause all pods to be recreated when upgrading. (Default: false) +- `show_diff`: _Optional._ Show the diff that is applied if upgrading an existing successful release. Will not be used when `devel` is set. (Default: false) +- `exit_after_diff`: _Optional._ Show the diff but don't actually install/upgrade. (Default: false) +- `reuse_values`: _Optional._ When upgrading, reuse the last release's values. (Default: false) +- `reset_values`: _Optional._ When upgrading, reset the values to the ones built into the chart. (Default: false) +- `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. ## Example ### Out -Define the resource: +Define the resource for authentication with certificates as follows: ```yaml resources: @@ -116,6 +121,27 @@ resources: url: https://somerepo.github.io/charts ``` + +Define the resource for authentication with gcloud sevice account json as follows: + +```yaml +resources: +- name: myapp-helm-gcloud + type: helm + source: + gcloud_cluster_auth: true + gcloud_service_account_key_file: _plain service account json file_ + gcloud_project_name: _project name_ + gcloud_k8s_cluster_name: _k8s cluster name_ + gcloud_k8s_zone: _k8s zone_ + repos: + - name: some_repo + url: https://somerepo.github.io/charts +``` + + + + Add to job: ```yaml diff --git a/assets/common.sh b/assets/common.sh index 9c90cd2..ec45968 100644 --- a/assets/common.sh +++ b/assets/common.sh @@ -1,6 +1,29 @@ #!/bin/bash set -e +setup_gcp_kubernetes() { + payload=$1 + source=$2 + + gcloud_service_account_key_file=$(jq -r '.source.gcloud_service_account_key_file // ""' < $payload) + gcloud_project_name=$(jq -r '.source.gcloud_project_name // ""' < $payload) + gcloud_k8s_cluster_name=$(jq -r '.source.gcloud_k8s_cluster_name // ""' < $payload) + gcloud_k8s_zone=$(jq -r '.source.gcloud_k8s_zone // ""' < $payload) + + if [ -z "$gcloud_service_account_key_file" ] || [ -z "$gcloud_project_name" ] || [ -z "$gcloud_k8s_cluster_name" ] || [ -z "$gcloud_k8s_zone" ]; then + echo "invalid payload for gcloud auth, please pass all required params" + exit 1 + fi + + echo "$gcloud_service_account_key_file" >> /gcloud.json + gcloud_service_account_name=($(cat /gcloud.json | jq -r ".client_email")) + gcloud auth activate-service-account ${gcloud_service_account_name} --key-file /gcloud.json + gcloud config set account ${gcloud_service_account_name} + gcloud config set project ${gcloud_project_name} + gcloud container clusters get-credentials ${gcloud_k8s_cluster_name} --zone ${gcloud_k8s_zone} + kubectl version +} + setup_kubernetes() { payload=$1 source=$2 @@ -25,7 +48,7 @@ setup_kubernetes() { token=$(jq -r '.source.token // ""' < $payload) token_path=$(jq -r '.params.token_path // ""' < $payload) insecure_skip_tls_verify=$(jq -r '.source.insecure_skip_tls_verify // "false"' < $payload) - + if [ "$insecure_skip_tls_verify" = true ]; then kubectl config set-cluster default --server=$cluster_url --insecure-skip-tls-verify else @@ -246,10 +269,21 @@ setup_resource() { set -x fi - echo "Initializing kubectl..." - setup_kubernetes $1 $2 + gcloud_cluster_auth=$(jq -r '.source.gcloud_cluster_auth // "false"' < $1) + if [ "$gcloud_cluster_auth" = "true" ]; then + echo "Initializing kubectl access using gcloud service account file" + setup_gcp_kubernetes $1 $2 + else + echo "Initializing kubectl using certificates" + setup_kubernetes $1 $2 + fi + + echo "Updating helm in server side..." + helm init --upgrade || true + kubectl rollout status deployment tiller-deploy -n kube-system || true echo "Initializing helm..." setup_tls $1 setup_helm $1 $2 setup_repos $1 + }