#!/usr/bin/env bash
# prometheus-community/kube-prometheus-stack 84.4.0 - base variant: default
# Path: fetch this entry's retained objects, check their SHA-256, then apply
# them with kubectl. It uses curl, shasum, awk and kubectl. It needs no cub
# CLI and no ConfigHub account.
# Generated by scripts/generate-public-site.mjs from this entry's listing:
# https://confighub.github.io/helm-expt/site/listings/prometheus-community-kube-prometheus-stack-84-4-0-default.json
# Entry page: https://confighub.github.io/helm-expt/site/charts/prometheus-community-kube-prometheus-stack-84-4-0.html
set -euo pipefail

say() { printf '\n>> %s\n' "$*"; }

for tool in curl awk kubectl; do
  if ! command -v "$tool" >/dev/null 2>&1; then
    printf '%s is required and was not found.\n' "$tool" >&2
    exit 1
  fi
done
if command -v shasum >/dev/null 2>&1; then
  sha256_of() { shasum -a 256 "$1" | awk '{print $1}'; }
elif command -v sha256sum >/dev/null 2>&1; then
  sha256_of() { sha256sum "$1" | awk '{print $1}'; }
else
  printf 'shasum is required and was not found.\n' >&2
  exit 1
fi

work=./prometheus-community-kube-prometheus-stack-84-4-0-default-objects
objects_url=https://raw.githubusercontent.com/confighub/helm-expt/main/recipes/prometheus-community/kube-prometheus-stack/84.4.0/revisions/default/r001/rendered/release-objects.yaml
objects_sha256=c5dc2d69b5f9d0163166cd07485ee067e96702856fbdb5e0af3de88df0a348db

say "Fetch the retained objects into $work/objects.yaml"
mkdir -p "$work"
curl -fsSL -o "$work/objects.yaml" "$objects_url"

say "Check the file against the SHA-256 in the listing"
fetched_sha256="$(sha256_of "$work/objects.yaml")"
if [ "$fetched_sha256" != "$objects_sha256" ]; then
  printf 'The file differs from the listing, so the script stops. Nothing was applied.\n  listing: %s\n  fetched: %s\n' "$objects_sha256" "$fetched_sha256" >&2
  exit 1
fi
printf 'The file matches: sha256 %s\n' "$fetched_sha256"

say "Split the file into its 126 objects. The cluster is untouched so far"
rm -rf "$work/docs" "$work/crds" "$work/rest"
mkdir -p "$work/docs" "$work/crds" "$work/rest"
awk -v dir="$work/docs" 'BEGIN { n = 0; f = sprintf("%s/doc-%04d.yaml", dir, n) } /^---[ \t]*$/ { close(f); n++; f = sprintf("%s/doc-%04d.yaml", dir, n); next } { print > f }' "$work/objects.yaml"
for n in 0002 0004 0006 0008 0010 0012 0014 0016 0018 0020; do mv "$work/docs/doc-$n.yaml" "$work/crds/"; done
for n in 0021 0022 0023 0024 0025 0026 0027 0028 0029 0030 0031 0032; do mv "$work/docs/doc-$n.yaml" "$work/rest/"; done
for n in 0033 0034 0035 0036 0037 0038 0039 0040 0041 0042 0043 0044; do mv "$work/docs/doc-$n.yaml" "$work/rest/"; done
for n in 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 0056; do mv "$work/docs/doc-$n.yaml" "$work/rest/"; done
for n in 0057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068; do mv "$work/docs/doc-$n.yaml" "$work/rest/"; done
for n in 0069 0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 0080; do mv "$work/docs/doc-$n.yaml" "$work/rest/"; done
for n in 0081 0082 0083 0084 0085 0086 0087 0088 0089 0090 0091 0092; do mv "$work/docs/doc-$n.yaml" "$work/rest/"; done
for n in 0093 0094 0095 0096 0097 0098 0099 0100 0101 0102 0103 0104; do mv "$work/docs/doc-$n.yaml" "$work/rest/"; done
for n in 0105 0106 0107 0108 0109 0110 0111 0112 0113 0114 0115 0116; do mv "$work/docs/doc-$n.yaml" "$work/rest/"; done
for n in 0117 0118 0119 0120 0121 0122 0123 0124 0125 0126 0127 0128; do mv "$work/docs/doc-$n.yaml" "$work/rest/"; done
for n in 0129 0130 0131 0132 0133 0134 0135 0136; do mv "$work/docs/doc-$n.yaml" "$work/rest/"; done
ls "$work/crds" "$work/rest"

if [ "${REQUIREMENTS_READY:-0}" != "1" ]; then
  say "Stop before applying anything. This entry's plan has 3 steps that an install needs first"
  cat >&2 <<'EOF_REQUIREMENTS'
This script cannot carry out these steps of the plan. They are yours to do, with your own values:
  - The package runs the chart's certificate creation Job before applying the admission webhooks.
  - The direct runner applies CRDs, creates the certificate, applies the workload, and patches the webhooks in that order.
  - The certificate Job creates the required admission Secret with ca, cert, and key.
Nothing was applied. Complete them before you apply the objects.
When they are done, re-run with:
  REQUIREMENTS_READY=1 bash try-objects.sh
EOF_REQUIREMENTS
  exit 1
fi
say "REQUIREMENTS_READY=1 is set. The script takes your word for 3 steps and does not check them"

