Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 114 additions & 39 deletions scripts/check_and_deploy_helm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ echo "CHART_ROOT=${CHART_ROOT}"
echo "CHART_NAME=${CHART_NAME}"
echo "REGISTRY_URL=${REGISTRY_URL}"
echo "REGISTRY_NAMESPACE=${REGISTRY_NAMESPACE}"
echo "DEPLOYMENT_FILE=${DEPLOYMENT_FILE}"
echo "USE_ISTIO_GATEWAY=${USE_ISTIO_GATEWAY}"
echo "HELM_VERSION=${HELM_VERSION}"
echo "KUBERNETES_SERVICE_ACCOUNT_NAME=${KUBERNETES_SERVICE_ACCOUNT_NAME}"
Expand Down Expand Up @@ -86,6 +85,8 @@ if [ -z "${KUBERNETES_MASTER_ADDRESS}" ]; then
echo -e "${PIPELINE_KUBERNETES_CLUSTER_NAME} not created or workers not ready"
exit 1
fi
CLUSTER_INGRESS_SUBDOMAIN=$( ibmcloud ks cluster get --cluster ${CLUSTER_ID} --json | jq -r '.ingressHostname' | cut -d, -f1 )
CLUSTER_INGRESS_SECRET=$( ibmcloud ks cluster get --cluster ${CLUSTER_ID} --json | jq -r '.ingressSecretName' | cut -d, -f1 )
fi
echo "Configuring cluster namespace"
if kubectl get namespace ${CLUSTER_NAMESPACE}; then
Expand Down Expand Up @@ -188,17 +189,85 @@ if [ -z "$RELEASE_NAME" ]; then
fi
echo -e "Release name: ${RELEASE_NAME}"

INGRESS_SET_VALUES=""
INGRESS_URL=""
if [ ! -z "${CLUSTER_INGRESS_SUBDOMAIN}" ]; then
echo "=========================================================="
echo -e "CHECKING cluster ingress configuration"
echo "Cluster is enabled for ingress."
if [ -f "${CHART_PATH}/values.yaml" ] && \
[[ '"found"' != $( yq read "${CHART_PATH}/values.yaml" --tojson | jq 'select(.ingress) | "found"' ) ]] ; then
echo -e "Did not find chart value 'ingress', will not detect."
else
# cluster has ingress subdomain and chart has detect ingress, so enable ingress
echo -e "Found helm chart value 'ingress'"
echo -e "UPDATING helm values with ingress information"
echo -e "Setting helm value: ingress.enabled=true"
INGRESS_SET_VALUES=",ingress.enabled=true"

CHART_VALUES_JSON=$( yq read "${CHART_PATH}/values.yaml" --tojson )

