blob: bf3f70920cc563497e9550be6b9df4c2236585f2 [file] [log] [blame]
garciadeblascf603f52025-06-04 11:57:28 +02001#!/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
16set -e -o pipefail
17
18HERE=$(dirname "$(readlink --canonicalize "$BASH_SOURCE")")
19source "${HERE}/../library/functions.sh"
20source "${HERE}/../library/trap.sh"
21source "${HERE}/../library/logging"
22source "${HERE}/../library/track"
23
24source "${HERE}/00-default-install-options.rc"
25[ ! -f "${OSM_HOME_DIR}/user-install-options.rc" ] || source "${OSM_HOME_DIR}/user-install-options.rc"
26source "${CREDENTIALS_DIR}/git_environment.rc"
27
28OSM_HELM_WORK_DIR="/etc/osm/helm"
garciadeblascf603f52025-06-04 11:57:28 +020029KUBECONFIG_AUX_CLUSTER_FILE="${OSM_HOME_DIR}/clusters/kubeconfig-aux-svc.yaml"
30KUBECONFIG_MGMT_CLUSTER_FILE="${OSM_HOME_DIR}/clusters/kubeconfig-mgmt.yaml"
31[ "${HERE}" == "/usr/share/osm-devops/installers" ] || OSM_HELM_UPDATE_DEPENDENCIES="y"
32OSM_GITOPS_ENABLED=${INSTALL_MGMT_CLUSTER:-"y"}
33
34# TODO: move this to a parent script that creates the VM
35mkdir -p "${OSM_HOME_DIR}/clusters"
36if [ -n "${KUBECONFIG_OSM_CLUSTER}" ]; then
37 cp "${KUBECONFIG_OSM_CLUSTER}" "${OSM_HOME_DIR}/clusters/kubeconfig-osm.yaml"
38else
39 cp "${HOME}/.kube/config" "${OSM_HOME_DIR}/clusters/kubeconfig-osm.yaml"
40fi
41
42export KUBECONFIG="${OSM_HOME_DIR}/clusters/kubeconfig-osm.yaml"
garciadeblas0df99ed2025-09-09 14:00:42 +020043if [ -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"
garciadeblas8a28f6d2025-06-11 11:11:56 +020045 OSM_K8S_NGINX_IPADDRESS=$(kubectl get svc ingress-nginx-controller -n ingress-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null)
garciadeblas0df99ed2025-09-09 14:00:42 +020046 OSM_BASE_DOMAIN="${OSM_BASE_DOMAIN:-"${OSM_K8S_NGINX_IPADDRESS}.nip.io"}"
garciadeblas8a28f6d2025-06-11 11:11:56 +020047fi
garciadeblas0df99ed2025-09-09 14:00:42 +020048echo "Using OSM_BASE_DOMAIN=${OSM_BASE_DOMAIN}"
garciadeblascf603f52025-06-04 11:57:28 +020049
50# Create folder to store helm values
51sudo mkdir -p ${OSM_HELM_WORK_DIR}
52
53# Saving secrets
54echo "Creating namespace ${OSM_NAMESPACE}"
garciadeblas8a28f6d2025-06-11 11:11:56 +020055kubectl get ns "${OSM_NAMESPACE}" >/dev/null 2>&1 || kubectl create ns "${OSM_NAMESPACE}"
garciadeblascf603f52025-06-04 11:57:28 +020056echo "Saving age keys in OSM cluster"
garciadeblas8a28f6d2025-06-11 11:11:56 +020057kubectl -n ${OSM_NAMESPACE} get secret mgmt-cluster-age-keys >/dev/null 2>&1 || \
garciadeblascf603f52025-06-04 11:57:28 +020058kubectl -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"
59echo "Creating secrets with kubeconfig files"
garciadeblas8a28f6d2025-06-11 11:11:56 +020060if [ -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}"
63fi
64if [ -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}"
67fi
garciadeblascf603f52025-06-04 11:57:28 +020068# 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
74OSM_HELM_OPTS=""
75# OSM_HELM_OPTS="${OSM_HELM_OPTS} --set nbi.useOsmSecret=false"
garciadeblas578ac922025-09-08 17:17:23 +020076[ -n "${OSM_HELM_TIMEOUT}" ] && OSM_HELM_OPTS="${OSM_HELM_OPTS} --timeout ${OSM_HELM_TIMEOUT}"
garciadeblascf603f52025-06-04 11:57:28 +020077
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}"
80OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.image.repositoryBase=${DOCKER_REGISTRY_URL}${DOCKER_USER}"
garciadeblas24a20d12025-09-10 17:09:06 +020081OSM_HELM_OPTS="${OSM_HELM_OPTS} --set airflow.defaultAirflowRepository=${DOCKER_REGISTRY_URL}${DOCKER_USER}/airflow"
garciadeblascf603f52025-06-04 11:57:28 +020082[ ! "$OSM_DOCKER_TAG" == "testing-daily" ] && OSM_HELM_OPTS="${OSM_HELM_OPTS} --set-string global.image.tag=${OSM_DOCKER_TAG}"
garciadeblas24a20d12025-09-10 17:09:06 +020083[ ! "$OSM_DOCKER_TAG" == "testing-daily" ] && OSM_HELM_OPTS="${OSM_HELM_OPTS} --set-string airflow.defaultAirflowTag=${OSM_DOCKER_TAG}"
garciadeblascf603f52025-06-04 11:57:28 +020084[ ! "$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
garciadeblas8a28f6d2025-06-11 11:11:56 +020086OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.hostname=${OSM_BASE_DOMAIN}"
garciadeblasb89a41f2025-09-09 13:07:50 +020087if [ -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}"
93fi
garciadeblas8a28f6d2025-06-11 11:11:56 +020094OSM_HELM_OPTS="${OSM_HELM_OPTS} --set grafana.ingress.hosts={grafana.${OSM_BASE_DOMAIN}}"
garciadeblasae4f2eb2026-01-15 11:31:20 +010095OSM_HELM_OPTS="${OSM_HELM_OPTS} --set grafana.ingress.tls[0].secretName=grafana-cert"
96OSM_HELM_OPTS="${OSM_HELM_OPTS} --set grafana.ingress.tls[0].hosts={grafana.${OSM_BASE_DOMAIN}}"
garciadeblas8a28f6d2025-06-11 11:11:56 +020097OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.server.ingress.hosts={prometheus.${OSM_BASE_DOMAIN}}"
garciadeblasae4f2eb2026-01-15 11:31:20 +010098OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.server.ingress.tls[0].secretName=prometheus-cert"
99OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.server.ingress.tls[0].hosts={prometheus.${OSM_BASE_DOMAIN}}"
100OSM_HELM_OPTS="${OSM_HELM_OPTS} --set airflow.ingress.web.hosts[0].name=airflow.${OSM_BASE_DOMAIN}"
101OSM_HELM_OPTS="${OSM_HELM_OPTS} --set airflow.ingress.web.hosts[0].tls.enabled=true"
102OSM_HELM_OPTS="${OSM_HELM_OPTS} --set airflow.ingress.web.hosts[0].tls.secretName=airflow-cert"
garciadeblas8a28f6d2025-06-11 11:11:56 +0200103# OSM_HELM_OPTS="${OSM_HELM_OPTS} --set prometheus.alertmanager.ingress.hosts={alertmanager.${OSM_BASE_DOMAIN}}"
garciadeblascf603f52025-06-04 11:57:28 +0200104if [ -z "${OSM_GITOPS_ENABLED}" ]; then
105 OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.gitops.enabled=false"
106else
garciadeblas823d8a32025-07-08 10:41:53 +0200107 OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.gitops.gitBaseUrl=${GIT_BASE_HTTP_URL}"
garciadeblascf603f52025-06-04 11:57:28 +0200108 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
garciadeblas823d8a32025-07-08 10:41:53 +0200111 OSM_HELM_OPTS="${OSM_HELM_OPTS} --set global.gitops.gitUser=${GIT_BASE_USERNAME}"
garciadeblascf603f52025-06-04 11:57:28 +0200112 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}"
114fi
115
116if [ -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
129fi
130
garciadeblas0b1c75c2025-11-11 23:04:39 +0100131# Only applicable to OSM CICD pipeline
132# Test specific modules specified in MODULES_FOR_TESTING, using docker tag MODULE_DOCKER_TAG
133if [ -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
148fi
149
garciadeblas5d2eddf2025-11-25 16:59:01 +0100150[ ! -f "${OSM_HOME_DIR}/user-values.yaml" ] || OSM_HELM_OPTS="${OSM_HELM_OPTS} --values ${OSM_HOME_DIR}/user-values.yaml"
151
152echo "helm upgrade --install -n $OSM_NAMESPACE --create-namespace $OSM_HELM_RELEASE ${HERE}/helm/osm ${OSM_HELM_OPTS}"
153helm 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
garciadeblascf603f52025-06-04 11:57:28 +0200155helm -n $OSM_NAMESPACE get values $OSM_HELM_RELEASE | sudo tee -a ${OSM_HELM_WORK_DIR}/osm-values.yaml
156
157# Check OSM health state
158echo -e "Checking OSM health state..."
159set +e
160${HERE}/45-osm-health.sh || \
161(echo -e "OSM is not healthy, but will probably converge to a healthy state soon." && \
162echo -e "Check OSM status with: kubectl -n ${OSM_NAMESPACE} get all" && \
163track healthchecks osm_unhealthy didnotconverge)
164track healthchecks after_healthcheck_ok
165set -e
166
167echo -e "Saving OSM enviroment to credentials folder..."
168OSM_HOSTNAME=$(kubectl get --namespace osm -o jsonpath="{.spec.rules[0].host}" ingress nbi-ingress)
garciadeblas8a28f6d2025-06-11 11:11:56 +0200169# OSM_HOSTNAME="nbi.${OSM_BASE_DOMAIN}:443"
garciadeblascf603f52025-06-04 11:57:28 +0200170echo -e "OSM HOSTNAME: ${OSM_HOSTNAME}"
171
172cat << EOF > "${CREDENTIALS_DIR}/osm_environment.rc"
173export OSM_HOSTNAME="${OSM_HOSTNAME}"
174EOF