| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 1 | #!/bin/bash |
| 2 | # |
| 3 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | # you may not use this file except in compliance with the License. |
| 5 | # You may obtain a copy of the License at |
| 6 | # |
| 7 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | # |
| 9 | # Unless required by applicable law or agreed to in writing, software |
| 10 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | # See the License for the specific language governing permissions and |
| 13 | # limitations under the License. |
| 14 | # |
| 15 | |
| 16 | set -e -o pipefail |
| 17 | |
| 18 | HERE=$(dirname "$(readlink --canonicalize "$BASH_SOURCE")") |
| 19 | source "${HERE}/../library/functions.sh" |
| 20 | source "${HERE}/../library/trap.sh" |
| 21 | source "${HERE}/../library/logging" |
| 22 | source "${HERE}/../library/track" |
| 23 | |
| 24 | source "${HERE}/00-default-install-options.rc" |
| 25 | [ ! -f "${OSM_HOME_DIR}/user-install-options.rc" ] || source "${OSM_HOME_DIR}/user-install-options.rc" |
| 26 | source "${CREDENTIALS_DIR}/git_environment.rc" |
| 27 | |
| 28 | OSM_HELM_WORK_DIR="/etc/osm/helm" |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 29 | KUBECONFIG_AUX_CLUSTER_FILE="${OSM_HOME_DIR}/clusters/kubeconfig-aux-svc.yaml" |
| 30 | KUBECONFIG_MGMT_CLUSTER_FILE="${OSM_HOME_DIR}/clusters/kubeconfig-mgmt.yaml" |
| 31 | [ "${HERE}" == "/usr/share/osm-devops/installers" ] || OSM_HELM_UPDATE_DEPENDENCIES="y" |
| 32 | OSM_GITOPS_ENABLED=${INSTALL_MGMT_CLUSTER:-"y"} |
| 33 | |
| 34 | # TODO: move this to a parent script that creates the VM |
| 35 | mkdir -p "${OSM_HOME_DIR}/clusters" |
| 36 | if [ -n "${KUBECONFIG_OSM_CLUSTER}" ]; then |
| 37 | cp "${KUBECONFIG_OSM_CLUSTER}" "${OSM_HOME_DIR}/clusters/kubeconfig-osm.yaml" |
| 38 | else |
| 39 | cp "${HOME}/.kube/config" "${OSM_HOME_DIR}/clusters/kubeconfig-osm.yaml" |
| 40 | fi |
| 41 | |
| 42 | export KUBECONFIG="${OSM_HOME_DIR}/clusters/kubeconfig-osm.yaml" |
| garciadeblas | 0df99ed | 2025-09-09 14:00:42 +0200 | [diff] [blame] | 43 | if [ -z "${OSM_BASE_DOMAIN}" ]; then |
| 44 | echo "OSM_BASE_DOMAIN is not set, will try to set it from the nginx ingress controller load balancer IP" |
| garciadeblas | 8a28f6d | 2025-06-11 11:11:56 +0200 | [diff] [blame] | 45 | OSM_K8S_NGINX_IPADDRESS=$(kubectl get svc ingress-nginx-controller -n ingress-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null) |
| garciadeblas | 0df99ed | 2025-09-09 14:00:42 +0200 | [diff] [blame] | 46 | OSM_BASE_DOMAIN="${OSM_BASE_DOMAIN:-"${OSM_K8S_NGINX_IPADDRESS}.nip.io"}" |
| garciadeblas | 8a28f6d | 2025-06-11 11:11:56 +0200 | [diff] [blame] | 47 | fi |
| garciadeblas | 0df99ed | 2025-09-09 14:00:42 +0200 | [diff] [blame] | 48 | echo "Using OSM_BASE_DOMAIN=${OSM_BASE_DOMAIN}" |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 49 | |
| 50 | # Create folder to store helm values |
| 51 | sudo mkdir -p ${OSM_HELM_WORK_DIR} |
| 52 | |
| 53 | # Saving secrets |
| 54 | echo "Creating namespace ${OSM_NAMESPACE}" |
| garciadeblas | 8a28f6d | 2025-06-11 11:11:56 +0200 | [diff] [blame] | 55 | kubectl get ns "${OSM_NAMESPACE}" >/dev/null 2>&1 || kubectl create ns "${OSM_NAMESPACE}" |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 56 | echo "Saving age keys in OSM cluster" |
| garciadeblas | 8a28f6d | 2025-06-11 11:11:56 +0200 | [diff] [blame] | 57 | kubectl -n ${OSM_NAMESPACE} get secret mgmt-cluster-age-keys >/dev/null 2>&1 || \ |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 58 | kubectl -n ${OSM_NAMESPACE} create secret generic mgmt-cluster-age-keys --from-file=privkey="${CREDENTIALS_DIR}/age.mgmt.key" --from-file=pubkey="${CREDENTIALS_DIR}/age.mgmt.pub" |
| 59 | echo "Creating secrets with kubeconfig files" |
| garciadeblas | 8a28f6d | 2025-06-11 11:11:56 +0200 | [diff] [blame] | 60 | if [ -f "${KUBECONFIG_AUX_CLUSTER_FILE}" ]; then |
| 61 | kubectl -n ${OSM_NAMESPACE} get secret auxcluster-secret >/dev/null 2>&1 || \ |
| 62 | kubectl -n ${OSM_NAMESPACE} create secret generic auxcluster-secret --from-file=kubeconfig="${KUBECONFIG_AUX_CLUSTER_FILE}" |
| 63 | fi |
| 64 | if [ -f "${KUBECONFIG_MGMT_CLUSTER_FILE}" ]; then |
| 65 | kubectl -n ${OSM_NAMESPACE} get secret mgmtcluster-secret >/dev/null 2>&1 || \ |
| 66 | kubectl -n ${OSM_NAMESPACE} create secret generic mgmtcluster-secret --from-file=kubeconfig="${KUBECONFIG_MGMT_CLUSTER_FILE}" |
| 67 | fi |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 68 | # Update helm dependencies |
| 69 | [ -n "${OSM_HELM_UPDATE_DEPENDENCIES}" ] && \ |
| 70 | echo "Updating helm dependencies" && \ |
| 71 | helm dependency update "${HERE}/helm/osm" |
| 72 | |
| 73 | # Generate helm values to be passed with --set |
| 74 | OSM_HELM_OPTS="" |
| 75 | # OSM_HELM_OPTS="${OSM_HELM_OPTS} --set nbi.useOsmSecret=false" |
| garciadeblas | 578ac92 | 2025-09-08 17:17:23 +0200 | [diff] [blame] | 76 | [ -n "${OSM_HELM_TIMEOUT}" ] && OSM_HELM_OPTS="${OSM_HELM_OPTS} --timeout ${OSM_HELM_TIMEOUT}" |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 77 | |
| 78 | # TODO: review if next line is really needed or should be conditional to DOCKER_REGISTRY_URL not empty |
| 79 | # [ -n "${DOCKER_REGISTRY_URL}" ] && OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.image.repository=${DOCKER_REGISTRY_URL}${DOCKER_USER}" |
| 80 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.image.repositoryBase=${DOCKER_REGISTRY_URL}${DOCKER_USER}" |
| garciadeblas | 24a20d1 | 2025-09-10 17:09:06 +0200 | [diff] [blame] | 81 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set airflow.defaultAirflowRepository=${DOCKER_REGISTRY_URL}${DOCKER_USER}/airflow" |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 82 | [ ! "$OSM_DOCKER_TAG" == "testing-daily" ] && OSM_HELM_OPTS="${OSM_HELM_OPTS} --set-string global.image.tag=${OSM_DOCKER_TAG}" |
| garciadeblas | 24a20d1 | 2025-09-10 17:09:06 +0200 | [diff] [blame] | 83 | [ ! "$OSM_DOCKER_TAG" == "testing-daily" ] && OSM_HELM_OPTS="${OSM_HELM_OPTS} --set-string airflow.defaultAirflowTag=${OSM_DOCKER_TAG}" |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 84 | [ ! "$OSM_DOCKER_TAG" == "testing-daily" ] && OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.server.sidecarContainers.prometheus-config-sidecar.image=${DOCKER_REGISTRY_URL}${DOCKER_USER}/prometheus:${OSM_DOCKER_TAG}" |
| 85 | |
| garciadeblas | 8a28f6d | 2025-06-11 11:11:56 +0200 | [diff] [blame] | 86 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.hostname=${OSM_BASE_DOMAIN}" |
| garciadeblas | b89a41f | 2025-09-09 13:07:50 +0200 | [diff] [blame] | 87 | if [ -n "${OSM_CLUSTER_INGRESS_CLASS}" ]; then |
| 88 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.ingressClassName=${OSM_CLUSTER_INGRESS_CLASS}" |
| 89 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set grafana.ingress.ingressClassName=${OSM_CLUSTER_INGRESS_CLASS}" |
| 90 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.server.ingress.ingressClassName=${OSM_CLUSTER_INGRESS_CLASS}" |
| 91 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set airflow.ingress.web.ingressClassName=${OSM_CLUSTER_INGRESS_CLASS}" |
| 92 | # OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.alertmanager.ingress.ingressClassName=${OSM_CLUSTER_INGRESS_CLASS}" |
| 93 | fi |
| garciadeblas | 8a28f6d | 2025-06-11 11:11:56 +0200 | [diff] [blame] | 94 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set grafana.ingress.hosts={grafana.${OSM_BASE_DOMAIN}}" |
| garciadeblas | ae4f2eb | 2026-01-15 11:31:20 +0100 | [diff] [blame] | 95 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set grafana.ingress.tls[0].secretName=grafana-cert" |
| 96 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set grafana.ingress.tls[0].hosts={grafana.${OSM_BASE_DOMAIN}}" |
| garciadeblas | 8a28f6d | 2025-06-11 11:11:56 +0200 | [diff] [blame] | 97 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.server.ingress.hosts={prometheus.${OSM_BASE_DOMAIN}}" |
| garciadeblas | ae4f2eb | 2026-01-15 11:31:20 +0100 | [diff] [blame] | 98 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.server.ingress.tls[0].secretName=prometheus-cert" |
| 99 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.server.ingress.tls[0].hosts={prometheus.${OSM_BASE_DOMAIN}}" |
| 100 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set airflow.ingress.web.hosts[0].name=airflow.${OSM_BASE_DOMAIN}" |
| 101 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set airflow.ingress.web.hosts[0].tls.enabled=true" |
| 102 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set airflow.ingress.web.hosts[0].tls.secretName=airflow-cert" |
| garciadeblas | 8a28f6d | 2025-06-11 11:11:56 +0200 | [diff] [blame] | 103 | # OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.alertmanager.ingress.hosts={alertmanager.${OSM_BASE_DOMAIN}}" |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 104 | if [ -z "${OSM_GITOPS_ENABLED}" ]; then |
| 105 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.gitops.enabled=false" |
| 106 | else |
| garciadeblas | 823d8a3 | 2025-07-08 10:41:53 +0200 | [diff] [blame] | 107 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.gitops.gitBaseUrl=${GIT_BASE_HTTP_URL}" |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 108 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.gitops.fleetRepoUrl=${FLEET_REPO_HTTP_URL}" |
| 109 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.gitops.swcatalogsRepoUrl=${SW_CATALOGS_REPO_HTTP_URL}" |
| 110 | # TODO: evaluate if we need to set two git user names, one for fleet and one for sw-catalogs |
| garciadeblas | 823d8a3 | 2025-07-08 10:41:53 +0200 | [diff] [blame] | 111 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.gitops.gitUser=${GIT_BASE_USERNAME}" |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 112 | AGE_MGMT_PUBKEY=$(tr -d '\n' < ${CREDENTIALS_DIR}/age.mgmt.pub) |
| 113 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.gitops.pubkey=${AGE_MGMT_PUBKEY}" |
| 114 | fi |
| 115 | |
| 116 | if [ -n "${OSM_BEHIND_PROXY}" ]; then |
| 117 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.behindHttpProxy=true" |
| 118 | [ -n "${HTTP_PROXY}" ] && OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.httpProxy.HTTP_PROXY=\"${HTTP_PROXY}\"" |
| 119 | [ -n "${HTTPS_PROXY}" ] && OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.httpProxy.HTTPS_PROXY=\"${HTTPS_PROXY}\"" |
| 120 | if [ -n "${NO_PROXY}" ]; then |
| 121 | if [[ ! "${NO_PROXY}" =~ .*".svc".* ]]; then |
| 122 | NO_PROXY="${NO_PROXY},.svc" |
| 123 | fi |
| 124 | if [[ ! "${NO_PROXY}" =~ .*".cluster.local".* ]]; then |
| 125 | NO_PROXY="${NO_PROXY},.cluster.local" |
| 126 | fi |
| 127 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.httpProxy.NO_PROXY=\"${NO_PROXY//,/\,}\"" |
| 128 | fi |
| 129 | fi |
| 130 | |
| garciadeblas | 0b1c75c | 2025-11-11 23:04:39 +0100 | [diff] [blame] | 131 | # Only applicable to OSM CICD pipeline |
| 132 | # Test specific modules specified in MODULES_FOR_TESTING, using docker tag MODULE_DOCKER_TAG |
| 133 | if [ -n "${MODULES_FOR_TESTING}" ]; then |
| 134 | for module in MON NBI RO LCM KEYSTONE NGUI NG-SA prometheus webhookTranslator; do |
| 135 | if echo ${MODULES_FOR_TESTING} | grep -q ${module} ; then |
| 136 | if [ "${module}" == "NG-SA" ]; then |
| 137 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set-string airflow.defaultAirflowTag=${MODULE_DOCKER_TAG}" |
| 138 | elif [ "${module}" == "prometheus" ]; then |
| 139 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.server.sidecarContainers.prometheus-config-sidecar.image=${DOCKER_REGISTRY_URL}${DOCKER_USER}/prometheus:${OSM_DOCKER_TAG}" |
| 140 | else |
| 141 | # For the rest of cases, set the image tag normally |
| 142 | helm_entry=${module,,} |
| 143 | echo "Setting custom docker tag ${MODULE_DOCKER_TAG} for module ${module} in helm options" |
| 144 | OSM_HELM_OPTS="${OSM_HELM_OPTS} --set ${helm_entry}.image.tag=${MODULE_DOCKER_TAG}" |
| 145 | fi |
| 146 | fi |
| 147 | done |
| 148 | fi |
| 149 | |
| garciadeblas | 5d2eddf | 2025-11-25 16:59:01 +0100 | [diff] [blame] | 150 | [ ! -f "${OSM_HOME_DIR}/user-values.yaml" ] || OSM_HELM_OPTS="${OSM_HELM_OPTS} --values ${OSM_HOME_DIR}/user-values.yaml" |
| 151 | |
| 152 | echo "helm upgrade --install -n $OSM_NAMESPACE --create-namespace $OSM_HELM_RELEASE ${HERE}/helm/osm ${OSM_HELM_OPTS}" |
| 153 | helm upgrade --install -n $OSM_NAMESPACE --create-namespace $OSM_HELM_RELEASE ${HERE}/helm/osm ${OSM_HELM_OPTS} |
| 154 | # Export final values.yaml used to install OSM to a file for future reference |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 155 | helm -n $OSM_NAMESPACE get values $OSM_HELM_RELEASE | sudo tee -a ${OSM_HELM_WORK_DIR}/osm-values.yaml |
| 156 | |
| 157 | # Check OSM health state |
| 158 | echo -e "Checking OSM health state..." |
| 159 | set +e |
| 160 | ${HERE}/45-osm-health.sh || \ |
| 161 | (echo -e "OSM is not healthy, but will probably converge to a healthy state soon." && \ |
| 162 | echo -e "Check OSM status with: kubectl -n ${OSM_NAMESPACE} get all" && \ |
| 163 | track healthchecks osm_unhealthy didnotconverge) |
| 164 | track healthchecks after_healthcheck_ok |
| 165 | set -e |
| 166 | |
| 167 | echo -e "Saving OSM enviroment to credentials folder..." |
| 168 | OSM_HOSTNAME=$(kubectl get --namespace osm -o jsonpath="{.spec.rules[0].host}" ingress nbi-ingress) |
| garciadeblas | 8a28f6d | 2025-06-11 11:11:56 +0200 | [diff] [blame] | 169 | # OSM_HOSTNAME="nbi.${OSM_BASE_DOMAIN}:443" |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 170 | echo -e "OSM HOSTNAME: ${OSM_HOSTNAME}" |
| 171 | |
| 172 | cat << EOF > "${CREDENTIALS_DIR}/osm_environment.rc" |
| 173 | export OSM_HOSTNAME="${OSM_HOSTNAME}" |
| 174 | EOF |