for((i=0; 1 ;i++)) ; do
INGRESS_HOST=$(echo "${CHART_VALUES_JSON}" | jq -r --argjson i "$i" '.ingress.hosts[$i]?' )
if [ -z "${INGRESS_HOST}" ] || [ 'null' = "${INGRESS_HOST}" ] ; then
break;
fi
if echo "${INGRESS_HOST}" | grep -q "cluster-ingress-subdomain" ; then
# ${var/regexp/str} variable replace syntax
INGRESS_HOST_UPDATED="${INGRESS_HOST/cluster-ingress-subdomain/$CLUSTER_INGRESS_SUBDOMAIN}"
echo "Upating ingress host: ${INGRESS_HOST} -> ingress.hosts[$i]=${INGRESS_HOST_UPDATED}"
INGRESS_SET_VALUES="${INGRESS_SET_VALUES},ingress.hosts[$i]=${INGRESS_HOST_UPDATED}"
INGRESS_HOST=$INGRESS_HOST_UPDATED
fi
if [ "$i" == "0" ] ; then
# Note, may be overwritten by https url below
INGRESS_URL="http://${INGRESS_HOST}"
echo "Found ingress http url: ${INGRESS_URL}"
fi
done
for((i=0; 1 ;i++)) ; do
INGRESS_TLS=$(echo "${CHART_VALUES_JSON}" | jq -r --argjson i "$i" '.ingress.tls[$i]?' )
if [ -z "${INGRESS_TLS}" ] || [ 'null' = "${INGRESS_TLS}" ] ; then
break;
fi
INGRESS_TLS_SECRET_NAME=$(echo "${CHART_VALUES_JSON}" | jq -r --argjson i "$i" '.ingress.tls[$i].secretName' )
if echo "${INGRESS_TLS_SECRET_NAME}" | grep -q "cluster-ingress-secret" ; then
INGRESS_TLS_SECRET_UPDATED="${INGRESS_TLS_SECRET_NAME/cluster-ingress-secret/$CLUSTER_INGRESS_SECRET}"
echo "Upating ingress tls secretName: ${INGRESS_TLS_SECRET_NAME} -> ingress.tls[$i].secretName=${INGRESS_TLS_SECRET_UPDATED}"
INGRESS_SET_VALUES="${INGRESS_SET_VALUES},ingress.tls[$i].secretName=${INGRESS_TLS_SECRET_UPDATED}"
fi
for((j=0; 1 ;j++)) ; do
INGRESS_TLS_HOST=$(echo "${CHART_VALUES_JSON}" | jq -r --argjson i "$i" --argjson j "$j" '.ingress.tls[$i].hosts[$j]?' )
if [ -z "${INGRESS_TLS_HOST}" ] || [ 'null' = "${INGRESS_TLS_HOST}" ] ; then
break;
fi
if echo "${INGRESS_TLS_HOST}" | grep -q "cluster-ingress-subdomain" ; then
INGRESS_TLS_HOST_UPDATED="${INGRESS_TLS_HOST/cluster-ingress-subdomain/$CLUSTER_INGRESS_SUBDOMAIN}"
echo "Upating ingress tls host: ${INGRESS_TLS_HOST} -> ingress.tls[$i].hosts[$j]=${INGRESS_TLS_HOST_UPDATED}"
INGRESS_SET_VALUES="${INGRESS_SET_VALUES},ingress.tls[$i].hosts[$j]=${INGRESS_TLS_HOST_UPDATED}"
INGRESS_TLS_HOST=$INGRESS_TLS_HOST_UPDATED
fi
if [ "$i" == "0" ] && [ "$j" == "0" ] ; then
# prefer the tls/https host rather than http
INGRESS_URL="https://${INGRESS_TLS_HOST}"
echo "Found ingress https url: ${INGRESS_URL}"
fi
done
done
fi
fi

echo "=========================================================="
echo "DEPLOYING HELM chart"
IMAGE_REPOSITORY=${REGISTRY_URL}/${REGISTRY_NAMESPACE}/${IMAGE_NAME}
IMAGE_PULL_SECRET_NAME="ibmcloud-toolchain-${PIPELINE_TOOLCHAIN_ID}-${REGISTRY_URL}"

# Using 'upgrade --install" for rolling updates. Note that subsequent updates will occur in the same namespace the release is currently deployed in, ignoring the explicit--namespace argument".
echo -e "Dry run into: ${PIPELINE_KUBERNETES_CLUSTER_NAME}/${CLUSTER_NAMESPACE}."
helm upgrade ${RELEASE_NAME} ${CHART_PATH} ${HELM_TLS_OPTION} --install --debug --dry-run --set image.repository=${IMAGE_REPOSITORY},image.tag=${IMAGE_TAG},image.pullSecret=${IMAGE_PULL_SECRET_NAME} ${HELM_UPGRADE_EXTRA_ARGS} --namespace ${CLUSTER_NAMESPACE}
helm upgrade ${RELEASE_NAME} ${CHART_PATH} ${HELM_TLS_OPTION} --install --debug --dry-run --set image.repository=${IMAGE_REPOSITORY},image.tag=${IMAGE_TAG},image.pullSecret=${IMAGE_PULL_SECRET_NAME}${INGRESS_SET_VALUES} ${HELM_UPGRADE_EXTRA_ARGS} --namespace ${CLUSTER_NAMESPACE}

