| garciadeblas | 8d8cd99 | 2024-05-21 16:04:14 +0200 | [diff] [blame] | 1 | ####################################################################################### |
| 2 | # Copyright ETSI Contributors and Others. |
| 3 | # |
| 4 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | # you may not use this file except in compliance with the License. |
| 6 | # You may obtain a copy of the License at |
| 7 | # |
| 8 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | # |
| 10 | # Unless required by applicable law or agreed to in writing, software |
| 11 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| 13 | # implied. |
| 14 | # See the License for the specific language governing permissions and |
| 15 | # limitations under the License. |
| 16 | ####################################################################################### |
| 17 | |
| 18 | set -e -o pipefail |
| 19 | |
| 20 | export HERE=$(dirname "$(readlink --canonicalize "$BASH_SOURCE")") |
| 21 | source "${HERE}/library/functions.sh" |
| 22 | source "${HERE}/library/trap.sh" |
| 23 | |
| 24 | |
| 25 | |
| 26 | # Input values |
| 27 | export CLUSTER_DIR="$1" |
| 28 | export PROJECT_DIR="$2" |
| 29 | export PROFILE_NAME="$3" |
| 30 | export TEMPLATES_DIR="$4" |
| 31 | export PUBLIC_KEY="$5" |
| 32 | |
| 33 | |
| 34 | # Helper functions to create the profile ConfigMaps |
| 35 | function safe_name() { |
| 36 | echo "$1" | \ |
| 37 | sed '/\.\// s|./||' | \ |
| 38 | sed 's|\.|-|g' | \ |
| 39 | sed 's|/|-|g' | \ |
| 40 | sed 's|_|-|g' | \ |
| 41 | sed 's| |-|g' |
| 42 | } |
| 43 | |
| 44 | function create_profile_configmap() { |
| 45 | local CONFIGMAP_NAME=$(safe_name "$1") |
| 46 | local PROFILE_REPO_URL="$2" |
| 47 | local PROFILE_PATH="$3" |
| 48 | kubectl create configmap ${CONFIGMAP_NAME} \ |
| 49 | --namespace flux-system \ |
| 50 | --from-literal=repo="${PROFILE_REPO_URL}" \ |
| 51 | --from-literal=path="${PROFILE_PATH}" \ |
| 52 | -o yaml \ |
| 53 | --dry-run=client |
| 54 | } |
| 55 | |
| 56 | # Helper functions to clone secret from one namespace to other |
| 57 | function clone_secret_to_new_ns_stdout() { |
| 58 | local SECRET_NAME="$1" |
| 59 | local SOURCE_NS="$2" |
| 60 | local DESTINATION_NS="$3" |
| 61 | |
| 62 | kubectl get secret "${SECRET_NAME}" -n "${SOURCE_NS}" -o yaml | \ |
| 63 | yq 'del(.metadata.uid) | del(.metadata.resourceVersion) | del(.metadata.creationTimestamp)' | \ |
| 64 | yq ".metadata.namespace = \"${DESTINATION_NS}\"" |
| 65 | } |
| 66 | |
| 67 | # Helper function to encrypt secrets from stdin |
| 68 | function encrypt_secret_from_stdin() { |
| 69 | local PUBLIC_KEY="$1" |
| 70 | |
| 71 | # Save secret manifest to temporary file |
| 72 | local TMPFILE=$(mktemp /tmp/secret.XXXXXXXXXX.yaml) || exit 1 |
| 73 | cat > "${TMPFILE}" |
| 74 | |
| 75 | # Encrypt |
| 76 | sops \ |
| 77 | --age=${PUBLIC_KEY} \ |
| 78 | --encrypt \ |
| 79 | --encrypted-regex '^(data|stringData)$' \ |
| 80 | --in-place "${TMPFILE}" |
| 81 | |
| 82 | # Outputs the result and removes the temporary file |
| 83 | cat "${TMPFILE}" && rm -f "${TMPFILE}" |
| 84 | } |
| 85 | |
| 86 | # Creates all folders in the profile (as well as env var aliases) |
| 87 | export ADDON_CTRL_DIR="${PROJECT_DIR}/infra-controller-profiles/${PROFILE_NAME}" |
| 88 | export ADDON_CONFIG_DIR="${PROJECT_DIR}/infra-config-profiles/${PROFILE_NAME}" |
| 89 | export RESOURCES_DIR="${PROJECT_DIR}/managed-resources/${PROFILE_NAME}" |
| 90 | export APPS_DIR="${PROJECT_DIR}/app-profiles/${PROFILE_NAME}" |
| 91 | mkdir -p "${ADDON_CTRL_DIR}" |
| 92 | mkdir -p "${ADDON_CONFIG_DIR}" |
| 93 | mkdir -p "${RESOURCES_DIR}" |
| 94 | mkdir -p "${APPS_DIR}" |
| 95 | |
| 96 | # Copies the templates for cluster setup |
| 97 | cp "${TEMPLATES_DIR}"/* "${CLUSTER_DIR}/" |
| 98 | |
| 99 | # Repo URLs |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 100 | export FLEET_REPO_URL="${FLEET_REPO_HTTP_URL}" |
| 101 | export SW_CATALOGS_REPO_URL="${SW_CATALOGS_REPO_HTTP_URL}" |
| garciadeblas | 8d8cd99 | 2024-05-21 16:04:14 +0200 | [diff] [blame] | 102 | export INFRA_CONTROLLERS_PATH="./${MGMT_PROJECT_NAME}/infra-controller-profiles/_management" |
| 103 | export INFRA_CONFIGS_PATH="./${MGMT_PROJECT_NAME}/infra-config-profiles/_management" |
| 104 | export MANAGED_RESOURCES_PATH="./${MGMT_PROJECT_NAME}/managed-resources/_management" |
| 105 | export APPS_PATH="./${MGMT_PROJECT_NAME}/app-profiles/_management" |
| 106 | |
| 107 | # Render Flux `GitRepository` objects with proper Git URL and relative repo paths |
| 108 | envsubst < "${TEMPLATES_DIR}/fleet-repo.yaml" > "${CLUSTER_DIR}/fleet-repo.yaml" |
| 109 | envsubst < "${TEMPLATES_DIR}/sw-catalogs-repo.yaml" > "${CLUSTER_DIR}/sw-catalogs-repo.yaml" |
| 110 | |
| 111 | # Secrets to access both Git repos |
| 112 | # (NOTE: these are the last secrets to be added imperatively) |
| 113 | kubectl delete secret fleet-repo --namespace flux-system 2> /dev/null || true |
| 114 | kubectl create secret generic fleet-repo \ |
| 115 | --namespace flux-system \ |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 116 | --from-literal=username="${FLEET_REPO_GIT_USERNAME}" \ |
| 117 | --from-literal=password="${FLEET_REPO_GIT_USER_PASS}" |
| garciadeblas | 8d8cd99 | 2024-05-21 16:04:14 +0200 | [diff] [blame] | 118 | |
| 119 | kubectl delete secret sw-catalogs --namespace flux-system 2> /dev/null || true |
| 120 | kubectl create secret generic sw-catalogs \ |
| 121 | --namespace flux-system \ |
| garciadeblas | cf603f5 | 2025-06-04 11:57:28 +0200 | [diff] [blame] | 122 | --from-literal=username="${SW_CATALOGS_REPO_GIT_USERNAME}" \ |
| 123 | --from-literal=password="${SW_CATALOGS_REPO_GIT_USER_PASS}" |
| garciadeblas | 8d8cd99 | 2024-05-21 16:04:14 +0200 | [diff] [blame] | 124 | |
| 125 | # Render Flux `Kustomizations` to sync with default profiles |
| 126 | envsubst < "${TEMPLATES_DIR}/infra-controllers.yaml" > "${CLUSTER_DIR}/infra-controllers.yaml" |
| 127 | envsubst < "${TEMPLATES_DIR}/infra-configs.yaml" > "${CLUSTER_DIR}/infra-configs.yaml" |
| 128 | envsubst < "${TEMPLATES_DIR}/managed-resources.yaml" > "${CLUSTER_DIR}/managed-resources.yaml" |
| 129 | envsubst < "${TEMPLATES_DIR}/apps.yaml" > "${CLUSTER_DIR}/apps.yaml" |
| 130 | |
| 131 | # Create `ConfigMaps` into profiles (and `Namespace` specs when needed) to avoid sync errors |
| 132 | ## Infra controllers ConfigMap |
| 133 | CONFIGMAP_NAME="infra-controllers" |
| 134 | PROFILE_REPO_URL="${FLEET_REPO_URL}" |
| 135 | PROFILE_PATH="${INFRA_CONTROLLERS_PATH}" |
| 136 | create_profile_configmap \ |
| 137 | "${CONFIGMAP_NAME}" \ |
| 138 | "${PROFILE_REPO_URL}" \ |
| 139 | "${PROFILE_PATH}" \ |
| 140 | > "${ADDON_CTRL_DIR}/profile-configmap.yaml" |
| 141 | |
| 142 | ## Infra configurations ConfigMap |
| 143 | CONFIGMAP_NAME="infra-configs" |
| 144 | PROFILE_REPO_URL="${FLEET_REPO_URL}" |
| 145 | PROFILE_PATH="${INFRA_CONFIGS_PATH}" |
| 146 | create_profile_configmap \ |
| 147 | "${CONFIGMAP_NAME}" \ |
| 148 | "${PROFILE_REPO_URL}" \ |
| 149 | "${PROFILE_PATH}" \ |
| 150 | > "${ADDON_CONFIG_DIR}/profile-configmap.yaml" |
| 151 | |
| 152 | ## Managed resources ConfigMap |
| 153 | CONFIGMAP_NAME="managed-resources" |
| 154 | PROFILE_REPO_URL="${FLEET_REPO_URL}" |
| 155 | PROFILE_PATH="${MANAGED_RESOURCES_PATH}" |
| 156 | create_profile_configmap \ |
| 157 | "${CONFIGMAP_NAME}" \ |
| 158 | "${PROFILE_REPO_URL}" \ |
| 159 | "${PROFILE_PATH}" \ |
| 160 | > "${RESOURCES_DIR}/profile-configmap.yaml" |
| 161 | |
| 162 | ## Managed resources namespace |
| 163 | kubectl create ns ${CONFIGMAP_NAME} \ |
| 164 | -o yaml \ |
| 165 | --dry-run=client \ |
| 166 | > "${RESOURCES_DIR}/namespace.yaml" |
| 167 | |
| 168 | ### Copy secrets for Git repos from `flux-system` to `managed-resources` namespace |
| 169 | clone_secret_to_new_ns_stdout \ |
| 170 | flux-system \ |
| 171 | flux-system \ |
| 172 | "${CONFIGMAP_NAME}" | \ |
| 173 | encrypt_secret_from_stdin \ |
| 174 | "${PUBLIC_KEY}" \ |
| 175 | > "${RESOURCES_DIR}/secret-flux-system.yaml" |
| 176 | |
| 177 | clone_secret_to_new_ns_stdout \ |
| 178 | fleet-repo \ |
| 179 | flux-system \ |
| 180 | "${CONFIGMAP_NAME}" | \ |
| 181 | encrypt_secret_from_stdin \ |
| 182 | "${PUBLIC_KEY}" \ |
| 183 | > "${RESOURCES_DIR}/secret-fleet-repo.yaml" |
| 184 | |
| 185 | clone_secret_to_new_ns_stdout \ |
| 186 | sw-catalogs \ |
| 187 | flux-system \ |
| 188 | "${CONFIGMAP_NAME}" | \ |
| 189 | encrypt_secret_from_stdin \ |
| 190 | "${PUBLIC_KEY}" \ |
| 191 | > "${RESOURCES_DIR}/secret-sw-catalogs.yaml" |
| 192 | |
| 193 | ## Apps ConfigMap |
| 194 | CONFIGMAP_NAME="apps" |
| 195 | PROFILE_REPO_URL="${FLEET_REPO_URL}" |
| 196 | PROFILE_PATH="${APPS_PATH}" |
| 197 | create_profile_configmap \ |
| 198 | "${CONFIGMAP_NAME}" \ |
| 199 | "${PROFILE_REPO_URL}" \ |
| 200 | "${PROFILE_PATH}" \ |
| 201 | > "${APPS_DIR}/profile-configmap.yaml" |