From 2162101e2ac0514c44b8ccfbe3de16a04f19eb70 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Sat, 9 Dec 2017 15:45:22 +0530 Subject: [PATCH 01/27] .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1caa81d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.DS_STORE +tmp From b179f70e0bde7682e6f93e98d2220a88a95c74f5 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Sat, 9 Dec 2017 15:48:31 +0530 Subject: [PATCH 02/27] adds: k8s-user, client-cert/key based auth --- update.sh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/update.sh b/update.sh index 98df6a9..25a2210 100755 --- a/update.sh +++ b/update.sh @@ -8,6 +8,14 @@ if [ ! -z ${PLUGIN_KUBERNETES_TOKEN} ]; then KUBERNETES_TOKEN=$PLUGIN_KUBERNETES_TOKEN fi +if [ ! -z ${PLUGIN_KUBERNETES_CLIENT_CERT} ]; then + KUBERNETES_CLIENT_CERT=$PLUGIN_KUBERNETES_CLIENT_CERT +fi + +if [ ! -z ${PLUGIN_KUBERNETES_CLIENT_KEY} ]; then + KUBERNETES_CLIENT_KEY=$PLUGIN_KUBERNETES_CLIENT_KEY +fi + if [ ! -z ${PLUGIN_KUBERNETES_SERVER} ]; then KUBERNETES_SERVER=$PLUGIN_KUBERNETES_SERVER fi @@ -16,7 +24,18 @@ if [ ! -z ${PLUGIN_KUBERNETES_CERT} ]; then KUBERNETES_CERT=${PLUGIN_KUBERNETES_CERT} fi -kubectl config set-credentials default --token=${KUBERNETES_TOKEN} +if [ ! -z ${PLUGIN_KUBERNETES_USER} ]; then + KUBERNETES_USER=${PLUGIN_KUBERNETES_USER:-default} +fi + +if [ ! -z ${KUBERNETES_CLIENT_CERT} ] && [ ! -z ${KUBERNETES_CLIENT_KEY} ]; then + echo ${KUBERNETES_CLIENT_CERT} | base64 -d > client.crt + echo ${KUBERNETES_CLIENT_KEY} | base64 -d > client.key + kubectl config set-credentials ${KUBERNETES_USER} --client-certificate=client.crt --client-key=client.key +else + kubectl config set-credentials ${KUBERNETES_USER} --token=${KUBERNETES_TOKEN} +fi + if [ ! -z ${KUBERNETES_CERT} ]; then echo ${KUBERNETES_CERT} | base64 -d > ca.crt kubectl config set-cluster default --server=${KUBERNETES_SERVER} --certificate-authority=ca.crt From 7ec8267de5e069d2762384793630641152c757fd Mon Sep 17 00:00:00 2001 From: hashfyre Date: Sat, 9 Dec 2017 15:48:39 +0530 Subject: [PATCH 03/27] updates readme --- README.md | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 8ec9b97..e99bad2 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This plugin allows to update a Kubernetes deployment. -## Usage +## Usage This pipeline will update the `my-deployment` deployment with the image tagged `DRONE_COMMIT_SHA:0:8` @@ -13,13 +13,13 @@ This pipeline will update the `my-deployment` deployment with the image tagged ` deployment: my-deployment repo: myorg/myrepo container: my-container - tag: + tag: - mytag - latest ``` Deploying containers across several deployments, eg in a scheduler-worker setup. Make sure your container `name` in your manifest is the same for each pod. - + ```yaml pipeline: deploy: @@ -27,7 +27,7 @@ Deploying containers across several deployments, eg in a scheduler-worker setup. deployment: [server-deploy, worker-deploy] repo: myorg/myrepo container: my-container - tag: + tag: - mytag - latest ``` @@ -41,19 +41,37 @@ Deploying multiple containers within the same deployment. deployment: my-deployment repo: myorg/myrepo container: [container1, container2] - tag: + tag: - mytag - latest ``` **NOTE**: Combining multi container deployments across multiple deployments is not recommended -This more complex example demonstrates how to deploy to several environments based on the branch, in a `app` namespace +This more complex example demonstrates how to deploy to several environments based on the branch, in a `app` namespace ```yaml pipeline: + deploy-qa: + image: quay.io/honestbee/drone-kubernetes + kubernetes_user: ${KUBERNETES_USER} + kubernetes_server: ${KUBERNETES_SERVER_STAGING} + kubernetes_cert: ${KUBERNETES_CERT_STAGING} + kubernetes_client_cert: ${PLUGIN_KUBERNETES_CLIENT_CERT} + kubernetes_client_key: ${PLUGIN_KUBERNETES_CLIENT_KEY} + deployment: my-deployment + repo: myorg/myrepo + container: my-container + namespace: app + tag: + - mytag + - latest + when: + branch: [ qa ] + deploy-staging: image: quay.io/honestbee/drone-kubernetes + kubernetes_user: ${KUBERNETES_USER} kubernetes_server: ${KUBERNETES_SERVER_STAGING} kubernetes_cert: ${KUBERNETES_CERT_STAGING} kubernetes_token: ${KUBERNETES_TOKEN_STAGING} @@ -61,7 +79,7 @@ This more complex example demonstrates how to deploy to several environments bas repo: myorg/myrepo container: my-container namespace: app - tag: + tag: - mytag - latest when: @@ -76,7 +94,7 @@ This more complex example demonstrates how to deploy to several environments bas repo: myorg/myrepo container: my-container namespace: app - tag: + tag: - mytag - latest when: @@ -96,7 +114,7 @@ This more complex example demonstrates how to deploy to several environments bas your-user/your-repo KUBERNETES_TOKEN eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJ... ``` -When using TLS Verification, ensure Server Certificate used by kubernetes API server +When using TLS Verification, ensure Server Certificate used by kubernetes API server is signed for SERVER url ( could be a reason for failures if using aliases of kubernetes cluster ) ## How to get token @@ -171,7 +189,7 @@ kubectl -n web get secrets kubectl -n web get secret/drone-deploy-token-XXXXX -o yaml | egrep 'ca.crt:|token:' ``` -## To do +## To do Replace the current kubectl bash script with a go implementation. From bb442305378a7d4d2688b4050a9887bf2bc9c3b5 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Sat, 9 Dec 2017 16:08:15 +0530 Subject: [PATCH 04/27] fixes readme qa example --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e99bad2..a47fd03 100644 --- a/README.md +++ b/README.md @@ -55,8 +55,8 @@ This more complex example demonstrates how to deploy to several environments bas deploy-qa: image: quay.io/honestbee/drone-kubernetes kubernetes_user: ${KUBERNETES_USER} - kubernetes_server: ${KUBERNETES_SERVER_STAGING} - kubernetes_cert: ${KUBERNETES_CERT_STAGING} + kubernetes_server: ${KUBERNETES_SERVER_QA} + kubernetes_cert: ${KUBERNETES_CERT_QA} kubernetes_client_cert: ${PLUGIN_KUBERNETES_CLIENT_CERT} kubernetes_client_key: ${PLUGIN_KUBERNETES_CLIENT_KEY} deployment: my-deployment From e264442450b908735ebc5e0122eeb5f077a58eeb Mon Sep 17 00:00:00 2001 From: hashfyre Date: Sat, 9 Dec 2017 17:08:57 +0530 Subject: [PATCH 05/27] adds execution step messages --- update.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/update.sh b/update.sh index 25a2210..90f0c83 100755 --- a/update.sh +++ b/update.sh @@ -29,14 +29,17 @@ if [ ! -z ${PLUGIN_KUBERNETES_USER} ]; then fi if [ ! -z ${KUBERNETES_CLIENT_CERT} ] && [ ! -z ${KUBERNETES_CLIENT_KEY} ]; then + echo "INFO: Setting client credentials with signed-certificate and key." echo ${KUBERNETES_CLIENT_CERT} | base64 -d > client.crt echo ${KUBERNETES_CLIENT_KEY} | base64 -d > client.key kubectl config set-credentials ${KUBERNETES_USER} --client-certificate=client.crt --client-key=client.key else + echo "INFO: Setting client credentials with token." kubectl config set-credentials ${KUBERNETES_USER} --token=${KUBERNETES_TOKEN} fi if [ ! -z ${KUBERNETES_CERT} ]; then + echo "INFO: Using secure connection with tls-certificate." echo ${KUBERNETES_CERT} | base64 -d > ca.crt kubectl config set-cluster default --server=${KUBERNETES_SERVER} --certificate-authority=ca.crt else From f546a27b4c6f0b2c5611fa409fd6f9b973096f23 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Mon, 11 Dec 2017 15:40:44 +0530 Subject: [PATCH 06/27] adds bash flags --- update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/update.sh b/update.sh index 90f0c83..97e227c 100755 --- a/update.sh +++ b/update.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -euo pipefail if [ -z ${PLUGIN_NAMESPACE} ]; then PLUGIN_NAMESPACE="default" From 6994a596aee5c75306fedfa121497dd8413fb6b6 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Mon, 11 Dec 2017 17:25:48 +0530 Subject: [PATCH 07/27] adds more verbosity --- update.sh | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/update.sh b/update.sh index 97e227c..7a9a1c6 100755 --- a/update.sh +++ b/update.sh @@ -5,38 +5,39 @@ if [ -z ${PLUGIN_NAMESPACE} ]; then PLUGIN_NAMESPACE="default" fi -if [ ! -z ${PLUGIN_KUBERNETES_TOKEN} ]; then - KUBERNETES_TOKEN=$PLUGIN_KUBERNETES_TOKEN -fi - -if [ ! -z ${PLUGIN_KUBERNETES_CLIENT_CERT} ]; then - KUBERNETES_CLIENT_CERT=$PLUGIN_KUBERNETES_CLIENT_CERT -fi - -if [ ! -z ${PLUGIN_KUBERNETES_CLIENT_KEY} ]; then - KUBERNETES_CLIENT_KEY=$PLUGIN_KUBERNETES_CLIENT_KEY -fi - if [ ! -z ${PLUGIN_KUBERNETES_SERVER} ]; then KUBERNETES_SERVER=$PLUGIN_KUBERNETES_SERVER +else + echo "ERROR: kubernetes_server url not provided" fi if [ ! -z ${PLUGIN_KUBERNETES_CERT} ]; then KUBERNETES_CERT=${PLUGIN_KUBERNETES_CERT} +else + echo "WARNING: kubernetes_server_cert not provided" + echo "Inscure connection to the cluster will be used." fi if [ ! -z ${PLUGIN_KUBERNETES_USER} ]; then KUBERNETES_USER=${PLUGIN_KUBERNETES_USER:-default} fi -if [ ! -z ${KUBERNETES_CLIENT_CERT} ] && [ ! -z ${KUBERNETES_CLIENT_KEY} ]; then +if [ ! -z ${PLUGIN_KUBERNETES_CLIENT_CERT} ] && [ ! -z ${PLUGIN_KUBERNETES_CLIENT_KEY} ]; then + KUBERNETES_CLIENT_CERT=$PLUGIN_KUBERNETES_CLIENT_CERT + KUBERNETES_CLIENT_KEY=$PLUGIN_KUBERNETES_CLIENT_KEY echo "INFO: Setting client credentials with signed-certificate and key." echo ${KUBERNETES_CLIENT_CERT} | base64 -d > client.crt echo ${KUBERNETES_CLIENT_KEY} | base64 -d > client.key kubectl config set-credentials ${KUBERNETES_USER} --client-certificate=client.crt --client-key=client.key -else +elif [ ! -z ${PLUGIN_KUBERNETES_TOKEN} ]; then + KUBERNETES_TOKEN=$PLUGIN_KUBERNETES_TOKEN echo "INFO: Setting client credentials with token." kubectl config set-credentials ${KUBERNETES_USER} --token=${KUBERNETES_TOKEN} +else + echo "ERROR: Provide either of the following authentication params:" + echo "[1] kubernetes_token" + echo "[2] kubernetes_client_cert and kubernetes_client_key" + exit 1 fi if [ ! -z ${KUBERNETES_CERT} ]; then From 3902a7985af43cab007e2a701e1a06c0ea9148c8 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Wed, 10 Jan 2018 04:02:29 +0530 Subject: [PATCH 08/27] script: update: drops base64 enc of certs, fixes bash errs --- update.sh | 73 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/update.sh b/update.sh index 7a9a1c6..52f1c62 100755 --- a/update.sh +++ b/update.sh @@ -1,55 +1,60 @@ #!/bin/bash set -euo pipefail -if [ -z ${PLUGIN_NAMESPACE} ]; then - PLUGIN_NAMESPACE="default" -fi - -if [ ! -z ${PLUGIN_KUBERNETES_SERVER} ]; then - KUBERNETES_SERVER=$PLUGIN_KUBERNETES_SERVER -else - echo "ERROR: kubernetes_server url not provided" -fi - -if [ ! -z ${PLUGIN_KUBERNETES_CERT} ]; then - KUBERNETES_CERT=${PLUGIN_KUBERNETES_CERT} -else - echo "WARNING: kubernetes_server_cert not provided" - echo "Inscure connection to the cluster will be used." -fi - if [ ! -z ${PLUGIN_KUBERNETES_USER} ]; then KUBERNETES_USER=${PLUGIN_KUBERNETES_USER:-default} fi -if [ ! -z ${PLUGIN_KUBERNETES_CLIENT_CERT} ] && [ ! -z ${PLUGIN_KUBERNETES_CLIENT_KEY} ]; then - KUBERNETES_CLIENT_CERT=$PLUGIN_KUBERNETES_CLIENT_CERT - KUBERNETES_CLIENT_KEY=$PLUGIN_KUBERNETES_CLIENT_KEY - echo "INFO: Setting client credentials with signed-certificate and key." - echo ${KUBERNETES_CLIENT_CERT} | base64 -d > client.crt - echo ${KUBERNETES_CLIENT_KEY} | base64 -d > client.key - kubectl config set-credentials ${KUBERNETES_USER} --client-certificate=client.crt --client-key=client.key -elif [ ! -z ${PLUGIN_KUBERNETES_TOKEN} ]; then - KUBERNETES_TOKEN=$PLUGIN_KUBERNETES_TOKEN - echo "INFO: Setting client credentials with token." - kubectl config set-credentials ${KUBERNETES_USER} --token=${KUBERNETES_TOKEN} +if [ ! -z ${PLUGIN_KUBERNETES_ENV} ]; then + KUBERNETES_ENV=${PLUGIN_KUBERNETES_ENV} + + KUBERNETES_SERVER_VAR=KUBERNETES_SERVER_${KUBERNETES_ENV} + KUBERNETES_CERT_VAR=KUBERNETES_SERVER_CERT_${KUBERNETES_ENV} + + KUBERNETES_SERVER=${!KUBERNETES_SERVER_VAR} + KUBERNETES_CERT=${!KUBERNETES_CERT_VAR} + + if [[ -z "${KUBERNETES_SERVER}" ]]; then + echo "ERROR: drone secret ${KUBERNETES_SERVER_VAR} not added!" + exit 1 + fi + + if [[ -z "${KUBERNETES_CERT}" ]]; then + echo "ERROR: drone secret ${KUBERNETES_CERT_VAR} not added!" + echo "Inscure connection to the cluster will be used." + fi else - echo "ERROR: Provide either of the following authentication params:" - echo "[1] kubernetes_token" - echo "[2] kubernetes_client_cert and kubernetes_client_key" + echo "ERROR: kubernetes_env not provided" exit 1 fi -if [ ! -z ${KUBERNETES_CERT} ]; then +if [ -z ${PLUGIN_NAMESPACE} ]; then + PLUGIN_NAMESPACE="default" +fi + +if [[ ! -z "${KUBERNETES_CLIENT_CERT}" ]] && [[ ! -z "${KUBERNETES_CLIENT_KEY}" ]]; then + echo "INFO: Setting client credentials with signed-certificate and key." + echo ${KUBERNETES_CLIENT_CERT} > client.crt + echo ${KUBERNETES_CLIENT_KEY} > client.key + kubectl config set-credentials ${KUBERNETES_USER} --client-certificate=client.crt --client-key=client.key +else + echo "ERROR: Provide the following authentication params:" + echo " - kubernetes_client_cert" + echo " - kubernetes_client_key" + echo "as drone secrets" + exit 1 +fi + +if [ ! -z "${KUBERNETES_CERT}" ]; then echo "INFO: Using secure connection with tls-certificate." - echo ${KUBERNETES_CERT} | base64 -d > ca.crt + echo ${KUBERNETES_CERT} > ca.crt kubectl config set-cluster default --server=${KUBERNETES_SERVER} --certificate-authority=ca.crt else echo "WARNING: Using insecure connection to cluster" kubectl config set-cluster default --server=${KUBERNETES_SERVER} --insecure-skip-tls-verify=true fi -kubectl config set-context default --cluster=default --user=default +kubectl config set-context default --cluster=default --user=${KUBERNETES_USER} kubectl config use-context default # kubectl version From 67abd5704ebc2e2c27fe308c44173860b9989162 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Wed, 10 Jan 2018 04:35:00 +0530 Subject: [PATCH 09/27] readded base64 decode --- update.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/update.sh b/update.sh index 52f1c62..bf2633d 100755 --- a/update.sh +++ b/update.sh @@ -34,8 +34,8 @@ fi if [[ ! -z "${KUBERNETES_CLIENT_CERT}" ]] && [[ ! -z "${KUBERNETES_CLIENT_KEY}" ]]; then echo "INFO: Setting client credentials with signed-certificate and key." - echo ${KUBERNETES_CLIENT_CERT} > client.crt - echo ${KUBERNETES_CLIENT_KEY} > client.key + echo ${KUBERNETES_CLIENT_CERT} | base64 -d > client.crt + echo ${KUBERNETES_CLIENT_KEY} | base64 -d > client.key kubectl config set-credentials ${KUBERNETES_USER} --client-certificate=client.crt --client-key=client.key else echo "ERROR: Provide the following authentication params:" @@ -47,7 +47,7 @@ fi if [ ! -z "${KUBERNETES_CERT}" ]; then echo "INFO: Using secure connection with tls-certificate." - echo ${KUBERNETES_CERT} > ca.crt + echo ${KUBERNETES_CERT} | base64 -d > ca.crt kubectl config set-cluster default --server=${KUBERNETES_SERVER} --certificate-authority=ca.crt else echo "WARNING: Using insecure connection to cluster" @@ -61,7 +61,7 @@ kubectl config use-context default IFS=',' read -r -a DEPLOYMENTS <<< "${PLUGIN_DEPLOYMENT}" IFS=',' read -r -a CONTAINERS <<< "${PLUGIN_CONTAINER}" for DEPLOY in ${DEPLOYMENTS[@]}; do - echo Deploying to $KUBERNETES_SERVER + echo Deploying to ${KUBERNETES_ENV} for CONTAINER in ${CONTAINERS[@]}; do kubectl -n ${PLUGIN_NAMESPACE} set image deployment/${DEPLOY} \ ${CONTAINER}=${PLUGIN_REPO}:${PLUGIN_TAG} --record From ad2ec49271aa0ed726b2a851d6733f299feeff27 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Wed, 10 Jan 2018 05:22:05 +0530 Subject: [PATCH 10/27] fix tag quotes --- update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update.sh b/update.sh index bf2633d..9a213fd 100755 --- a/update.sh +++ b/update.sh @@ -64,6 +64,6 @@ for DEPLOY in ${DEPLOYMENTS[@]}; do echo Deploying to ${KUBERNETES_ENV} for CONTAINER in ${CONTAINERS[@]}; do kubectl -n ${PLUGIN_NAMESPACE} set image deployment/${DEPLOY} \ - ${CONTAINER}=${PLUGIN_REPO}:${PLUGIN_TAG} --record + ${CONTAINER}="${PLUGIN_REPO}:${PLUGIN_TAG}" --record done done From d8eefee1236290e8a27a89dab7ec4b508fc72fd7 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Wed, 10 Jan 2018 16:58:04 +0530 Subject: [PATCH 11/27] code-sanity --- update.sh | 88 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/update.sh b/update.sh index 9a213fd..b4be9d6 100755 --- a/update.sh +++ b/update.sh @@ -1,69 +1,71 @@ #!/bin/bash set -euo pipefail -if [ ! -z ${PLUGIN_KUBERNETES_USER} ]; then - KUBERNETES_USER=${PLUGIN_KUBERNETES_USER:-default} +# check optional params +if [ ! -z ${PLUGIN_USER} ]; then + USER=${PLUGIN_USER:-default} fi -if [ ! -z ${PLUGIN_KUBERNETES_ENV} ]; then - KUBERNETES_ENV=${PLUGIN_KUBERNETES_ENV} +if [ ! -z ${PLUGIN_NAMESPACE} ]; then + NAMESPACE=${PLUGIN_NAMESPACE:-default} +fi - KUBERNETES_SERVER_VAR=KUBERNETES_SERVER_${KUBERNETES_ENV} - KUBERNETES_CERT_VAR=KUBERNETES_SERVER_CERT_${KUBERNETES_ENV} +# check required params +if [ ! -z ${PLUGIN_CLUSTER} ]; then + CLUSTER=${PLUGIN_CLUSTER} - KUBERNETES_SERVER=${!KUBERNETES_SERVER_VAR} - KUBERNETES_CERT=${!KUBERNETES_CERT_VAR} + SERVER_URL_VAR=SERVER_URL_${CLUSTER} + SERVER_CERT_VAR=SERVER_CERT_${CLUSTER} + CLIENT_CERT_VAR=CLIENT_CERT_${CLUSTER} + CLIENT_KEY_VAR=CLIENT_KEY_${CLUSTER} - if [[ -z "${KUBERNETES_SERVER}" ]]; then - echo "ERROR: drone secret ${KUBERNETES_SERVER_VAR} not added!" + SERVER_URL=${!SERVER_URL_VAR} + SERVER_CERT=${!SERVER_CERT_VAR} + CLIENT_CERT=${!CLIENT_CERT_VAR} + CLIENT_KEY=${!CLIENT_KEY_VAR} + + if [[ -z "${SERVER_URL}" ]]; then + echo "[ERROR] drone secret: ${SERVER_URL_VAR} not added!" exit 1 fi - if [[ -z "${KUBERNETES_CERT}" ]]; then - echo "ERROR: drone secret ${KUBERNETES_CERT_VAR} not added!" - echo "Inscure connection to the cluster will be used." + if [[ ! -z "${SERVER_CERT}" ]]; then + echo "[INFO] Using secure connection with tls-certificate." + echo ${SERVER_CERT} | base64 -d > ca.crt + kubectl config set-cluster default --server=${SERVER_URL} --certificate-authority=ca.crt + + if [[ ! -z "${CLIENT_CERT}" ]] && [[ ! -z "${CLIENT_KEY}" ]]; then + echo "[INFO] Setting client credentials with signed-certificate and key." + echo ${CLIENT_CERT} | base64 -d > client.crt + echo ${CLIENT_KEY} | base64 -d > client.key + kubectl config set-credentials ${USER} --client-certificate=client.crt --client-key=client.key + else + echo "[ERROR] Required plugin parameters:" + echo " - client_cert" + echo " - client_key" + echo "are not provided" + exit 1 + fi + else + echo "[WARNING] Required plugin parameter: ${SERVER_CERT_VAR} not added!" + echo "[WARNING] Using insecure connection to cluster" + kubectl config set-cluster default --server=${SERVER_URL} --insecure-skip-tls-verify=true fi else - echo "ERROR: kubernetes_env not provided" + echo "[ERROR] Required pipeline parameter: cluster not provided" exit 1 fi -if [ -z ${PLUGIN_NAMESPACE} ]; then - PLUGIN_NAMESPACE="default" -fi - -if [[ ! -z "${KUBERNETES_CLIENT_CERT}" ]] && [[ ! -z "${KUBERNETES_CLIENT_KEY}" ]]; then - echo "INFO: Setting client credentials with signed-certificate and key." - echo ${KUBERNETES_CLIENT_CERT} | base64 -d > client.crt - echo ${KUBERNETES_CLIENT_KEY} | base64 -d > client.key - kubectl config set-credentials ${KUBERNETES_USER} --client-certificate=client.crt --client-key=client.key -else - echo "ERROR: Provide the following authentication params:" - echo " - kubernetes_client_cert" - echo " - kubernetes_client_key" - echo "as drone secrets" - exit 1 -fi - -if [ ! -z "${KUBERNETES_CERT}" ]; then - echo "INFO: Using secure connection with tls-certificate." - echo ${KUBERNETES_CERT} | base64 -d > ca.crt - kubectl config set-cluster default --server=${KUBERNETES_SERVER} --certificate-authority=ca.crt -else - echo "WARNING: Using insecure connection to cluster" - kubectl config set-cluster default --server=${KUBERNETES_SERVER} --insecure-skip-tls-verify=true -fi - -kubectl config set-context default --cluster=default --user=${KUBERNETES_USER} +kubectl config set-context default --cluster=default --user=${USER} kubectl config use-context default # kubectl version IFS=',' read -r -a DEPLOYMENTS <<< "${PLUGIN_DEPLOYMENT}" IFS=',' read -r -a CONTAINERS <<< "${PLUGIN_CONTAINER}" for DEPLOY in ${DEPLOYMENTS[@]}; do - echo Deploying to ${KUBERNETES_ENV} + echo Deploying to ${CLUSTER} for CONTAINER in ${CONTAINERS[@]}; do - kubectl -n ${PLUGIN_NAMESPACE} set image deployment/${DEPLOY} \ + kubectl -n ${NAMESPACE} set image deployment/${DEPLOY} \ ${CONTAINER}="${PLUGIN_REPO}:${PLUGIN_TAG}" --record done done From 0fe0fc584f44ab3f857992313b508cb066737700 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Wed, 10 Jan 2018 17:29:56 +0530 Subject: [PATCH 12/27] dockerfile: single run --- Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 86eb979..c6b2222 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM alpine:3.4 -RUN apk --no-cache add curl ca-certificates bash -RUN curl -Lo /usr/local/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl -RUN chmod +x /usr/local/bin/kubectl +RUN apk --no-cache add curl ca-certificates bash && \ + curl -Lo /usr/local/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \ + chmod +x /usr/local/bin/kubectl COPY update.sh /bin/ ENTRYPOINT ["/bin/bash"] CMD ["/bin/update.sh"] From 1e439538874a58c2beb44dc7f67781cd7f35904e Mon Sep 17 00:00:00 2001 From: hashfyre Date: Wed, 10 Jan 2018 17:30:40 +0530 Subject: [PATCH 13/27] script: ucase cluster --- update.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/update.sh b/update.sh index b4be9d6..6d06a96 100755 --- a/update.sh +++ b/update.sh @@ -12,13 +12,16 @@ fi # check required params if [ ! -z ${PLUGIN_CLUSTER} ]; then - CLUSTER=${PLUGIN_CLUSTER} + # convert cluster name to ucase and assign + CLUSTER=${PLUGIN_CLUSTER^^} + # create dynamic cert var names SERVER_URL_VAR=SERVER_URL_${CLUSTER} SERVER_CERT_VAR=SERVER_CERT_${CLUSTER} CLIENT_CERT_VAR=CLIENT_CERT_${CLUSTER} CLIENT_KEY_VAR=CLIENT_KEY_${CLUSTER} + # expand the var contents SERVER_URL=${!SERVER_URL_VAR} SERVER_CERT=${!SERVER_CERT_VAR} CLIENT_CERT=${!CLIENT_CERT_VAR} From 99ea3d19d5bb6b40e6c6211e1b8cbafb23614590 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Wed, 10 Jan 2018 17:30:49 +0530 Subject: [PATCH 14/27] readme: update --- README.md | 176 +++++++++++++++++------------------------------------- 1 file changed, 56 insertions(+), 120 deletions(-) diff --git a/README.md b/README.md index a47fd03..2669c4b 100644 --- a/README.md +++ b/README.md @@ -1,140 +1,76 @@ -# Kubernetes plugin for drone.io [![Docker Repository on Quay](https://quay.io/repository/honestbee/drone-kubernetes/status "Docker Repository on Quay")](https://quay.io/repository/honestbee/drone-kubernetes) +# Kubernetes plugin for drone.io [![Docker Repository on Docker Cloud](https://cloud.docker.com/app/razorpay/repository/docker/razorpay/drone-kubernetes) +## Borrowed and distilled from [honestbee/drone-kubernetes](https://github.com/honestbee/drone-kubernetes) This plugin allows to update a Kubernetes deployment. + - Cert based auth for tls + - Insecure auth without tls + +This version deprecates token based auth ## Usage This pipeline will update the `my-deployment` deployment with the image tagged `DRONE_COMMIT_SHA:0:8` ```yaml - pipeline: - deploy: - image: quay.io/honestbee/drone-kubernetes - deployment: my-deployment - repo: myorg/myrepo - container: my-container - tag: - - mytag - - latest +pipeline: + deploy: + image: razorpay/drone-kubernetes + pull: true + secrets: + - docker_username + - docker_password + - server_url_ + - server_cert_ + - client_cert_ + - client_key_ + - ... + user: + cluster: + deployment: [] + repo: + container: [ ] + namespace: + tag: + - ${DRONE_REPO_BRANCH}-${DRONE_COMMIT_SHA} + - ... + when: + environment: + branch: [ ,... ] + event: + exclude: [push, pull_request, tag] + include: [deployment] ``` -Deploying containers across several deployments, eg in a scheduler-worker setup. Make sure your container `name` in your manifest is the same for each pod. - -```yaml - pipeline: - deploy: - image: quay.io/honestbee/drone-kubernetes - deployment: [server-deploy, worker-deploy] - repo: myorg/myrepo - container: my-container - tag: - - mytag - - latest -``` - -Deploying multiple containers within the same deployment. - -```yaml - pipeline: - deploy: - image: quay.io/honestbee/drone-kubernetes - deployment: my-deployment - repo: myorg/myrepo - container: [container1, container2] - tag: - - mytag - - latest -``` - -**NOTE**: Combining multi container deployments across multiple deployments is not recommended - -This more complex example demonstrates how to deploy to several environments based on the branch, in a `app` namespace - -```yaml - pipeline: - deploy-qa: - image: quay.io/honestbee/drone-kubernetes - kubernetes_user: ${KUBERNETES_USER} - kubernetes_server: ${KUBERNETES_SERVER_QA} - kubernetes_cert: ${KUBERNETES_CERT_QA} - kubernetes_client_cert: ${PLUGIN_KUBERNETES_CLIENT_CERT} - kubernetes_client_key: ${PLUGIN_KUBERNETES_CLIENT_KEY} - deployment: my-deployment - repo: myorg/myrepo - container: my-container - namespace: app - tag: - - mytag - - latest - when: - branch: [ qa ] - - deploy-staging: - image: quay.io/honestbee/drone-kubernetes - kubernetes_user: ${KUBERNETES_USER} - kubernetes_server: ${KUBERNETES_SERVER_STAGING} - kubernetes_cert: ${KUBERNETES_CERT_STAGING} - kubernetes_token: ${KUBERNETES_TOKEN_STAGING} - deployment: my-deployment - repo: myorg/myrepo - container: my-container - namespace: app - tag: - - mytag - - latest - when: - branch: [ staging ] - - deploy-prod: - image: quay.io/honestbee/drone-kubernetes - kubernetes_server: ${KUBERNETES_SERVER_PROD} - kubernetes_token: ${KUBERNETES_TOKEN_PROD} - # notice: no tls verification will be done, warning will is printed - deployment: my-deployment - repo: myorg/myrepo - container: my-container - namespace: app - tag: - - mytag - - latest - when: - branch: [ master ] -``` ## Required secrets -```bash - drone secret add --image=honestbee/drone-kubernetes \ - your-user/your-repo KUBERNETES_SERVER https://mykubernetesapiserver - - drone secret add --image=honestbee/drone-kubernetes \ - your-user/your-repo KUBERNETES_CERT - - drone secret add --image=honestbee/drone-kubernetes \ - your-user/your-repo KUBERNETES_TOKEN eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJ... -``` + - server_url + - tls: + - server_cert + - `kubectl get secret [ your default secret name ] -o yaml | egrep 'ca.crt:' > ca.crt` + - `kubectl get secret [ your default secret name ] -o yaml | egrep 'ca.key:' > ca.key` + - client_cert + - client_key + - ``` + openssl genrsa -out client.key + openssl req -new -key client.key -out client.csr -subj "/CN=drone/O=org" + openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 500 + ``` + - ``` + cat ca.crt | base64 > car.crt.enc + cat client.crt | base64 > client.crt.enc + cat client.key | base64 > client.key.enc + ``` + - ``` + drone secret add -repository razorpay/gimli -image razorpay/drone-kubernetes -event deployment -name server_url_ -value https://k8s.org.com.:443 + drone secret add -repository razorpay/gimli -image razorpay/drone-kubernetes -event deployment -name server_cert_ -value @./ca.crt.enc + drone secret add -repository razorpay/gimli -image razorpay/drone-kubernetes -event deployment -name client_cert_ -value @./client.crt.enc + drone secret add -repository razorpay/gimli -image razorpay/drone-kubernetes -event deployment -name client_key_ -value @./client.key.enc + ``` When using TLS Verification, ensure Server Certificate used by kubernetes API server is signed for SERVER url ( could be a reason for failures if using aliases of kubernetes cluster ) -## How to get token -1. After deployment inspect you pod for name of (k8s) secret with **token** and **ca.crt** -```bash -kubectl describe po/[ your pod name ] | grep SecretName | grep token -``` -(When you use **default service account**) - -2. Get data from you (k8s) secret -```bash -kubectl get secret [ your default secret name ] -o yaml | egrep 'ca.crt:|token:' -``` -3. Copy-paste contents of ca.crt into your drone's **KUBERNETES_CERT** secret -4. Decode base64 encoded token -```bash -echo [ your k8s base64 encoded token ] | base64 -d && echo'' -``` -5. Copy-paste decoded token into your drone's **KUBERNETES_TOKEN** secret - ### RBAC When using a version of kubernetes with RBAC (role-based access control) From 78e44f22aaf1acfc795f945ebf332ba62ecc4692 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Wed, 10 Jan 2018 17:39:49 +0530 Subject: [PATCH 15/27] fix badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2669c4b..b616d33 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Kubernetes plugin for drone.io [![Docker Repository on Docker Cloud](https://cloud.docker.com/app/razorpay/repository/docker/razorpay/drone-kubernetes) +# Kubernetes plugin for drone.io [Docker Repository on Docker Cloud](https://cloud.docker.com/app/razorpay/repository/docker/razorpay/drone-kubernetes) ## Borrowed and distilled from [honestbee/drone-kubernetes](https://github.com/honestbee/drone-kubernetes) This plugin allows to update a Kubernetes deployment. From 44363261d077a83e72f4edb9bb70acbc65b901de Mon Sep 17 00:00:00 2001 From: hashfyre Date: Wed, 10 Jan 2018 18:52:00 +0530 Subject: [PATCH 16/27] readme: fix header --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b616d33..fc9250a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# Kubernetes plugin for drone.io [Docker Repository on Docker Cloud](https://cloud.docker.com/app/razorpay/repository/docker/razorpay/drone-kubernetes) +# Kubernetes plugin for drone.io +#### [Docker Repository on Docker Cloud](https://cloud.docker.com/app/razorpay/repository/docker/razorpay/drone-kubernetes) ## Borrowed and distilled from [honestbee/drone-kubernetes](https://github.com/honestbee/drone-kubernetes) This plugin allows to update a Kubernetes deployment. From e0e14785e4d1a988dcb1e9f96f3523c3b7c2f6e6 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Thu, 11 Jan 2018 12:53:45 +0530 Subject: [PATCH 17/27] base: alpine3.7 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c6b2222..bf1bbbc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.4 +FROM alpine:3.7 RUN apk --no-cache add curl ca-certificates bash && \ curl -Lo /usr/local/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \ chmod +x /usr/local/bin/kubectl From 694dddeaaf2262d4d1b073fc99a20d115ba66d2e Mon Sep 17 00:00:00 2001 From: hashfyre Date: Fri, 19 Jan 2018 13:43:19 +0530 Subject: [PATCH 18/27] script: adds command to check deployment rollout status --- update.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/update.sh b/update.sh index 6d06a96..a439397 100755 --- a/update.sh +++ b/update.sh @@ -71,4 +71,6 @@ for DEPLOY in ${DEPLOYMENTS[@]}; do kubectl -n ${NAMESPACE} set image deployment/${DEPLOY} \ ${CONTAINER}="${PLUGIN_REPO}:${PLUGIN_TAG}" --record done + # wait on deployment rollout status + kubectl -n ${NAMESPACE} rollout status deployment/${DEPLOY} done From 29350b0abe8e0c11ca0d92c77f39305ea2562428 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Fri, 19 Jan 2018 12:54:52 +0530 Subject: [PATCH 19/27] script, readme: plugin_auth_mode: token --- README.md | 11 ++++++---- update.sh | 61 ++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index fc9250a..fd872e5 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,9 @@ This plugin allows to update a Kubernetes deployment. - Cert based auth for tls + - token based auth - Insecure auth without tls -This version deprecates token based auth - ## Usage This pipeline will update the `my-deployment` deployment with the image tagged `DRONE_COMMIT_SHA:0:8` @@ -22,11 +21,12 @@ pipeline: - docker_password - server_url_ - server_cert_ - - client_cert_ - - client_key_ + - client_cert_ / - server_token_ + - client_key_ / - server_token_ - ... user: cluster: + auth_mode: [ token | client-cert ] // provide only if providing server_cert_ deployment: [] repo: container: [ ] @@ -46,6 +46,9 @@ pipeline: ## Required secrets - server_url + - token: + - server_token + - `kubectl get secret [ your default secret name ] -o yaml | egrep 'token:' > server.token` - tls: - server_cert - `kubectl get secret [ your default secret name ] -o yaml | egrep 'ca.crt:' > ca.crt` diff --git a/update.sh b/update.sh index a439397..ab9c6d2 100755 --- a/update.sh +++ b/update.sh @@ -18,14 +18,10 @@ if [ ! -z ${PLUGIN_CLUSTER} ]; then # create dynamic cert var names SERVER_URL_VAR=SERVER_URL_${CLUSTER} SERVER_CERT_VAR=SERVER_CERT_${CLUSTER} - CLIENT_CERT_VAR=CLIENT_CERT_${CLUSTER} - CLIENT_KEY_VAR=CLIENT_KEY_${CLUSTER} # expand the var contents SERVER_URL=${!SERVER_URL_VAR} SERVER_CERT=${!SERVER_CERT_VAR} - CLIENT_CERT=${!CLIENT_CERT_VAR} - CLIENT_KEY=${!CLIENT_KEY_VAR} if [[ -z "${SERVER_URL}" ]]; then echo "[ERROR] drone secret: ${SERVER_URL_VAR} not added!" @@ -35,32 +31,59 @@ if [ ! -z ${PLUGIN_CLUSTER} ]; then if [[ ! -z "${SERVER_CERT}" ]]; then echo "[INFO] Using secure connection with tls-certificate." echo ${SERVER_CERT} | base64 -d > ca.crt - kubectl config set-cluster default --server=${SERVER_URL} --certificate-authority=ca.crt + kubectl config set-cluster ${CLUSTER} --server=${SERVER_URL} --certificate-authority=ca.crt - if [[ ! -z "${CLIENT_CERT}" ]] && [[ ! -z "${CLIENT_KEY}" ]]; then - echo "[INFO] Setting client credentials with signed-certificate and key." - echo ${CLIENT_CERT} | base64 -d > client.crt - echo ${CLIENT_KEY} | base64 -d > client.key - kubectl config set-credentials ${USER} --client-certificate=client.crt --client-key=client.key - else - echo "[ERROR] Required plugin parameters:" - echo " - client_cert" - echo " - client_key" - echo "are not provided" - exit 1 + # vars based on auth_mode + if [ ! -z ${PLUGIN_AUTH_MODE} ]; then + if [[ "${PLUGIN_AUTH_MODE}" == "token" ]]; then + echo "[INFO] Using Server token to authorize" + SERVER_TOKEN_VAR=SERVER_TOKEN_${CLUSTER} + # expand + SERVER_TOKEN=${!SERVER_TOKEN_VAR} + if [[ ! -z "${SERVER_TOKEN}" ]]; then + kubectl config set-credentials ${USER} --token=${SERVER_TOKEN} + else + echo "[ERROR] Required plugin param - server_token - not provided." + exit 1 + fi + elif [[ "${PLUGIN_AUTH_MODE}" == "client-cert" ]]; then + echo "[INFO] Using Client cert and Key to authorize" + CLIENT_CERT_VAR=CLIENT_CERT_${CLUSTER} + CLIENT_KEY_VAR=CLIENT_KEY_${CLUSTER} + # expand + CLIENT_CERT=${!CLIENT_CERT_VAR} + CLIENT_KEY=${!CLIENT_KEY_VAR} + + if [[ ! -z "${CLIENT_CERT}" ]] && [[ ! -z "${CLIENT_KEY}" ]]; then + echo "[INFO] Setting client credentials with signed-certificate and key." + echo ${CLIENT_CERT} | base64 -d > client.crt + echo ${CLIENT_KEY} | base64 -d > client.key + kubectl config set-credentials ${USER} --client-certificate=client.crt --client-key=client.key + else + echo "[ERROR] Required plugin parameters:" + echo " - client_cert" + echo " - client_key" + echo "are not provided" + exit 1 + fi + else + echo "[ERROR] Required plugin param - auth_mode - not provided" + echo "[INFO] Should be either [ token | client-cert ]" + exit 1 + fi fi else echo "[WARNING] Required plugin parameter: ${SERVER_CERT_VAR} not added!" echo "[WARNING] Using insecure connection to cluster" - kubectl config set-cluster default --server=${SERVER_URL} --insecure-skip-tls-verify=true + kubectl config set-cluster ${CLUSTER} --server=${SERVER_URL} --insecure-skip-tls-verify=true fi else echo "[ERROR] Required pipeline parameter: cluster not provided" exit 1 fi -kubectl config set-context default --cluster=default --user=${USER} -kubectl config use-context default +kubectl config set-context ${CLUSTER} --cluster=${CLUSTER} --user=${USER} +kubectl config use-context ${CLUSTER} # kubectl version IFS=',' read -r -a DEPLOYMENTS <<< "${PLUGIN_DEPLOYMENT}" From 661f4705265eb0448130264c3a6756678491c15b Mon Sep 17 00:00:00 2001 From: hashfyre Date: Tue, 23 Jan 2018 12:57:45 +0530 Subject: [PATCH 20/27] temp: update script: blocking deployment watch --- update.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update.sh b/update.sh index ab9c6d2..eb74330 100755 --- a/update.sh +++ b/update.sh @@ -95,5 +95,5 @@ for DEPLOY in ${DEPLOYMENTS[@]}; do ${CONTAINER}="${PLUGIN_REPO}:${PLUGIN_TAG}" --record done # wait on deployment rollout status - kubectl -n ${NAMESPACE} rollout status deployment/${DEPLOY} + # kubectl -n ${NAMESPACE} rollout status deployment/${DEPLOY} done From e715f7e0e872b998b707b6e358c0039c292cbe21 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Thu, 25 Jan 2018 12:48:19 +0530 Subject: [PATCH 21/27] script: rewrite with functions --- update.sh | 270 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 190 insertions(+), 80 deletions(-) diff --git a/update.sh b/update.sh index eb74330..2401502 100755 --- a/update.sh +++ b/update.sh @@ -1,99 +1,209 @@ #!/bin/bash set -euo pipefail -# check optional params -if [ ! -z ${PLUGIN_USER} ]; then +# globals +USER="" +NAMESPACE="" +CLUSTER="" +DEPLOYMENTS="" +CONTAINERS="" +SERVER_URL="" + +# set globals +setUser(){ USER=${PLUGIN_USER:-default} -fi +} -if [ ! -z ${PLUGIN_NAMESPACE} ]; then +setNamespace(){ NAMESPACE=${PLUGIN_NAMESPACE:-default} -fi +} -# check required params -if [ ! -z ${PLUGIN_CLUSTER} ]; then - # convert cluster name to ucase and assign - CLUSTER=${PLUGIN_CLUSTER^^} +setDeployments(){ + IFS=',' read -r -a DEPLOYMENTS <<< "${PLUGIN_DEPLOYMENT}" +} - # create dynamic cert var names - SERVER_URL_VAR=SERVER_URL_${CLUSTER} - SERVER_CERT_VAR=SERVER_CERT_${CLUSTER} +setContainers(){ + IFS=',' read -r -a CONTAINERS <<< "${PLUGIN_CONTAINER}" +} - # expand the var contents - SERVER_URL=${!SERVER_URL_VAR} - SERVER_CERT=${!SERVER_CERT_VAR} - - if [[ -z "${SERVER_URL}" ]]; then - echo "[ERROR] drone secret: ${SERVER_URL_VAR} not added!" +setCluster(){ + if [ ! -z ${PLUGIN_CLUSTER} ]; then + # convert cluster name to ucase and assign + CLUSTER=${PLUGIN_CLUSTER^^} + else + echo "[ERROR] Required pipeline parameter: cluster not provided" exit 1 fi +} - if [[ ! -z "${SERVER_CERT}" ]]; then - echo "[INFO] Using secure connection with tls-certificate." - echo ${SERVER_CERT} | base64 -d > ca.crt - kubectl config set-cluster ${CLUSTER} --server=${SERVER_URL} --certificate-authority=ca.crt +setServerUrl(){ + # create dynamic cert var names + local SERVER_URL_VAR=SERVER_URL_${CLUSTER} + SERVER_URL=${!SERVER_URL_VAR} + if [[ -z "${SERVER_URL}" ]]; then + echo "[ERROR] Required drone secret: ${SERVER_URL_VAR} not added!" + exit 1 + fi +} - # vars based on auth_mode - if [ ! -z ${PLUGIN_AUTH_MODE} ]; then - if [[ "${PLUGIN_AUTH_MODE}" == "token" ]]; then - echo "[INFO] Using Server token to authorize" - SERVER_TOKEN_VAR=SERVER_TOKEN_${CLUSTER} - # expand - SERVER_TOKEN=${!SERVER_TOKEN_VAR} - if [[ ! -z "${SERVER_TOKEN}" ]]; then - kubectl config set-credentials ${USER} --token=${SERVER_TOKEN} - else - echo "[ERROR] Required plugin param - server_token - not provided." - exit 1 - fi - elif [[ "${PLUGIN_AUTH_MODE}" == "client-cert" ]]; then - echo "[INFO] Using Client cert and Key to authorize" - CLIENT_CERT_VAR=CLIENT_CERT_${CLUSTER} - CLIENT_KEY_VAR=CLIENT_KEY_${CLUSTER} - # expand - CLIENT_CERT=${!CLIENT_CERT_VAR} - CLIENT_KEY=${!CLIENT_KEY_VAR} +setGlobals(){ + setUser + setNamespace + setDeployments + setContainers + setCluster + setServerUrl +} - if [[ ! -z "${CLIENT_CERT}" ]] && [[ ! -z "${CLIENT_KEY}" ]]; then - echo "[INFO] Setting client credentials with signed-certificate and key." - echo ${CLIENT_CERT} | base64 -d > client.crt - echo ${CLIENT_KEY} | base64 -d > client.key - kubectl config set-credentials ${USER} --client-certificate=client.crt --client-key=client.key - else - echo "[ERROR] Required plugin parameters:" - echo " - client_cert" - echo " - client_key" - echo "are not provided" - exit 1 - fi - else - echo "[ERROR] Required plugin param - auth_mode - not provided" - echo "[INFO] Should be either [ token | client-cert ]" - exit 1 - fi +setSecureCluster(){ + local CLUSTER=$1; shift + local SERVER_URL=$1; shift + local SERVER_CERT=$1 + + echo "[INFO] Using secure connection with tls-certificate." + echo ${SERVER_CERT} | base64 -d > ca.crt + kubectl config set-cluster ${CLUSTER} --server=${SERVER_URL} --certificate-authority=ca.crt +} + +setInsecureCluster(){ + local CLUSTER=$1; shift + local SERVER_URL=$1 + + echo "[WARNING] Using insecure connection to cluster" + kubectl config set-cluster ${CLUSTER} --server=${SERVER_URL} --insecure-skip-tls-verify=true +} + +setServerToken(){ + local USER=$1; shift + local SERVER_TOKEN=$1 + + echo "[INFO] Setting client credentials with token" + kubectl config set-credentials ${USER} --token=${SERVER_TOKEN} +} + +setClientCertAndKey(){ + local USER=$1; shift + local CLIENT_CERT=$1; shift + local CLIENT_KEY=$1 + + echo "[INFO] Setting client credentials with signed-certificate and key." + echo ${CLIENT_CERT} | base64 -d > client.crt + echo ${CLIENT_KEY} | base64 -d > client.key + kubectl config set-credentials ${USER} --client-certificate=client.crt --client-key=client.key +} + +setContext(){ + local CLUSTER=$1; shift + local USER=$1 + + kubectl config set-context ${CLUSTER} --cluster=${CLUSTER} --user=${USER} + kubectl config use-context ${CLUSTER} +} + +pollDeploymentRollout(){ + local NAMESPACE=$1; shift + local DEPLOY=$1 + # wait on deployment rollout status + kubectl -n ${NAMESPACE} rollout status --watch=false --revision=0 deployment/${DEPLOY} +} + +startDeployment(){ + local CLUSTER=$1; shift + local NAMESPACE=$1; shift + local DEPLOYMENTS=$1; shift + local CONTAINERS=$1 + + for DEPLOY in ${DEPLOYMENTS[@]}; do + echo Deploying to ${CLUSTER} + for CONTAINER in ${CONTAINERS[@]}; do + kubectl -n ${NAMESPACE} set image deployment/${DEPLOY} \ + ${CONTAINER}="${PLUGIN_REPO}:${PLUGIN_TAG}" --record + done + #pollDeploymentRollout ${NAMESPACE} ${DEPLOY} + done +} + +clientAuthToken(){ + local CLUSTER=$1; shift + local USER=$1 + + echo "[INFO] Using Server token to authorize" + + CLIENT_TOKEN_VAR=CLIENT_TOKEN_${CLUSTER} + CLIENT_TOKEN=${!CLIENT_TOKEN_VAR} + + if [[ ! -z "${CLIENT_TOKEN}" ]]; then + setClientToken ${USER} ${CLIENT_TOKEN} + else + echo "[ERROR] Required plugin secrets:" + echo " - ${CLIENT_TOKEN_VAR}" + echo "not provided." + exit 1 + fi +} + +clientAuthCert(){ + local CLUSTER=$1; shift + local USER=$1 + + echo "[INFO] Using Client cert and Key to authorize" + CLIENT_CERT_VAR=CLIENT_CERT_${CLUSTER} + CLIENT_KEY_VAR=CLIENT_KEY_${CLUSTER} + # expand + CLIENT_CERT=${!CLIENT_CERT_VAR} + CLIENT_KEY=${!CLIENT_KEY_VAR} + + if [[ ! -z "${CLIENT_CERT}" ]] && [[ ! -z "${CLIENT_KEY}" ]]; then + setClientCertAndKey ${USER} ${CLIENT_CERT} ${CLIENT_KEY} + else + echo "[ERROR] Required plugin secrets:" + echo " - ${CLIENT_CERT_VAR}" + echo " - ${CLIENT_KEY_VAR}" + echo "not provided" + exit 1 + fi +} + +clientAuth(){ + local AUTH_MODE=$1; shift + local CLUSTER=$1; shift + local USER=$1 + + if [ ! -z ${AUTH_MODE} ]; then + if [[ "${AUTH_MODE}" == "token" ]]; then + clientAuthToken ${CLUSTER} ${USER} + elif [[ "${AUTH_MODE}" == "client-cert" ]]; then + clientAuthCert ${CLUSTER} ${USER} + else + echo "[ERROR] Required plugin param - auth_mode - Should be either:" + echo "[ token | client-cert ]" + exit 1 fi else - echo "[WARNING] Required plugin parameter: ${SERVER_CERT_VAR} not added!" - echo "[WARNING] Using insecure connection to cluster" - kubectl config set-cluster ${CLUSTER} --server=${SERVER_URL} --insecure-skip-tls-verify=true + echo "[ERROR] Required plugin param - auth_mode - not provided" + exit 1 fi -else - echo "[ERROR] Required pipeline parameter: cluster not provided" - exit 1 -fi +} -kubectl config set-context ${CLUSTER} --cluster=${CLUSTER} --user=${USER} -kubectl config use-context ${CLUSTER} +clusterAuth(){ + local SERVER_URL=$1; shift + local CLUSTER=$1; shift + local USER=$1 -# kubectl version -IFS=',' read -r -a DEPLOYMENTS <<< "${PLUGIN_DEPLOYMENT}" -IFS=',' read -r -a CONTAINERS <<< "${PLUGIN_CONTAINER}" -for DEPLOY in ${DEPLOYMENTS[@]}; do - echo Deploying to ${CLUSTER} - for CONTAINER in ${CONTAINERS[@]}; do - kubectl -n ${NAMESPACE} set image deployment/${DEPLOY} \ - ${CONTAINER}="${PLUGIN_REPO}:${PLUGIN_TAG}" --record - done - # wait on deployment rollout status - # kubectl -n ${NAMESPACE} rollout status deployment/${DEPLOY} -done + SERVER_CERT_VAR=SERVER_CERT_${CLUSTER} + SERVER_CERT=${!SERVER_CERT_VAR} + + if [[ ! -z "${SERVER_CERT}" ]]; then + setSecureCluster ${CLUSTER} ${SERVER_URL} ${SERVER_CERT} + AUTH_MODE=${PLUGIN_AUTH_MODE} + clientAuth ${AUTH_MODE} ${CLUSTER} ${USER} + else + echo "[WARNING] Required plugin parameter: ${SERVER_CERT_VAR} not added!" + setInsecureCluster ${CLUSTER} ${SERVER_URL} + fi +} + +setGlobals +clusterAuth ${SERVER_URL} ${CLUSTER} ${USER} +setContext ${CLUSTER} ${USER} +startDeployment ${CLUSTER} ${NAMESPACE} ${DEPLOYMENTS} ${CONTAINERS} From 41e7b9cce39950a5f6729a2a1368420505e94d4d Mon Sep 17 00:00:00 2001 From: hashfyre Date: Thu, 25 Jan 2018 16:37:09 +0530 Subject: [PATCH 22/27] script: poll rollout sans watch --- update.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/update.sh b/update.sh index 2401502..065347a 100755 --- a/update.sh +++ b/update.sh @@ -104,7 +104,14 @@ pollDeploymentRollout(){ local NAMESPACE=$1; shift local DEPLOY=$1 # wait on deployment rollout status - kubectl -n ${NAMESPACE} rollout status --watch=false --revision=0 deployment/${DEPLOY} + while true; do + result=`kubectl -n ${NAMESPACE} rollout status --watch=false --revision=0 deployment/${DEPLOY}` + if [[ "${result}" == "deployment \"${DEPLOY}\" successfully rolled out" ]]; then + exit 0 + else + sleep 10 + fi + done } startDeployment(){ @@ -119,7 +126,7 @@ startDeployment(){ kubectl -n ${NAMESPACE} set image deployment/${DEPLOY} \ ${CONTAINER}="${PLUGIN_REPO}:${PLUGIN_TAG}" --record done - #pollDeploymentRollout ${NAMESPACE} ${DEPLOY} + pollDeploymentRollout ${NAMESPACE} ${DEPLOY} done } From 60da9f684469b371f81b8f4730e46fc5274d7ee7 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Tue, 30 Jan 2018 20:58:22 +0530 Subject: [PATCH 23/27] script: rollout polling with multiple deployments --- update.sh | 59 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/update.sh b/update.sh index 065347a..43519e7 100755 --- a/update.sh +++ b/update.sh @@ -18,14 +18,6 @@ setNamespace(){ NAMESPACE=${PLUGIN_NAMESPACE:-default} } -setDeployments(){ - IFS=',' read -r -a DEPLOYMENTS <<< "${PLUGIN_DEPLOYMENT}" -} - -setContainers(){ - IFS=',' read -r -a CONTAINERS <<< "${PLUGIN_CONTAINER}" -} - setCluster(){ if [ ! -z ${PLUGIN_CLUSTER} ]; then # convert cluster name to ucase and assign @@ -49,8 +41,6 @@ setServerUrl(){ setGlobals(){ setUser setNamespace - setDeployments - setContainers setCluster setServerUrl } @@ -73,7 +63,7 @@ setInsecureCluster(){ kubectl config set-cluster ${CLUSTER} --server=${SERVER_URL} --insecure-skip-tls-verify=true } -setServerToken(){ +setClientToken(){ local USER=$1; shift local SERVER_TOKEN=$1 @@ -103,30 +93,59 @@ setContext(){ pollDeploymentRollout(){ local NAMESPACE=$1; shift local DEPLOY=$1 + local TIMEOUT=600 + # wait on deployment rollout status + echo "[INFO] Watching ${DEPLOY} rollout status..." while true; do result=`kubectl -n ${NAMESPACE} rollout status --watch=false --revision=0 deployment/${DEPLOY}` + echo ${result} if [[ "${result}" == "deployment \"${DEPLOY}\" successfully rolled out" ]]; then - exit 0 + return 0 else + # TODO: more conditions for error handling based on result text sleep 10 + TIMEOUT=$((TIMEOUT-10)) + if [ "${TIMEOUT}" -eq 0 ]; then + return 1 + fi fi done } startDeployment(){ - local CLUSTER=$1; shift local NAMESPACE=$1; shift - local DEPLOYMENTS=$1; shift - local CONTAINERS=$1 + local DEPLOY=$1; shift + local CONTAINER=$1 + + kubectl -n ${NAMESPACE} set image deployment/${DEPLOY} \ + ${CONTAINER}="${PLUGIN_REPO}:${PLUGIN_TAG}" --record + + pollDeploymentRollout ${NAMESPACE} ${DEPLOY} + if [ "$?" -eq 0 ]; then + return 0 + else + return 1 + fi +} + +startDeployments(){ + local CLUSTER=$1; shift + local NAMESPACE=$1 + + IFS=',' read -r -a DEPLOYMENTS <<< "${PLUGIN_DEPLOYMENT}" + IFS=',' read -r -a CONTAINERS <<< "${PLUGIN_CONTAINER}" for DEPLOY in ${DEPLOYMENTS[@]}; do - echo Deploying to ${CLUSTER} + echo "[INFO] Deploying ${DEPLOY} to ${CLUSTER} ${NAMESPACE}" for CONTAINER in ${CONTAINERS[@]}; do - kubectl -n ${NAMESPACE} set image deployment/${DEPLOY} \ - ${CONTAINER}="${PLUGIN_REPO}:${PLUGIN_TAG}" --record + startDeployment ${NAMESPACE} ${DEPLOY} ${CONTAINER} + if [ "$?" -eq 0 ]; then + continue + else + exit 0 + fi done - pollDeploymentRollout ${NAMESPACE} ${DEPLOY} done } @@ -213,4 +232,4 @@ clusterAuth(){ setGlobals clusterAuth ${SERVER_URL} ${CLUSTER} ${USER} setContext ${CLUSTER} ${USER} -startDeployment ${CLUSTER} ${NAMESPACE} ${DEPLOYMENTS} ${CONTAINERS} +startDeployments ${CLUSTER} ${NAMESPACE} From a72e4869ad3dc009eb863a8a35d14f480b0a2053 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Tue, 6 Feb 2018 16:14:58 +0530 Subject: [PATCH 24/27] deploy: fix multi-container deployment --- update.sh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/update.sh b/update.sh index 43519e7..7524c25 100755 --- a/update.sh +++ b/update.sh @@ -116,10 +116,10 @@ pollDeploymentRollout(){ startDeployment(){ local NAMESPACE=$1; shift local DEPLOY=$1; shift - local CONTAINER=$1 + local CONTAINER_UPDATE_LIST=$1 kubectl -n ${NAMESPACE} set image deployment/${DEPLOY} \ - ${CONTAINER}="${PLUGIN_REPO}:${PLUGIN_TAG}" --record + "${CONTAINER_UPDATE_LIST}" --record pollDeploymentRollout ${NAMESPACE} ${DEPLOY} if [ "$?" -eq 0 ]; then @@ -139,13 +139,14 @@ startDeployments(){ for DEPLOY in ${DEPLOYMENTS[@]}; do echo "[INFO] Deploying ${DEPLOY} to ${CLUSTER} ${NAMESPACE}" for CONTAINER in ${CONTAINERS[@]}; do - startDeployment ${NAMESPACE} ${DEPLOY} ${CONTAINER} - if [ "$?" -eq 0 ]; then - continue - else - exit 0 - fi + CONTAINER_UPDATE_LIST+="${CONTAINER}=${PLUGIN_REPO}:${PLUGIN_TAG} " done + startDeployment ${NAMESPACE} ${DEPLOY} ${CONTAINER_UPDATE_LIST} + if [ "$?" -eq 0 ]; then + continue + else + exit 0 + fi done } From b29f9078927b46bfeaaa41f768cc638b8908ec5f Mon Sep 17 00:00:00 2001 From: Hashfyre Date: Tue, 6 Feb 2018 20:09:06 +0530 Subject: [PATCH 25/27] Revert "fix: multi-container deployments" --- update.sh | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/update.sh b/update.sh index 7524c25..43519e7 100755 --- a/update.sh +++ b/update.sh @@ -116,10 +116,10 @@ pollDeploymentRollout(){ startDeployment(){ local NAMESPACE=$1; shift local DEPLOY=$1; shift - local CONTAINER_UPDATE_LIST=$1 + local CONTAINER=$1 kubectl -n ${NAMESPACE} set image deployment/${DEPLOY} \ - "${CONTAINER_UPDATE_LIST}" --record + ${CONTAINER}="${PLUGIN_REPO}:${PLUGIN_TAG}" --record pollDeploymentRollout ${NAMESPACE} ${DEPLOY} if [ "$?" -eq 0 ]; then @@ -139,14 +139,13 @@ startDeployments(){ for DEPLOY in ${DEPLOYMENTS[@]}; do echo "[INFO] Deploying ${DEPLOY} to ${CLUSTER} ${NAMESPACE}" for CONTAINER in ${CONTAINERS[@]}; do - CONTAINER_UPDATE_LIST+="${CONTAINER}=${PLUGIN_REPO}:${PLUGIN_TAG} " + startDeployment ${NAMESPACE} ${DEPLOY} ${CONTAINER} + if [ "$?" -eq 0 ]; then + continue + else + exit 0 + fi done - startDeployment ${NAMESPACE} ${DEPLOY} ${CONTAINER_UPDATE_LIST} - if [ "$?" -eq 0 ]; then - continue - else - exit 0 - fi done } From d5f0e5407599d9b5fa1b4181f42cf96d9bec4b82 Mon Sep 17 00:00:00 2001 From: hashfyre Date: Mon, 5 Mar 2018 18:57:56 +0530 Subject: [PATCH 26/27] script: update all containers of a dep to an image --- update.sh | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/update.sh b/update.sh index 43519e7..c4d79b0 100755 --- a/update.sh +++ b/update.sh @@ -119,8 +119,7 @@ startDeployment(){ local CONTAINER=$1 kubectl -n ${NAMESPACE} set image deployment/${DEPLOY} \ - ${CONTAINER}="${PLUGIN_REPO}:${PLUGIN_TAG}" --record - + *="${PLUGIN_REPO}:${PLUGIN_TAG}" --record pollDeploymentRollout ${NAMESPACE} ${DEPLOY} if [ "$?" -eq 0 ]; then return 0 @@ -138,14 +137,12 @@ startDeployments(){ for DEPLOY in ${DEPLOYMENTS[@]}; do echo "[INFO] Deploying ${DEPLOY} to ${CLUSTER} ${NAMESPACE}" - for CONTAINER in ${CONTAINERS[@]}; do - startDeployment ${NAMESPACE} ${DEPLOY} ${CONTAINER} - if [ "$?" -eq 0 ]; then - continue - else - exit 0 - fi - done + startDeployment ${NAMESPACE} ${DEPLOY} ${CONTAINER} + if [ "$?" -eq 0 ]; then + continue + else + exit 0 + fi done } From 35771e4e9409303b19907ce6522276226e10b93f Mon Sep 17 00:00:00 2001 From: hashfyre Date: Mon, 5 Mar 2018 19:03:29 +0530 Subject: [PATCH 27/27] script: remove containers block --- update.sh | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/update.sh b/update.sh index c4d79b0..523a87c 100755 --- a/update.sh +++ b/update.sh @@ -6,7 +6,6 @@ USER="" NAMESPACE="" CLUSTER="" DEPLOYMENTS="" -CONTAINERS="" SERVER_URL="" # set globals @@ -113,31 +112,18 @@ pollDeploymentRollout(){ done } -startDeployment(){ - local NAMESPACE=$1; shift - local DEPLOY=$1; shift - local CONTAINER=$1 - - kubectl -n ${NAMESPACE} set image deployment/${DEPLOY} \ - *="${PLUGIN_REPO}:${PLUGIN_TAG}" --record - pollDeploymentRollout ${NAMESPACE} ${DEPLOY} - if [ "$?" -eq 0 ]; then - return 0 - else - return 1 - fi -} - startDeployments(){ local CLUSTER=$1; shift local NAMESPACE=$1 IFS=',' read -r -a DEPLOYMENTS <<< "${PLUGIN_DEPLOYMENT}" - IFS=',' read -r -a CONTAINERS <<< "${PLUGIN_CONTAINER}" for DEPLOY in ${DEPLOYMENTS[@]}; do echo "[INFO] Deploying ${DEPLOY} to ${CLUSTER} ${NAMESPACE}" - startDeployment ${NAMESPACE} ${DEPLOY} ${CONTAINER} + kubectl -n ${NAMESPACE} set image deployment/${DEPLOY} \ + *="${PLUGIN_REPO}:${PLUGIN_TAG}" --record + pollDeploymentRollout ${NAMESPACE} ${DEPLOY} + if [ "$?" -eq 0 ]; then continue else