#!/bin/bash # Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/) # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ######################################################################################################################## # Read deployment settings ######################################################################################################################## # If not already set, set the namespace where NATS will be deployed. export NATS_NAMESPACE=${NATS_NAMESPACE:-"nats"} # If not already set, set the name of the secret where NATS data and credentials will be stored. export NATS_SECRET_NAME=${NATS_SECRET_NAME:-"nats-data"} # If not already set, set the namespace where the secret containing NATS data and credentials will be stored. export NATS_SECRET_NAMESPACE=${NATS_SECRET_NAMESPACE:-"tfs"} # If not already set, disable flag for re-deploying NATS from scratch. # WARNING: ACTIVATING THIS FLAG IMPLIES LOOSING THE MESSAGE BROKER INFORMATION! # If NATS_REDEPLOY is "YES", the message broker will be dropped while checking/deploying NATS. export NATS_REDEPLOY=${NATS_REDEPLOY:-""} ######################################################################################################################## # Automated steps start here ######################################################################################################################## # Constants TMP_FOLDER="./tmp" NATS_MANIFESTS_PATH="manifests/nats" # Create a tmp folder for files modified during the deployment TMP_MANIFESTS_FOLDER="$TMP_FOLDER/manifests" mkdir -p $TMP_MANIFESTS_FOLDER function nats_deploy_single() { echo "NATS Namespace" echo ">>> Create NATS Namespace (if missing)" kubectl create namespace ${NATS_NAMESPACE} echo echo "Add NATS Helm Chart" helm3 repo add nats https://nats-io.github.io/k8s/helm/charts/ echo echo "Install NATS (single-node)" echo ">>> Checking if NATS is deployed..." if kubectl get --namespace ${NATS_NAMESPACE} statefulset/nats &> /dev/null; then echo ">>> NATS is present; skipping step." else echo ">>> Deploy NATS" helm3 install nats nats/nats --namespace ${NATS_NAMESPACE} --set nats.image.tag=2.9-alpine echo ">>> Waiting NATS statefulset to be created..." while ! kubectl get --namespace ${NATS_NAMESPACE} statefulset/nats &> /dev/null; do printf "%c" "." sleep 1 done # Wait for statefulset condition "Available=True" does not work # Wait for statefulset condition "jsonpath='{.status.readyReplicas}'=3" throws error: # "error: readyReplicas is not found" # Workaround: Check the pods are ready #echo ">>> NATS statefulset created. Waiting for readiness condition..." #kubectl wait --namespace ${NATS_NAMESPACE} --for=condition=Available=True --timeout=300s statefulset/nats #kubectl wait --namespace ${NATS_NAMESPACE} --for=jsonpath='{.status.readyReplicas}'=3 --timeout=300s \ # statefulset/nats echo ">>> NATS statefulset created. Waiting NATS pods to be created..." while ! kubectl get --namespace ${NATS_NAMESPACE} pod/nats-0 &> /dev/null; do printf "%c" "." sleep 1 done kubectl wait --namespace ${NATS_NAMESPACE} --for=condition=Ready --timeout=300s pod/nats-0 fi echo echo "NATS Port Mapping" echo ">>> Expose NATS Client port (4222)" NATS_CLIENT_PORT=$(kubectl --namespace ${NATS_NAMESPACE} get service nats -o 'jsonpath={.spec.ports[?(@.name=="client")].port}') PATCH='{"data": {"'${NATS_CLIENT_PORT}'": "'${NATS_NAMESPACE}'/nats:'${NATS_CLIENT_PORT}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" PORT_MAP='{"containerPort": '${NATS_CLIENT_PORT}', "hostPort": '${NATS_CLIENT_PORT}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" echo echo ">>> Expose NATS HTTP Mgmt GUI port (8222)" NATS_GUI_PORT=$(kubectl --namespace ${NATS_NAMESPACE} get service nats -o 'jsonpath={.spec.ports[?(@.name=="monitor")].port}') PATCH='{"data": {"'${NATS_GUI_PORT}'": "'${NATS_NAMESPACE}'/nats:'${NATS_GUI_PORT}'"}}' kubectl patch configmap nginx-ingress-tcp-microk8s-conf --namespace ingress --patch "${PATCH}" PORT_MAP='{"containerPort": '${NATS_GUI_PORT}', "hostPort": '${NATS_GUI_PORT}'}' CONTAINER='{"name": "nginx-ingress-microk8s", "ports": ['${PORT_MAP}']}' PATCH='{"spec": {"template": {"spec": {"containers": ['${CONTAINER}']}}}}' kubectl patch daemonset nginx-ingress-microk8s-controller --namespace ingress --patch "${PATCH}" echo echo "Create secret with NATS data" kubectl create secret generic ${NATS_SECRET_NAME} --namespace ${NATS_SECRET_NAMESPACE} --type='Opaque' \ --from-literal=namespace=${NATS_NAMESPACE} \ --from-literal=client_port=${NATS_CLIENT_PORT} \ --from-literal=gui_port=${NATS_GUI_PORT} kubectl get all --all-namespaces } function nats_undeploy_single() { echo "Delete secret with NATS data" kubectl delete secret ${NATS_SECRET_NAME} --namespace ${NATS_SECRET_NAMESPACE} --ignore-not-found echo echo "NATS" echo ">>> Checking if NATS is deployed..." if kubectl get --namespace ${NATS_NAMESPACE} statefulset/nats &> /dev/null; then echo ">>> Undeploy NATS" helm3 uninstall --namespace ${NATS_NAMESPACE} nats else echo ">>> NATS is not present; skipping step." fi echo echo "NATS Namespace" echo ">>> Delete NATS Namespace (if exists)" kubectl delete namespace ${NATS_NAMESPACE} --ignore-not-found echo } if [ "$NATS_REDEPLOY" == "YES" ]; then nats_undeploy_single fi nats_deploy_single