say "Check that kubectl reaches a cluster"
if ! kubectl get --raw /version >/dev/null 2>&1; then
  printf 'kubectl cannot reach a cluster. Point it at a throwaway cluster and re-run this script.\n' >&2
  exit 1
fi
kubectl config current-context 2>/dev/null || true

say "Create the kube-system namespace if it does not exist"
if ! kubectl get namespace kube-system >/dev/null 2>&1; then
  kubectl create namespace kube-system
fi

say "Create the monitoring namespace if it does not exist"
if ! kubectl get namespace monitoring >/dev/null 2>&1; then
  kubectl create namespace monitoring
fi

wait_for_crd() {
  crd_name="$1"
  deadline=$(( $(date +%s) + 180 ))
  until kubectl get "crd/${crd_name}" >/dev/null 2>&1; do
    if [ "$(date +%s)" -ge "$deadline" ]; then
      printf "CRD %s did not appear within 180 seconds.\n" "$crd_name" >&2
      return 1
    fi
    sleep 2
  done
  kubectl wait --for=condition=Established --timeout=120s "crd/${crd_name}"
}

say "Check the 10 CRDs this file holds"
missing_crds=0
if ! kubectl get crd/alertmanagerconfigs.monitoring.coreos.com >/dev/null 2>&1; then
  missing_crds=1
fi
if ! kubectl get crd/alertmanagers.monitoring.coreos.com >/dev/null 2>&1; then
  missing_crds=1
fi
if ! kubectl get crd/podmonitors.monitoring.coreos.com >/dev/null 2>&1; then
  missing_crds=1
fi
if ! kubectl get crd/probes.monitoring.coreos.com >/dev/null 2>&1; then
  missing_crds=1
fi
if ! kubectl get crd/prometheusagents.monitoring.coreos.com >/dev/null 2>&1; then
  missing_crds=1
fi
if ! kubectl get crd/prometheuses.monitoring.coreos.com >/dev/null 2>&1; then
  missing_crds=1
fi
if ! kubectl get crd/prometheusrules.monitoring.coreos.com >/dev/null 2>&1; then
  missing_crds=1
fi
if ! kubectl get crd/scrapeconfigs.monitoring.coreos.com >/dev/null 2>&1; then
  missing_crds=1
fi
if ! kubectl get crd/servicemonitors.monitoring.coreos.com >/dev/null 2>&1; then
  missing_crds=1
fi
if ! kubectl get crd/thanosrulers.monitoring.coreos.com >/dev/null 2>&1; then
  missing_crds=1
fi
if [ "$missing_crds" -eq 1 ]; then
  say "A CRD is missing, so apply the file's CRDs first"
  kubectl apply --server-side -f "$work/crds"
  crd_outcome="were applied first"
elif kubectl diff --server-side -f "$work/crds" >/dev/null 2>&1; then
  say "The CRDs already exist and match this file. The script leaves them under their current owner"
  crd_outcome="already existed and matched, so the script left them alone"
elif [ "${APPLY_CRDS:-0}" = "1" ]; then
  say "The existing CRDs differ from this file. APPLY_CRDS=1 is set, so the script applies the file's CRDs"
  kubectl apply --server-side -f "$work/crds"
  crd_outcome="differed and were applied, because APPLY_CRDS=1 was set"
else
  say "The CRDs already exist and differ from this file, or another tool owns them"
  cat <<'EOF_CRDS'
This script does not change CRDs it did not just create.
If this is an upgrade, the objects that follow may need the newer CRDs.
To let this script apply the file's CRDs, re-run with:
  APPLY_CRDS=1 bash try-objects.sh
EOF_CRDS
  exit 1
fi
wait_for_crd alertmanagerconfigs.monitoring.coreos.com
wait_for_crd alertmanagers.monitoring.coreos.com
wait_for_crd podmonitors.monitoring.coreos.com
wait_for_crd probes.monitoring.coreos.com
wait_for_crd prometheusagents.monitoring.coreos.com
wait_for_crd prometheuses.monitoring.coreos.com
wait_for_crd prometheusrules.monitoring.coreos.com
wait_for_crd scrapeconfigs.monitoring.coreos.com
wait_for_crd servicemonitors.monitoring.coreos.com
wait_for_crd thanosrulers.monitoring.coreos.com

say "Apply the other 116 objects"
kubectl apply -f "$work/rest"

say "Done. The 10 CRDs $crd_outcome. kubectl applied the other 116 objects of this entry's retained file."
say "The script stops here. It did not wait for any workload to start"
say "Not run by this script: 7 steps of this entry's plan. The entry page says who runs each one."
cat <<'EOF_NOT_RUN'
   - The package runs the chart's certificate creation Job before applying the admission webhooks.
   - The direct runner applies CRDs, creates the certificate, applies the workload, and patches the webhooks in that order.
   - The certificate Job creates the required admission Secret with ca, cert, and key.
   - The run removes both completed Jobs and their temporary RBAC objects.
   - The package runs the chart's webhook patch Job after the webhook objects exist.
   - The direct package route upgraded the default preset from 85.3.3 to 86.1.0, established the updated CRDs, retained the admission Secret, reran the webhook step, checked six workloads, and and more. The listing gives the rest.
   - The run checks three CA bundles, the operator endpoint, a server dry-run, and six workloads.
EOF_NOT_RUN
