my-homelab-configs/lib/jeannie/toolchain.sh

144 lines
4.9 KiB
Bash

#!/usr/bin/env bash
require_debian_server() {
local command_name="$1"
local os_id=""
if [[ "$(uname -s)" != "Linux" ]]; then
echo "Refusing to run '${command_name}' from this machine. Run it on the Debian homelab server." >&2
exit 1
fi
if [[ -r /etc/os-release ]]; then
os_id="$(awk -F= '$1 == "ID" {gsub(/"/, "", $2); print $2; exit}' /etc/os-release)"
fi
if [[ "${os_id}" != "debian" ]]; then
echo "Refusing to run '${command_name}' on ${os_id:-unknown OS}. Run it on the Debian homelab server." >&2
exit 1
fi
}
tofu_state_has_resource() {
local stack="$1"
local resource_address="$2"
tofu -chdir="${REPO_ROOT}/${stack}" state show "${resource_address}" >/dev/null 2>&1
}
cleanup_stale_helm_release_secrets() {
local namespace="$1"
local release_name="$2"
kubectl --kubeconfig "${KUBECONFIG_PATH}" -n "${namespace}" get secrets \
-l "owner=helm,name=${release_name}" \
-o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.status}{"\n"}{end}' 2>/dev/null |
while IFS=$'\t' read -r secret status; do
case "${status}" in
pending-install|pending-upgrade|pending-rollback|failed|uninstalling)
echo "Deleting stale Helm release secret ${namespace}/${secret} with status=${status}..."
kubectl --kubeconfig "${KUBECONFIG_PATH}" -n "${namespace}" delete secret "${secret}"
;;
esac
done
}
helm_release_deployed_secret_exists() {
local namespace="$1"
local release_name="$2"
local secret_name
secret_name="$(kubectl --kubeconfig "${KUBECONFIG_PATH}" -n "${namespace}" get secrets \
-l "owner=helm,name=${release_name},status=deployed" \
-o jsonpath='{.items[0].metadata.name}' 2>/dev/null || true)"
[[ -n "${secret_name}" ]]
}
kubernetes_resource_exists() {
local namespace="$1"
local resource_kind="$2"
local resource_name="$3"
if [[ -n "${namespace}" ]]; then
kubectl --kubeconfig "${KUBECONFIG_PATH}" -n "${namespace}" get "${resource_kind}" "${resource_name}" >/dev/null 2>&1
return $?
fi
kubectl --kubeconfig "${KUBECONFIG_PATH}" get "${resource_kind}" "${resource_name}" >/dev/null 2>&1
}
adopt_tofu_helm_release() {
local stack="$1"
local resource_address="$2"
local namespace="$3"
local release_name="$4"
local has_state=false
local has_deployed_release=false
if tofu_state_has_resource "${stack}" "${resource_address}"; then
has_state=true
fi
cleanup_stale_helm_release_secrets "${namespace}" "${release_name}"
if helm_release_deployed_secret_exists "${namespace}" "${release_name}"; then
has_deployed_release=true
fi
if [[ "${has_state}" == "true" && "${has_deployed_release}" == "false" ]]; then
echo "Removing stale Helm release state for ${namespace}/${release_name} from ${stack} (${resource_address}) because no deployed Helm release exists..."
tofu -chdir="${REPO_ROOT}/${stack}" state rm "${resource_address}"
return 0
fi
if [[ "${has_state}" == "true" ]]; then
return 0
fi
if [[ "${has_deployed_release}" == "false" ]]; then
return 0
fi
echo "Importing existing Helm release ${namespace}/${release_name} into ${stack} state (${resource_address})..."
tofu -chdir="${REPO_ROOT}/${stack}" import -input=false "${resource_address}" "${namespace}/${release_name}"
}
adopt_tofu_kubernetes_resource() {
local stack="$1"
local resource_address="$2"
local namespace="$3"
local resource_kind="$4"
local resource_name="$5"
local import_id="$6"
if tofu_state_has_resource "${stack}" "${resource_address}"; then
return 0
fi
if ! kubernetes_resource_exists "${namespace}" "${resource_kind}" "${resource_name}"; then
return 0
fi
echo "Importing existing Kubernetes ${resource_kind} ${resource_name} into ${stack} state (${resource_address})..."
tofu -chdir="${REPO_ROOT}/${stack}" import -input=false "${resource_address}" "${import_id}"
}
adopt_tofu_kubernetes_manifest() {
local stack="$1"
local resource_address="$2"
local namespace="$3"
local kubectl_kind="$4"
local api_version="$5"
local manifest_kind="$6"
local resource_name="$7"
local import_id
if tofu_state_has_resource "${stack}" "${resource_address}"; then
return 0
fi
if ! kubernetes_resource_exists "${namespace}" "${kubectl_kind}" "${resource_name}"; then
return 0
fi
import_id="apiVersion=${api_version},kind=${manifest_kind},namespace=${namespace},name=${resource_name}"
echo "Importing existing Kubernetes ${manifest_kind} ${namespace}/${resource_name} into ${stack} state (${resource_address})..."
tofu -chdir="${REPO_ROOT}/${stack}" import -input=false "${resource_address}" "${import_id}"
}