#!/bin/bash # Первый шаг переноса инстанса на другой куб (DST, по умолчанию loop-3): секреты + перепривязка в визоре. # loopctl k8s rebind loop12a40f770b5a # Источник = куб из SOURCES, где есть CR; провайдер БД в визоре ищется по host:port из секрета. # Не делает: sync, гашение на исходном кубе, DNS (это loopctl k8s move). set -euo pipefail ID=${1:?loop id, например loop12a40f770b5a} . "$(dirname "$0")/../lib/common.sh" copy_secret() { # $1 имя; копирует с $SRC на $DST без вывода данных kubectl --context "$SRC" -n loop get secret "$1" -o json \ | jq '{apiVersion,kind,type,data,metadata:{name:.metadata.name,namespace:"loop"}}' \ | kubectl --context "$DST" apply -f - >/dev/null echo " $1 скопирован" } hash_secrets() { # $1 context kubectl --context "$1" -n loop get secret "$ID-db-credentials" "$ID-s3-credentials" "$ID-license" -o json \ | jq -S '[.items[]|{n:.metadata.name,t:.type,d:.data}]' | shasum | cut -c1-12 } echo "== $ID" # источник = куб, где есть CR (registry неактуален); домен из ingress CR for SRC in $SOURCES ""; do [ -n "$SRC" ] || { echo "CR $ID не найден ни на одном исходном кубе"; exit 1; } DOMAIN=$(kubectl --context "$SRC" -n loop get mattermost "$ID" -o jsonpath='{.spec.ingress.host}' 2>/dev/null) && [ -n "$DOMAIN" ] && break done SRC_CLUSTER=$(echo "select id from cluster_instance where name='$SRC';" | vsql) DST_CLUSTER=$(echo "select id from cluster_instance where name='$DST';" | vsql) [ -n "$DST_CLUSTER" ] || { echo "в визоре нет кластера $DST"; exit 1; } echo " $DOMAIN $SRC" # база в секрете на исходном кубе уже должна смотреть в Selectel DBHOST=$(kubectl --context "$SRC" -n loop get secret "$ID-db-credentials" -o json | jq -r '.data.DB_CONNECTION_STRING|@base64d' | sed -E 's#.*@([^/]+)/.*#\1#') echo " БД в секрете: $DBHOST" case $DBHOST in *.mdb.yandexcloud.net*) echo "секрет ещё смотрит в Yandex, стоп"; exit 1;; esac # CR с таким именем на $DST быть не должно if kubectl --context "$DST" -n loop get mattermost "$ID" >/dev/null 2>&1; then echo "CR уже есть на $DST, стоп"; exit 1; fi # провайдер БД = ON_PREM-провайдер визора с тем же host:port, что в секрете PROVIDER=$(echo "select id||'|'||name from database_provider where vendor='ON_PREM' and host_name='${DBHOST%:*}' and host_port::text='${DBHOST##*:}';" | vsql) [ "$(grep -c . <<<"$PROVIDER")" = 1 ] || { echo "в визоре не один ON_PREM-провайдер для $DBHOST: '$PROVIDER'"; exit 1; } TARGET=${PROVIDER#*|}; PROVIDER=${PROVIDER%%|*}; echo " провайдер: $TARGET" confirm "Скопирую секреты $ID на $DST и перепривяжу инстанс в визоре на $DST." || exit 1 echo "-- секреты на $DST" for s in wildcard-loop.ru-tls private.docker.wilix.dev; do # общие, копируем один раз kubectl --context "$DST" -n loop get secret "$s" >/dev/null 2>&1 || copy_secret "$s" done for s in db-credentials s3-credentials license; do copy_secret "$ID-$s"; done H1=$(hash_secrets "$SRC"); H3=$(hash_secrets "$DST") [ "$H1" = "$H3" ] || { echo "секреты не совпали: $H1 / $H3"; exit 1; } echo " совпадают ($H1)" # свой сертификат (не wildcard): cluster-issuer оставляем, иначе на новом кубе он перестанет продлеваться OWN_TLS=$(kubectl --context "$SRC" -n loop get mattermost "$ID" -o jsonpath='{.spec.ingress.tlsSecret}') [ "$OWN_TLS" = wildcard-loop.ru-tls ] && OWN_TLS="" echo "-- визор" TAIL=${ID#loop} FOUND=$(printf "select i.id, i.domain, c.name, d.id from loop_instance i join cluster_instance c on c.id=i.cluster_instance_id join database_instance d on d.id=i.database_instance_id where i.id like '%%%s' and i.deleted_at is null;\n" "$TAIL" | vsql) [ "$(printf '%s\n' "$FOUND" | grep -c .)" = 1 ] || { echo "в визоре не один инстанс: $FOUND"; exit 1; } IFS='|' read -r VID VDOMAIN VCLUSTER DBID <<<"$FOUND" echo " $VID $VDOMAIN куб=$VCLUSTER" [ "$VDOMAIN" = "$DOMAIN" ] || { echo "домен в визоре другой: $VDOMAIN"; exit 1; } vsql <