echo -e "Deploying into: ${PIPELINE_KUBERNETES_CLUSTER_NAME}/${CLUSTER_NAMESPACE}."
helm upgrade ${RELEASE_NAME} ${CHART_PATH} ${HELM_TLS_OPTION} --install --set image.repository=${IMAGE_REPOSITORY},image.tag=${IMAGE_TAG},image.pullSecret=${IMAGE_PULL_SECRET_NAME} ${HELM_UPGRADE_EXTRA_ARGS} --namespace ${CLUSTER_NAMESPACE}
helm upgrade ${RELEASE_NAME} ${CHART_PATH} ${HELM_TLS_OPTION} --install --set image.repository=${IMAGE_REPOSITORY},image.tag=${IMAGE_TAG},image.pullSecret=${IMAGE_PULL_SECRET_NAME}${INGRESS_SET_VALUES} ${HELM_UPGRADE_EXTRA_ARGS} --namespace ${CLUSTER_NAMESPACE}

echo "=========================================================="
echo -e "CHECKING deployment status of release ${RELEASE_NAME} with image tag: ${IMAGE_TAG}"
Expand Down Expand Up @@ -266,10 +335,10 @@ echo "DEPLOYED PODS:"
kubectl describe pods --selector app=${APP_NAME} --namespace ${CLUSTER_NAMESPACE}

