|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# Copyright 2019 Istio Authors |
| 4 | +# |
| 5 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | +# you may not use this file except in compliance with the License. |
| 7 | +# You may obtain a copy of the License at |
| 8 | +# |
| 9 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | +# |
| 11 | +# Unless required by applicable law or agreed to in writing, software |
| 12 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | +# See the License for the specific language governing permissions and |
| 15 | +# limitations under the License. |
| 16 | + |
| 17 | +# The integration test runtime is calling this script two times if istio.test.kube.controlPlaneInstaller parameter set. One call is with |
| 18 | +# install and another is with cleanup. On install script is used to convert istio in-cluster operator config to sail operator config and install istiod, istio-cni and gateways. |
| 19 | +# On cleanup istiod, istio-cni, istio-ingressgateway and istio-engressgateway are cleaned |
| 20 | +# The output log of this script is printed under working directory set by: --istio.test.work_dir/sail-operator-setup.log |
| 21 | +# Upstream WoW to call this script is documented in here: https://github.com/openshift-service-mesh/istio/tree/master/tests/integration#running-tests-on-custom-deployment |
| 22 | + |
| 23 | +LOG_FILE="$2/sail-operator-setup.log" |
| 24 | +# Redirect stdout and stderr to the log file |
| 25 | +exec > >(awk '{print strftime("[%Y-%m-%d %H:%M:%S]"), $0}' | tee -a "$LOG_FILE") 2>&1 |
| 26 | + |
| 27 | +# Exit immediately for non zero status |
| 28 | +set -e |
| 29 | +# Check unset variables |
| 30 | +set -u |
| 31 | +# Print commands |
| 32 | +set -x |
| 33 | +# fail if any command in the pipeline fails |
| 34 | +set -o pipefail |
| 35 | + |
| 36 | +SKIP_CLEANUP="${SKIP_CLEANUP:-"false"}" |
| 37 | + |
| 38 | + |
| 39 | +function usage() { |
| 40 | + echo "Usage: $0 <install|cleanup> <input_yaml>" |
| 41 | + echo "Example: $0 install /path/to/iop.yaml" |
| 42 | + exit 1 |
| 43 | +} |
| 44 | + |
| 45 | +if [[ $# -lt 2 ]]; then |
| 46 | + echo "Error: Missing required arguments." |
| 47 | + usage |
| 48 | +fi |
| 49 | + |
| 50 | +if ! command -v yq &>/dev/null; then |
| 51 | + echo "Error: 'yq' is not installed. Please install it before running the script." |
| 52 | + exit 1 |
| 53 | +fi |
| 54 | + |
| 55 | +if ! command -v helm &> /dev/null; then |
| 56 | + echo "Helm is not installed. Please install Helm before proceeding." |
| 57 | + exit 1 |
| 58 | +fi |
| 59 | + |
| 60 | +WD=$(dirname "$0") |
| 61 | +PROW="$(dirname "$WD")" |
| 62 | +ROOT="$(dirname "$PROW")" |
| 63 | + |
| 64 | +WORKDIR="$2" |
| 65 | +# iop.yaml is the static file name for istiod config created by upstream integration test runtime |
| 66 | +IOP_FILE="$2"/iop.yaml |
| 67 | +SAIL_IOP_FILE="$(basename "${IOP_FILE%.yaml}")-sail.yaml" |
| 68 | + |
| 69 | +CONVERTER_BRANCH="${CONVERTER_BRANCH:-main}" |
| 70 | + |
| 71 | +# get istio version from versions.yaml |
| 72 | +VERSION_FILE="https://raw.githubusercontent.com/istio-ecosystem/sail-operator/$CONVERTER_BRANCH/pkg/istioversion/versions.yaml" |
| 73 | +if [ -z "${ISTIO_VERSION:-}" ]; then |
| 74 | + ISTIO_VERSION="$(curl -s "$VERSION_FILE" | grep -E 'name: v[0-9]+\.[0-9]+' | sed -E 's/.*(v[0-9]+\.[0-9]+).*/\1/' | sort -Vr | head -n1)-latest" |
| 75 | +fi |
| 76 | + |
| 77 | +NAMESPACE="${NAMESPACE:-istio-system}" |
| 78 | +ISTIOCNI_NAMESPACE="${ISTIOCNI_NAMESPACE:-istio-cni}" |
| 79 | + |
| 80 | +ISTIOCNI="${PROW}/config/sail-operator/istio-cni.yaml" |
| 81 | +INGRESS_GATEWAY_VALUES="${PROW}/config/sail-operator/ingress-gateway-values.yaml" |
| 82 | +EGRESS_GATEWAY_VALUES="${PROW}/config/sail-operator/egress-gateway-values.yaml" |
| 83 | + |
| 84 | +CONVERTER_ADDRESS="https://raw.githubusercontent.com/istio-ecosystem/sail-operator/$CONVERTER_BRANCH/tools/configuration-converter.sh" |
| 85 | +CONVERTER_SCRIPT=$(basename "$CONVERTER_ADDRESS") |
| 86 | + |
| 87 | +function download_execute_converter(){ |
| 88 | + cd "${PROW}" |
| 89 | + curl -fsSL "$CONVERTER_ADDRESS" -o "$CONVERTER_SCRIPT" || { echo "Failed to download converter script"; exit 1; } |
| 90 | + chmod +x "$CONVERTER_SCRIPT" |
| 91 | + bash "$CONVERTER_SCRIPT" "$IOP_FILE" -v "$ISTIO_VERSION" -n "$NAMESPACE" || { echo "Failed to execute converter script"; exit 1; } |
| 92 | + rm "$CONVERTER_SCRIPT" |
| 93 | +} |
| 94 | + |
| 95 | +function install_istio_cni(){ |
| 96 | + oc create namespace "${ISTIOCNI_NAMESPACE}" || true |
| 97 | + TMP_ISTIOCNI=$WORKDIR/istio-cni.yaml |
| 98 | + cp "$ISTIOCNI" "$TMP_ISTIOCNI" |
| 99 | + yq -i ".spec.namespace=\"$ISTIOCNI_NAMESPACE\"" "$TMP_ISTIOCNI" |
| 100 | + yq -i ".spec.version=\"$ISTIO_VERSION\"" "$TMP_ISTIOCNI" |
| 101 | + oc apply -f "$TMP_ISTIOCNI" |
| 102 | + echo "istioCNI created." |
| 103 | +} |
| 104 | + |
| 105 | +function install_istio(){ |
| 106 | + # overwrite sailoperator version before applying it |
| 107 | + oc create namespace "${NAMESPACE}" || true |
| 108 | + if [ "${SAIL_API_VERSION:-}" != "" ]; then |
| 109 | + yq -i eval ".apiVersion = \"sailoperator.io/$SAIL_API_VERSION\"" "$WORKDIR/$SAIL_IOP_FILE" |
| 110 | + fi |
| 111 | + patch_config |
| 112 | + oc apply -f "$WORKDIR/$SAIL_IOP_FILE" || { echo "Failed to install istio"; kubectl get istio default -o yaml;} |
| 113 | + oc -n "$NAMESPACE" wait --for=condition=Available deployment/istiod --timeout=240s || { sleep 60; } |
| 114 | + echo "istiod created." |
| 115 | +} |
| 116 | + |
| 117 | +SECRET_NAME="istio-ca-secret" |
| 118 | +WEBHOOK_FILE="$PROW/config/sail-operator/validatingwebhook.yaml" |
| 119 | + |
| 120 | +function patch_config() { |
| 121 | + # adds some control plane values that are mandatory and not available in iop.yaml |
| 122 | + if [[ "$WORKDIR" == *"telemetry-tracing-zipkin"* ]]; then |
| 123 | + # Workaround until https://github.com/istio/istio/pull/55408 is merged |
| 124 | + yq eval ' |
| 125 | + .spec.values.meshConfig.enableTracing = true | |
| 126 | + .spec.values.pilot.traceSampling = 100.0 | |
| 127 | + .spec.values.global.proxy.tracer = "zipkin" |
| 128 | + ' -i "$WORKDIR/$SAIL_IOP_FILE" |
| 129 | + echo "Configured tracing for Zipkin." |
| 130 | + fi |
| 131 | + |
| 132 | + # Workaround until https://github.com/istio-ecosystem/sail-operator/issues/749 is fixed |
| 133 | + CA_BUNDLE=$(kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" -o yaml 2>/dev/null | grep "ca-cert" | awk '{print $2}') |
| 134 | + |
| 135 | + # If not found, sleep for 5 seconds and retry once |
| 136 | + if [ -z "$CA_BUNDLE" ]; then |
| 137 | + echo "Secret not found. Sleeping for 5 seconds before retrying..." |
| 138 | + sleep 5 |
| 139 | + |
| 140 | + # Retry once |
| 141 | + CA_BUNDLE=$(kubectl get secret "$SECRET_NAME" -n "$NAMESPACE" -o yaml 2>/dev/null | grep "ca-cert" | awk '{print $2}') |
| 142 | + |
| 143 | + if [ -z "$CA_BUNDLE" ]; then |
| 144 | + echo "Secret still not found after retry. Exiting." |
| 145 | + exit 1 |
| 146 | + fi |
| 147 | + fi |
| 148 | + |
| 149 | + sed -i "s|<base64-encoded-CA-cert>|$CA_BUNDLE|g" "$WEBHOOK_FILE" |
| 150 | + kubectl apply -f "$WEBHOOK_FILE" |
| 151 | + sed -i "s|$CA_BUNDLE|<base64-encoded-CA-cert>|g" "$WEBHOOK_FILE" |
| 152 | +} |
| 153 | + |
| 154 | +# Install ingress and egress gateways |
| 155 | +function install_gateways(){ |
| 156 | + helm template -n "$NAMESPACE" istio-ingressgateway "${ROOT}"/manifests/charts/gateway --values "$INGRESS_GATEWAY_VALUES" > "${WORKDIR}"/istio-ingressgateway.yaml |
| 157 | + oc apply -f "${WORKDIR}"/istio-ingressgateway.yaml |
| 158 | + helm template -n "$NAMESPACE" istio-egressgateway "${ROOT}"/manifests/charts/gateway --values "$EGRESS_GATEWAY_VALUES" > "${WORKDIR}"/istio-egressgateway.yaml |
| 159 | + oc apply -f "${WORKDIR}"/istio-egressgateway.yaml |
| 160 | + oc -n "$NAMESPACE" wait --for=condition=Available deployment/istio-ingressgateway --timeout=60s || { echo "Failed to start istio-ingressgateway"; oc get pods -n "$NAMESPACE" -o wide; oc describe pod $(oc get pods -n istio-system --no-headers | awk "$3==\"ErrImagePull\" {print $1}" | head -n 1) -n istio-system; exit 1;} |
| 161 | + oc -n "$NAMESPACE" wait --for=condition=Available deployment/istio-egressgateway --timeout=60s || { echo "Failed to start istio-egressgateway"; kubectl get istios; oc get pods -n "$NAMESPACE" -o wide; exit 1;} |
| 162 | + echo "Gateways created." |
| 163 | +} |
| 164 | + |
| 165 | +function cleanup_istio(){ |
| 166 | + kubectl delete all --all -n "$ISTIOCNI_NAMESPACE" |
| 167 | + kubectl delete all --all -n "$NAMESPACE" |
| 168 | + kubectl delete istios.sailoperator.io --all --all-namespaces --wait=true |
| 169 | + kubectl get clusterrole | grep istio | awk '{print $1}' | xargs kubectl delete clusterrole |
| 170 | + kubectl get clusterrolebinding | grep istio | awk '{print $1}' | xargs kubectl delete clusterrolebinding |
| 171 | + echo "Cleanup completed." |
| 172 | +} |
| 173 | + |
| 174 | +if [ "$1" = "install" ]; then |
| 175 | + download_execute_converter || { echo "Failed to execute converter"; exit 1; } |
| 176 | + install_istio_cni || { echo "Failed to install Istio CNI"; exit 1; } |
| 177 | + install_istio || { echo "Failed to install Istio"; exit 1; } |
| 178 | + install_gateways || { echo "Failed to install gateways"; exit 1; } |
| 179 | +elif [ "$1" = "cleanup" ]; then |
| 180 | + if [ "$SKIP_CLEANUP" = "true" ]; then |
| 181 | + echo "Skipping cleanup because SKIP_CLEANUP is set to true." |
| 182 | + else |
| 183 | + cleanup_istio || { echo "Failed to cleanup cluster"; exit 1; } |
| 184 | + fi |
| 185 | +fi |
0 commit comments