# lookup service for current release
APP_SERVICE=$(kubectl get services --namespace ${CLUSTER_NAMESPACE} -o json | jq -r ' .items[] | select (.spec.selector.release=="'"${RELEASE_NAME}"'") | .metadata.name ')
APP_SERVICE=$(kubectl get services --namespace ${CLUSTER_NAMESPACE} -o json | jq -r ' .items[] | select (.spec.selector.release=="'"${RELEASE_NAME}"'" and .spec.type=="NodePort") | .metadata.name ')
if [ -z "${APP_SERVICE}" ]; then
# lookup service for current app
APP_SERVICE=$(kubectl get services --namespace ${CLUSTER_NAMESPACE} -o json | jq -r ' .items[] | select (.spec.selector.app=="'"${APP_NAME}"'") | .metadata.name ')
# lookup service for current app with NodePort type
APP_SERVICE=$(kubectl get services --namespace ${CLUSTER_NAMESPACE} -o json | jq -r ' .items[] | select select (.spec.selector.app=="'"${APP_NAME}"'" and .spec.type=="NodePort") | .metadata.name ')
fi
if [ ! -z "${APP_SERVICE}" ]; then
echo -e "SERVICE: ${APP_SERVICE}"
Expand All @@ -280,41 +349,47 @@ fi
echo ""
echo "=========================================================="
echo "DEPLOYMENT SUCCEEDED"
if [ ! -z "${APP_SERVICE}" ]; then
echo ""
if [ "${USE_ISTIO_GATEWAY}" = true ]; then
PORT=$( kubectl get svc istio-ingressgateway -n istio-system -o json | jq -r '.spec.ports[] | select (.name=="http2") | .nodePort ' )
echo -e "*** istio gateway enabled ***"
else
PORT=$( kubectl get services --namespace ${CLUSTER_NAMESPACE} | grep ${APP_SERVICE} | sed 's/.*:\([0-9]*\).*/\1/g' )
fi
if [ -z "${KUBERNETES_MASTER_ADDRESS}" ]; then
echo "Using first worker node ip address as NodeIP: ${IP_ADDR}"
else
# check if a route resource exists in the this kubernetes cluster
if kubectl explain route > /dev/null 2>&1; then
# Assuming the kubernetes target cluster is an openshift cluster
# Check if a route exists for exposing the service ${APP_SERVICE}
if kubectl get routes --namespace ${CLUSTER_NAMESPACE} -o json | jq --arg service "$APP_SERVICE" -e '.items[] | select(.spec.to.name==$service)'; then
echo "Existing route to expose service $APP_SERVICE"
else
# create OpenShift route
if [ "${CLUSTER_INGRESS_SUBDOMAIN}" ] && [ "${INGRESS_URL}" ]; then
# Expose app using ingress URL
export APP_URL="${INGRESS_URL}" # using 'export', the env var gets passed to next job in stage
echo -e "VIEW THE APPLICATION AT: ${APP_URL}"
else
if [ ! -z "${APP_SERVICE}" ]; then
echo ""
if [ "${USE_ISTIO_GATEWAY}" = true ]; then
PORT=$( kubectl get svc istio-ingressgateway -n istio-system -o json | jq -r '.spec.ports[] | select (.name=="http2") | .nodePort ' )
echo -e "*** istio gateway enabled ***"
else
PORT=$( kubectl get service "${APP_SERVICE}" --namespace "${CLUSTER_NAMESPACE}" -o json | jq -r '.spec.ports[0].nodePort' )
fi
if [ -z "${KUBERNETES_MASTER_ADDRESS}" ]; then
echo "Using first worker node ip address as NodeIP: ${IP_ADDR}"
else
# check if a route resource exists in the this kubernetes cluster
if kubectl explain route > /dev/null 2>&1; then
# Assuming the kubernetes target cluster is an openshift cluster
# Check if a route exists for exposing the service ${APP_SERVICE}
if kubectl get routes --namespace ${CLUSTER_NAMESPACE} -o json | jq --arg service "$APP_SERVICE" -e '.items[] | select(.spec.to.name==$service)'; then
echo "Existing route to expose service $APP_SERVICE"
else
# create OpenShift route
cat > test-route.json << EOF
{"apiVersion":"route.openshift.io/v1","kind":"Route","metadata":{"name":"${APP_SERVICE}"},"spec":{"to":{"kind":"Service","name":"${APP_SERVICE}"}}}
EOF
echo ""
cat test-route.json
kubectl apply -f test-route.json --validate=false --namespace ${CLUSTER_NAMESPACE}
kubectl get routes --namespace ${CLUSTER_NAMESPACE}
echo ""
cat test-route.json
kubectl apply -f test-route.json --validate=false --namespace ${CLUSTER_NAMESPACE}
kubectl get routes --namespace ${CLUSTER_NAMESPACE}
fi
echo "LOOKING for host in route exposing service $APP_SERVICE"
IP_ADDR=$(kubectl get routes --namespace ${CLUSTER_NAMESPACE} -o json | jq --arg service "$APP_SERVICE" -r '.items[] | select(.spec.to.name==$service) | .status.ingress[0].host')
PORT=80
else
# Use the KUBERNETES_MASTER_ADRESS
IP_ADDR=${KUBERNETES_MASTER_ADDRESS}
fi
echo "LOOKING for host in route exposing service $APP_SERVICE"
IP_ADDR=$(kubectl get routes --namespace ${CLUSTER_NAMESPACE} -o json | jq --arg service "$APP_SERVICE" -r '.items[] | select(.spec.to.name==$service) | .status.ingress[0].host')
PORT=80
else
# Use the KUBERNETES_MASTER_ADRESS
IP_ADDR=${KUBERNETES_MASTER_ADDRESS}
fi
fi
export APP_URL=http://${IP_ADDR}:${PORT} # using 'export', the env var gets passed to next job in stage
echo -e "VIEW THE APPLICATION AT: ${APP_URL}"
fi
export APP_URL=http://${IP_ADDR}:${PORT} # using 'export', the env var gets passed to next job in stage
echo -e "VIEW THE APPLICATION AT: ${APP_URL}"
fi
fi