ce7cb702218693d08ea6d83464d2457c9250027c

This commit is contained in:
ms2k 2026-11-12 20:46:28 +09:00
commit 34c5f8963c
13 changed files with 145336 additions and 0 deletions

View file

@ -0,0 +1,165 @@
open System
open System.Diagnostics
open System.IO
type Result = { Code: int; Output: string; Error: string }
type Fixture = { Root: string; Source: string; Mask: string }
let require condition message =
if not condition then invalidOp message
let run root environment executable arguments =
let start = ProcessStartInfo executable
start.WorkingDirectory <- root
start.UseShellExecute <- false
start.RedirectStandardOutput <- true
start.RedirectStandardError <- true
for argument in arguments do start.ArgumentList.Add argument
for name, value in environment do start.Environment[name] <- value
use child = Process.Start start
let output = child.StandardOutput.ReadToEndAsync()
let error = child.StandardError.ReadToEndAsync()
child.WaitForExit()
{ Code = child.ExitCode; Output = output.Result; Error = error.Result }
let git fixture arguments =
let result = run fixture.Root [] "git" arguments
require (result.Code = 0) result.Error
result.Output
let write path (text: string) = File.WriteAllText(path, text)
let stage fixture = git fixture [ "add"; "." ] |> ignore
let hook = Path.Combine(__SOURCE_DIRECTORY__, "pre-commit")
let runHook fixture environment =
let before = git fixture [ "ls-files"; "--stage"; "-z" ]
let result = run fixture.Root environment hook []
require (before = git fixture [ "ls-files"; "--stage"; "-z" ]) "hook changed the index"
result
let passes fixture =
let result = runHook fixture []
require (result.Code = 0) result.Error
let fails expected fixture =
let result = runHook fixture []
require (result.Code <> 0) "hook unexpectedly succeeded"
require (result.Error.Contains(expected: string)) result.Error
let directory fixture path = Directory.CreateDirectory(Path.Combine(fixture.Root, path)).FullName
let tests: (string * (Fixture -> unit)) list =
[ "staged tree", fun fixture ->
write fixture.Source "unstaged source edit\n"
write fixture.Mask "unstaged invalid mask\n"
passes fixture
"unrelated change", fun fixture ->
write fixture.Source "other=changed\nvalue=synthetic\n"
stage fixture
passes fixture
"missing match", fun fixture ->
write fixture.Source "value=changed\n"
stage fixture
fails "no match" fixture
"multiple matches", fun fixture ->
write fixture.Source "synthetic synthetic\n"
stage fixture
fails "multiple matches" fixture
"overlapping matches", fun fixture ->
write fixture.Source "aaa"
write fixture.Mask "[[replace]]\nbefore = 'aa'\nafter = 'b'\n"
stage fixture
fails "multiple matches" fixture
"empty before", fun fixture ->
write fixture.Mask "[[replace]]\nbefore = ''\nafter = 'x'\n"
stage fixture
fails "before is empty" fixture
"ordered rules", fun fixture ->
write fixture.Mask
("[[replace]]\nbefore = 'synthetic'\nafter = 'intermediate'\n"
+ "[[replace]]\nbefore = 'intermediate'\nafter = '********'\n")
stage fixture
passes fixture
"invalid TOML", fun fixture ->
write fixture.Mask "invalid = ["
stage fixture
let result = runHook fixture []
require (result.Code <> 0) "invalid TOML was accepted"
"invalid schema", fun fixture ->
write fixture.Mask "[[replace]]\nbefore = 'synthetic'\nafter = 1\n"
stage fixture
fails "expected text" fixture
"missing target", fun fixture ->
git fixture [ "rm"; "--cached"; "config.txt" ] |> ignore
fails "target is not a regular file" fixture
"symlink target", fun fixture ->
File.Delete fixture.Source
File.CreateSymbolicLink(fixture.Source, "elsewhere") |> ignore
stage fixture
fails "target is not a regular file" fixture
"omitted subtree", fun fixture ->
let hidden = directory fixture "hidden"
write (Path.Combine(hidden, ".omit")) ""
write (Path.Combine(hidden, "invalid.mask.toml")) "invalid"
let nested = directory fixture "hidden/nested"
write (Path.Combine(nested, ".omit")) ""
write (Path.Combine(nested, "legacy.mask.diff")) "invalid"
stage fixture
let result = runHook fixture []
require (result.Code = 0) result.Error
require (result.Output.Contains "1 directories omitted") result.Output
"omit prefix boundary", fun fixture ->
let hidden = directory fixture "hidden"
write (Path.Combine(hidden, ".omit")) ""
let peer = directory fixture "hidden-peer"
write (Path.Combine(peer, "invalid.mask.toml")) "invalid"
stage fixture
fails "target is not a regular file" fixture
"unstaged omit", fun fixture ->
write fixture.Source "synthetic synthetic"
stage fixture
write (Path.Combine(fixture.Root, ".omit")) ""
fails "multiple matches" fixture
"legacy format", fun fixture ->
write (Path.Combine(fixture.Root, "old.mask.diff")) "invalid"
stage fixture
fails "legacy mask format" fixture
"alternate index", fun fixture ->
let index = Path.Combine(fixture.Root, "alternate")
File.Copy(Path.Combine(fixture.Root, ".git/index"), index)
write fixture.Source "staged drift\n"
git fixture [ "add"; "config.txt" ] |> ignore
let before = File.ReadAllBytes index
let result = runHook fixture [ "GIT_INDEX_FILE", index ]
require (result.Code = 0) result.Error
require (before = File.ReadAllBytes index) "hook changed the alternate index" ]
for name, test in tests do
let root = Directory.CreateDirectory(Path.Combine(fsi.CommandLineArgs[1], $"hook-tests-{Guid.NewGuid():N}")).FullName
let fixture = { Root = root; Source = Path.Combine(root, "config.txt"); Mask = Path.Combine(root, "config.txt.mask.toml") }
try
git fixture [ "init"; "-q" ] |> ignore
write fixture.Source "value=synthetic\n"
write fixture.Mask "[[replace]]\nbefore = 'synthetic'\nafter = '********'\n"
stage fixture
test fixture
printfn "passed: %s" name
finally
Directory.Delete(root, true)
printfn "%d hook tests passed" tests.Length

2
scripts/hooks/pre-commit Executable file
View file

@ -0,0 +1,2 @@
#!/bin/sh
exec dotnet fsi --quiet --exec "$(dirname "$0")/pre-commit.fsx" "$@"

View file

@ -0,0 +1,30 @@
#r "nuget: Tomlyn, 2.10.1"
#load "../../services/project-delivery/actions/masking.fsx"
open System
let checkIndex () =
let git arguments = Masking.run "git" arguments None
let entries =
git [ "ls-files"; "--stage"; "-z" ]
|> _.Split('\u0000', StringSplitOptions.RemoveEmptyEntries)
|> Array.map (fun entry ->
let fields = entry.Split('\t', 2)
let metadata = fields[0].Split(' ')
if metadata[2] <> "0" then
invalidOp "unmerged index"
fields[1], (metadata[0] = "100644" || metadata[0] = "100755", metadata[1]))
|> Map.ofArray
Masking.makePlan Masking.parseRules (entries |> Map.map (fun _ (regular, _) -> regular)) (fun path ->
git [ "cat-file"; "blob"; snd entries[path] ])
try
let plan = checkIndex ()
printfn "masks: %d staged masks verified; %d directories omitted" plan.Masks.Length plan.Omitted.Length
with :? InvalidOperationException as error ->
eprintfn "masks: %s" error.Message
exit 1

View file

@ -0,0 +1,7 @@
server: https://k3s.ms2k.internal:6443
kubelet-arg:
- max-pods=250
node-taint:
- workload=nas:PreferNoSchedule

View file

@ -0,0 +1,23 @@
server: https://********
flannel-backend: none
disable-network-policy: true
disable-kube-proxy: true
tls-san:
- "********"
- 10.72.123.235
cluster-cidr: 172.19.28.14/12
service-cidr: 10.74.150.93/12
cluster-dns: 10.97.104.110
secrets-encryption: true
kubelet-arg:
- max-pods=250
disable:
- coredns
- traefik
- servicelb

74
scripts/k3s/install.sh Executable file
View file

@ -0,0 +1,74 @@
#!/usr/bin/env bash
# Usage: install.sh server|agent <ssh-target>
set -euo pipefail
set +o xtrace 2>/dev/null || true
VAULT_PATH="${K3S_VAULT_PATH:-secret/k3s}"
VAULT_FIELD="${K3S_VAULT_FIELD:-server-token}"
INSTALL_K3S_VERSION="${INSTALL_K3S_VERSION:-v1.36.2+k3s1}"
REMOTE_CONFIG=/etc/rancher/k3s/config.yaml
die() { echo "error: $*" >&2; exit 1; }
usage() {
cat >&2 <<'EOF'
Usage: install.sh server|agent <ssh-target>
EOF
exit 2
}
scrub() {
token=''
unset token 2>/dev/null || true
}
trap scrub EXIT
[[ $# -eq 2 ]] || usage
role=$1
target=$2
case "$role" in
server|agent) ;;
*) die "role must be server or agent (got: $role)" ;;
esac
[[ -n "$target" ]] || die "ssh-target is empty"
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
case "$role" in
server) config=$script_dir/config.server.yaml ;;
agent) config=$script_dir/config.agent-nas.yaml ;;
esac
[[ -f "$config" ]] || die "missing config: $config"
if grep -qE '^[[:space:]]*token:[[:space:]]' "$config"; then
die "config must not contain token: ($config)"
fi
command -v vault >/dev/null || die "vault CLI not found"
command -v ssh >/dev/null || die "ssh not found"
command -v scp >/dev/null || die "scp not found"
token=$(vault kv get -field="$VAULT_FIELD" "$VAULT_PATH") \
|| die "failed to read $VAULT_FIELD from $VAULT_PATH"
[[ -n "$token" ]] || die "empty token from $VAULT_PATH field $VAULT_FIELD"
echo "role=$role target=$target config=$config version=$INSTALL_K3S_VERSION"
ssh -o BatchMode=yes "$target" "install -d -m 0755 /etc/rancher/k3s"
scp -o BatchMode=yes -q "$config" "${target}:/tmp/k3s-config.yaml"
ssh -o BatchMode=yes "$target" "install -m 0600 /tmp/k3s-config.yaml $REMOTE_CONFIG && rm -f /tmp/k3s-config.yaml"
# K3S_TOKEN must not appear in ssh/remote argv (visible in ps).
ssh -o BatchMode=yes "$target" 'bash -s' <<EOF
set -euo pipefail
set +o xtrace 2>/dev/null || true
export INSTALL_K3S_VERSION=$(printf '%q' "$INSTALL_K3S_VERSION")
export K3S_TOKEN=$(printf '%q' "$token")
curl -sfL https://get.k3s.io | sh -s - $(printf '%q' "$role")
unset K3S_TOKEN
EOF
scrub
echo "install finished on $target ($role)"

234
scripts/k3s/prepare-node.sh Executable file
View file

@ -0,0 +1,234 @@
#!/usr/bin/env bash
# Usage: prepare-node.sh [--defer-restart] <ssh-target>
# Host packages, Longhorn dir, runsc, internal CA + registries.yaml. Idempotent; before install.sh.
set -euo pipefail
CA_URL="${K3S_CA_URL:-https://vault.quorate.internal/v1/pki/ca/pem}"
CA_REMOTE=/etc/rancher/k3s/quorate-internal-ca.crt
REG_REMOTE=/etc/rancher/k3s/registries.yaml
die() { echo "error: $*" >&2; exit 1; }
usage() {
cat >&2 <<'EOF'
Usage: prepare-node.sh [--defer-restart] <ssh-target>
EOF
exit 2
}
defer_restart=0
if [[ ${1:-} == --defer-restart ]]; then
defer_restart=1
shift
fi
[[ $# -eq 1 ]] || usage
target=$1
[[ -n "$target" ]] || die "ssh-target is empty"
command -v ssh >/dev/null || die "ssh not found"
command -v scp >/dev/null || die "scp not found"
command -v curl >/dev/null || die "curl not found"
command -v openssl >/dev/null || die "openssl not found"
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
registries_src=$script_dir/registries.yaml
[[ -f $registries_src ]] || die "missing $registries_src"
workdir=$(mktemp -d)
trap 'rm -rf "$workdir"' EXIT
ca_local=$workdir/quorate-internal-ca.crt
curl -fsSL --max-time 30 "$CA_URL" -o "$ca_local" \
|| die "failed to fetch CA from $CA_URL"
openssl x509 -in "$ca_local" -noout 2>/dev/null \
|| die "fetched CA is not a valid PEM certificate"
openssl x509 -in "$ca_local" -noout -text | grep -q 'CA:TRUE' \
|| die "fetched certificate is not a CA"
echo "prepare-node target=$target"
ssh -o BatchMode=yes "$target" "install -d -m 0755 /etc/rancher/k3s"
scp -o BatchMode=yes -q "$ca_local" "${target}:/tmp/quorate-internal-ca.crt"
scp -o BatchMode=yes -q "$registries_src" "${target}:/tmp/k3s-registries.yaml"
ssh -o BatchMode=yes "$target" "bash -s -- $defer_restart" <<'REMOTE'
set -euo pipefail
export DEBIAN_FRONTEND=noninteractive
defer_restart=$1
if ! command -v apt-get >/dev/null; then
echo "error: only Debian-family apt hosts are supported" >&2
exit 1
fi
pkg_installed() {
dpkg-query -W -f='${Status}' "$1" 2>/dev/null | grep -q 'install ok installed'
}
need_k3s_restart=0
pkgs=(open-iscsi nfs-common xfsprogs smartmontools)
missing=()
for p in "${pkgs[@]}"; do
pkg_installed "$p" || missing+=("$p")
done
if ((${#missing[@]})); then
apt-get update -qq
apt-get install -y -qq "${missing[@]}"
fi
if systemctl cat iscsid.service >/dev/null 2>&1; then
systemctl is-enabled --quiet iscsid 2>/dev/null || systemctl enable iscsid >/dev/null
systemctl is-active --quiet iscsid 2>/dev/null || systemctl start iscsid
fi
install -d -m 0755 /var/lib/longhorn
inotify_file=/etc/sysctl.d/90-k3s-inotify.conf
inotify_limit=1024
inotify_setting="fs.inotify.max_user_instances = $inotify_limit"
install -d -m 0755 /etc/sysctl.d
if [[ ! -f $inotify_file ]] || ! cmp -s <(printf '%s\n' "$inotify_setting") "$inotify_file"; then
printf '%s\n' "$inotify_setting" >"$inotify_file"
fi
chmod 0644 "$inotify_file"
if [[ $(sysctl -n fs.inotify.max_user_instances) != "$inotify_limit" ]]; then
sysctl -p "$inotify_file"
fi
CA_REMOTE=/etc/rancher/k3s/quorate-internal-ca.crt
REG_REMOTE=/etc/rancher/k3s/registries.yaml
SYS_CA=/usr/local/share/ca-certificates/internal-root-ca.crt
install -d -m 0755 /etc/rancher/k3s
if [[ -f $CA_REMOTE ]] && cmp -s /tmp/quorate-internal-ca.crt "$CA_REMOTE"; then
:
else
install -m 0644 /tmp/quorate-internal-ca.crt "$CA_REMOTE"
need_k3s_restart=1
fi
if [[ -f $REG_REMOTE ]] && cmp -s /tmp/k3s-registries.yaml "$REG_REMOTE"; then
:
else
install -m 0644 /tmp/k3s-registries.yaml "$REG_REMOTE"
need_k3s_restart=1
fi
if [[ -f $SYS_CA ]] && cmp -s /tmp/quorate-internal-ca.crt "$SYS_CA"; then
:
else
install -d -m 0755 /usr/local/share/ca-certificates
install -m 0644 /tmp/quorate-internal-ca.crt "$SYS_CA"
update-ca-certificates >/dev/null
fi
rm -f /tmp/quorate-internal-ca.crt /tmp/k3s-registries.yaml
if ! command -v runsc >/dev/null 2>&1 || ! command -v containerd-shim-runsc-v1 >/dev/null 2>&1; then
for p in ca-certificates curl gnupg; do
pkg_installed "$p" || { apt-get update -qq; apt-get install -y -qq ca-certificates curl gnupg; break; }
done
if [[ ! -f /usr/share/keyrings/gvisor-archive-keyring.gpg ]]; then
curl -fsSL https://gvisor.dev/archive.key | gpg --dearmor -o /usr/share/keyrings/gvisor-archive-keyring.gpg
fi
arch=$(dpkg --print-architecture)
gvisor_list=/etc/apt/sources.list.d/gvisor.list
gvisor_line="deb [arch=${arch} signed-by=/usr/share/keyrings/gvisor-archive-keyring.gpg] https://storage.googleapis.com/gvisor/releases release main"
if [[ ! -f $gvisor_list ]] || ! grep -qxF "$gvisor_line" "$gvisor_list"; then
printf '%s\n' "$gvisor_line" >"$gvisor_list"
fi
if ! { apt-get update -qq && apt-get install -y -qq runsc \
&& command -v runsc >/dev/null && command -v containerd-shim-runsc-v1 >/dev/null; }; then
ARCH=$(uname -m)
URL=https://storage.googleapis.com/gvisor/releases/release/latest/${ARCH}
tmp=$(mktemp -d)
curl -fsSL -o "$tmp/gvisor.tar.bz2" "${URL}/gvisor.tar.bz2"
curl -fsSL -o "$tmp/gvisor.tar.bz2.sha512" "${URL}/gvisor.tar.bz2.sha512"
(cd "$tmp" && sha512sum -c gvisor.tar.bz2.sha512)
tar -xjf "$tmp/gvisor.tar.bz2" -C /usr/local/bin
rm -rf "$tmp"
fi
need_k3s_restart=1
fi
command -v runsc >/dev/null || { echo "error: runsc not on PATH" >&2; exit 1; }
command -v containerd-shim-runsc-v1 >/dev/null || {
echo "error: containerd-shim-runsc-v1 not on PATH" >&2
exit 1
}
ctd_dir=/var/lib/rancher/k3s/agent/etc/containerd
tmpl=$ctd_dir/config-v3.toml.tmpl
read -r -d '' desired_tmpl <<'TMPL' || true
{{ template "base" . }}
[plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.runsc]
runtime_type = "io.containerd.runsc.v1"
pod_annotations = ["dev.gvisor.spec.mount.var-run-argo.share", "dev.gvisor.spec.mount.var-run-argo.type", "dev.gvisor.spec.mount.var-run-argo.options"]
[plugins.'io.containerd.nri.v1.nri']
disable = false
disable_connections = false
plugin_config_path = "/etc/nri/conf.d"
plugin_path = "/opt/nri/plugins"
plugin_registration_timeout = "5s"
plugin_request_timeout = "2s"
socket_path = "/var/run/nri/nri.sock"
TMPL
mkdir -p "$ctd_dir"
if [[ -f $tmpl ]] && cmp -s <(printf '%s\n' "$desired_tmpl") "$tmpl"; then
:
else
printf '%s\n' "$desired_tmpl" >"$tmpl"
chmod 644 "$tmpl"
need_k3s_restart=1
fi
if [[ -f $ctd_dir/config.toml ]]; then
grep -q 'runtimes.runsc' "$ctd_dir/config.toml" || need_k3s_restart=1
grep -q 'io.containerd.nri.v1.nri' "$ctd_dir/config.toml" || need_k3s_restart=1
fi
k3s_unit=
if systemctl is-active --quiet k3s 2>/dev/null || systemctl is-enabled --quiet k3s 2>/dev/null; then
k3s_unit=k3s
elif systemctl is-active --quiet k3s-agent 2>/dev/null || systemctl is-enabled --quiet k3s-agent 2>/dev/null; then
k3s_unit=k3s-agent
fi
if [[ $need_k3s_restart -eq 1 ]]; then
if [[ $defer_restart -eq 1 ]]; then
echo "k3s restart: deferred"
elif [[ -n $k3s_unit ]]; then
systemctl restart "$k3s_unit"
fi
fi
if [[ $defer_restart -eq 0 && -n $k3s_unit ]]; then
grep -q 'io.containerd.nri.v1.nri' "$ctd_dir/config.toml"
grep -q 'socket_path = "/var/run/nri/nri.sock"' "$ctd_dir/config.toml"
for _ in {1..30}; do
[[ -S /var/run/nri/nri.sock ]] && break
sleep 1
done
[[ -S /var/run/nri/nri.sock ]] || {
echo "error: NRI socket not available after $k3s_unit restart" >&2
exit 1
}
fi
echo "packages: ${pkgs[*]}"
echo "longhorn: /var/lib/longhorn"
echo "runsc: $(runsc --version 2>&1 | head -1)"
echo "registry CA: $CA_REMOTE"
echo "registries: $REG_REMOTE"
echo "system CA: $SYS_CA"
echo "prepare-node finished on $(hostname)"
REMOTE
echo "prepare-node finished on $target"

View file

@ -0,0 +1,14 @@
mirrors:
zot.quorate.internal:
endpoint:
- "https://zot.quorate.internal"
registry.quorate.internal:
endpoint:
- "https://registry.quorate.internal"
configs:
zot.quorate.internal:
tls:
ca_file: /etc/rancher/k3s/quorate-internal-ca.crt
registry.quorate.internal:
tls:
ca_file: /etc/rancher/k3s/quorate-internal-ca.crt

16
scripts/kyverno-test.sh Executable file
View file

@ -0,0 +1,16 @@
#!/usr/bin/env bash
# Run the repository Kyverno CLI test suite.
# Local/manual gate until Argo Workflows CI exists; same entrypoint for that runner later.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
TEST_DIR="${ROOT}/vendor/platform/kyverno/tests"
KYVERNO_VERSION="${KYVERNO_VERSION:-v1.19.2}"
if ! command -v kyverno >/dev/null 2>&1; then
echo "kyverno CLI not found; install ${KYVERNO_VERSION} from kyverno releases" >&2
exit 127
fi
echo "kyverno $(kyverno version 2>/dev/null | head -1 || true)"
exec kyverno test "${TEST_DIR}"

89
scripts/tofu-pg-state Executable file
View file

@ -0,0 +1,89 @@
#!/usr/bin/env bash
set -euo pipefail
export VAULT_ADDR=https://vault.quorate.internal
state_host="${TF_STATE_PG_HOST:-10.234.158.153}"
state_port="${TF_STATE_PG_PORT:-5432}"
state_db="${TF_STATE_PG_DB:-tf_state}"
state_vault_path="${TF_STATE_PG_VAULT_PATH:-database/static-creds/tf-state}"
source_s3_key="${VERSITYGW_TERRAFORM_STATE_ACCESS_KEY_ID:-terraform-state}"
source_s3_path="${VERSITYGW_TERRAFORM_STATE_VAULT_PATH:-secret/versitygw/users/terraform-state}"
if [[ -z "${TF_CLI_CONFIG_FILE:-}" && -f dev.tfrc ]]; then
export TF_CLI_CONFIG_FILE=dev.tfrc
fi
tofu_subcommand=""
for arg in "$@"; do
case "$arg" in
-chdir=*)
;;
-*)
if [[ "$arg" == "-help" || "$arg" == "--help" || "$arg" == "-version" ]]; then
tofu_subcommand="$arg"
break
fi
;;
*)
tofu_subcommand="$arg"
break
;;
esac
done
needs_state_credentials=true
needs_s3_credentials=false
case "$tofu_subcommand" in
"" | "-help" | "--help" | "-version" | "version" | "fmt" | "validate" | "get" | "metadata")
needs_state_credentials=false
;;
"init")
for arg in "$@"; do
if [[ "$arg" == "-backend=false" ]]; then
needs_state_credentials=false
break
fi
if [[ "$arg" == "-migrate-state" ]]; then
needs_s3_credentials=true
fi
done
;;
esac
if [[ "$needs_state_credentials" == "false" ]]; then
exec tofu "$@"
fi
if ! command -v vault >/dev/null 2>&1; then
echo "vault CLI is required to read PostgreSQL Terraform state credentials" >&2
exit 1
fi
state_user="$(vault read -field=username "$state_vault_path")"
state_password="$(vault read -field=password "$state_vault_path")"
if [[ -z "$state_user" || -z "$state_password" ]]; then
echo "Vault credential $state_vault_path is incomplete" >&2
exit 1
fi
export PG_CONN_STR="postgres://${state_host}:${state_port}/${state_db}?sslmode=require"
export PGUSER="$state_user"
export PGPASSWORD="$state_password"
if [[ "$needs_s3_credentials" == "true" ]]; then
source_s3_secret="$(vault kv get -field=secretAccessKey "$source_s3_path")"
if [[ -z "$source_s3_secret" ]]; then
echo "Vault credential $source_s3_path is incomplete" >&2
exit 1
fi
export AWS_ACCESS_KEY_ID="$source_s3_key"
export AWS_SECRET_ACCESS_KEY="$source_s3_secret"
export AWS_REGION="${AWS_REGION:-us-east-1}"
export AWS_EC2_METADATA_DISABLED=true
fi
exec tofu "$@"

313
scripts/trust-internal-ca.sh Executable file
View file

@ -0,0 +1,313 @@
#!/usr/bin/env bash
# Fetch and system-trust the internal root CA from Vault.
#
# Usage: ./trust-internal-ca.sh [--expected-sha256 AA:BB:...] [--kube-context NAME]
# [--non-interactive] [--no-browsers] [--no-java]
set -euo pipefail
# ── Config ────────────────────────────────────────────────────────────────────
CERT_URL="https://vault.quorate.internal/v1/pki/ca/pem"
CERT_NAME="internal-root-ca"
EXPECTED_CN="Internal Root CA"
KUBE_CONTEXT="${KUBE_CONTEXT:-quorate}"
# ── Flags ─────────────────────────────────────────────────────────────────────
EXPECTED_FP=""
NON_INTERACTIVE=false
SKIP_BROWSERS=false
SKIP_JAVA=false
FETCHED_INSECURELY=false
while [[ $# -gt 0 ]]; do
case "$1" in
--expected-sha256) EXPECTED_FP="$2"; shift 2 ;;
--kube-context) KUBE_CONTEXT="$2"; shift 2 ;;
--non-interactive) NON_INTERACTIVE=true; shift ;;
--no-browsers) SKIP_BROWSERS=true; shift ;;
--no-java) SKIP_JAVA=true; shift ;;
*) echo "Unknown flag: $1" >&2; exit 1 ;;
esac
done
# ── Helpers ───────────────────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BOLD='\033[1m'; NC='\033[0m'
info() { echo -e "${GREEN}[+]${NC} $*"; }
warn() { echo -e "${YELLOW}[!]${NC} $*"; }
die() { echo -e "${RED}[✗]${NC} $*" >&2; exit 1; }
hr() { echo -e "${BOLD}────────────────────────────────────────────────────────${NC}"; }
require() { command -v "$1" &>/dev/null || die "Required tool not found: $1 — install it and retry"; }
confirm() {
local prompt="$1"
if $NON_INTERACTIVE; then
info "(non-interactive) auto-confirming: $prompt"
return 0
fi
read -r -p "$prompt [yes/N] " ans
[[ "${ans,,}" == "yes" ]] || die "Aborted by user."
}
require curl
require openssl
# ── Fetch ─────────────────────────────────────────────────────────────────────
TMPDIR_WORK=$(mktemp -d)
trap 'rm -rf "$TMPDIR_WORK"' EXIT
CERT_FILE="$TMPDIR_WORK/${CERT_NAME}.crt"
info "Fetching CA certificate from $CERT_URL ..."
if ! curl -fsSL --max-time 15 "$CERT_URL" -o "$CERT_FILE"; then
[[ -n "$EXPECTED_FP" ]] \
|| die "TLS verification failed. Retry with an out-of-band --expected-sha256 pin."
warn "TLS verification failed; retrying with the supplied fingerprint pin."
curl --insecure -fsSL --max-time 15 "$CERT_URL" -o "$CERT_FILE" \
|| die "Fetch failed — is vault.quorate.internal reachable?"
FETCHED_INSECURELY=true
fi
# ── Structural validation ─────────────────────────────────────────────────────
openssl x509 -in "$CERT_FILE" -noout 2>/dev/null \
|| die "Fetched content is not a valid PEM certificate"
IS_CA=$(openssl x509 -in "$CERT_FILE" -noout -text | grep -c "CA:TRUE" || true)
[[ "$IS_CA" -gt 0 ]] || die "Certificate does not have CA:TRUE — refusing to install a non-CA cert"
ACTUAL_CN=$(openssl x509 -in "$CERT_FILE" -noout -subject \
| sed -E 's/.*[Cc][Nn]\s*=\s*([^,\/]+).*/\1/')
if [[ "$ACTUAL_CN" != "$EXPECTED_CN" ]]; then
warn "Subject CN mismatch — expected '${EXPECTED_CN}', got '${ACTUAL_CN}'"
confirm "CN does not match. Continue anyway?"
fi
# ── Fingerprint display & verification ───────────────────────────────────────
SHA256=$(openssl x509 -in "$CERT_FILE" -noout -fingerprint -sha256 | cut -d= -f2)
SHA1=$(openssl x509 -in "$CERT_FILE" -noout -fingerprint -sha1 | cut -d= -f2)
hr
echo -e "${BOLD}Certificate details:${NC}"
openssl x509 -in "$CERT_FILE" -noout -subject -issuer -dates 2>/dev/null | sed 's/^/ /'
echo ""
echo -e " ${BOLD}SHA-256:${NC} $SHA256"
echo -e " ${BOLD}SHA-1: ${NC} $SHA1"
hr
# Pinned fingerprint check (if --expected-sha256 was passed)
if [[ -n "$EXPECTED_FP" ]]; then
EXPECTED_NORM="${EXPECTED_FP^^}" # normalise to upper
ACTUAL_NORM="${SHA256^^}"
if [[ "$EXPECTED_NORM" == "$ACTUAL_NORM" ]]; then
info "Fingerprint matches --expected-sha256."
else
die "Fingerprint MISMATCH — expected $EXPECTED_FP, got $SHA256"
fi
fi
# ── kubectl cross-verify (best-effort) ───────────────────────────────────────
if command -v kubectl &>/dev/null; then
info "kubectl detected — attempting cross-verify against cluster ..."
CLUSTER_FP=""
VAULT_POD=$(kubectl --context "$KUBE_CONTEXT" get pod -n vault \
-l app.kubernetes.io/name=vault -o jsonpath='{.items[0].metadata.name}' \
2>/dev/null || true)
if [[ -n "$VAULT_POD" ]]; then
CLUSTER_CA_PEM=$(kubectl --context "$KUBE_CONTEXT" exec -n vault "$VAULT_POD" -- \
vault read -address=https://vault-active-tls.vault.svc.cluster.local:443 \
-ca-cert=/vault/userconfig/vault-server-tls/ca.crt \
-tls-server-name=vault-active-direct.vault.svc.cluster.local \
-field=certificate pki/cert/ca 2>/dev/null || true)
if [[ -n "$CLUSTER_CA_PEM" ]]; then
CLUSTER_FP=$(echo "$CLUSTER_CA_PEM" \
| openssl x509 -noout -fingerprint -sha256 2>/dev/null | cut -d= -f2 || true)
[[ -n "$CLUSTER_FP" ]] && info "Cross-verify source: vault pod PKI CA"
fi
fi
if [[ -n "$CLUSTER_FP" ]]; then
if [[ "${CLUSTER_FP^^}" == "${SHA256^^}" ]]; then
info "Cluster cross-verify PASSED — fingerprints match."
else
warn "Cluster cross-verify FAILED — fingerprint from cluster: $CLUSTER_FP"
warn "Fingerprint from HTTP: $SHA256"
confirm "Fingerprints differ. Possible MITM or stale cert. Continue anyway?"
fi
else
warn "Could not retrieve CA cert from cluster for cross-verify."
warn "Manually check with: kubectl --context $KUBE_CONTEXT exec -n vault <pod> -- vault read pki/cert/ca"
fi
fi
# ── User confirmation ─────────────────────────────────────────────────────────
echo ""
if $FETCHED_INSECURELY; then
warn "TLS verification was disabled for bootstrap; the supplied SHA-256 pin matched."
fi
echo ""
confirm "Install and trust this CA certificate system-wide?"
# ── OS trust store install ────────────────────────────────────────────────────
install_debian() {
local dest="/usr/local/share/ca-certificates/${CERT_NAME}.crt"
info "Installing to $dest (Debian/Ubuntu)"
sudo install -m 644 "$CERT_FILE" "$dest"
sudo update-ca-certificates
}
install_rhel() {
local dest="/etc/pki/ca-trust/source/anchors/${CERT_NAME}.crt"
info "Installing to $dest (RHEL/Fedora)"
sudo install -m 644 "$CERT_FILE" "$dest"
sudo update-ca-trust extract
}
install_arch() {
local dest="/etc/ca-certificates/trust-source/anchors/${CERT_NAME}.crt"
info "Installing to $dest (Arch Linux)"
sudo install -m 644 "$CERT_FILE" "$dest"
sudo trust extract-compat
}
install_suse() {
local dest="/etc/pki/trust/anchors/${CERT_NAME}.crt"
info "Installing to $dest (openSUSE)"
sudo install -m 644 "$CERT_FILE" "$dest"
sudo update-ca-certificates
}
install_macos() {
info "Installing to macOS System Keychain (covers Safari and Chrome)..."
sudo security add-trusted-cert -d -r trustRoot \
-k /Library/Keychains/System.keychain "$CERT_FILE"
}
install_linux() {
# shellcheck source=/dev/null
. /etc/os-release
local id="${ID:-unknown}" like="${ID_LIKE:-}"
if [[ "$id" == "debian" || "$id" == "ubuntu" || "$like" == *"debian"* ]]; then install_debian
elif [[ "$id" == "fedora" || "$like" == *"fedora"* || "$like" == *"rhel"* || "$id" == "rhel" || "$id" == "centos" ]]; then install_rhel
elif [[ "$id" == "arch" || "$like" == *"arch"* ]]; then install_arch
elif [[ "$id" == "opensuse"* || "$like" == *"suse"* ]]; then install_suse
else
warn "Unknown distro '$id' — attempting Debian-style install"
install_debian
fi
}
# ── NSS (Firefox / Chrome on Linux) ──────────────────────────────────────────
install_nss() {
if ! command -v certutil &>/dev/null; then
warn "certutil not found — skipping NSS databases."
warn " Debian/Ubuntu: sudo apt install libnss3-tools"
warn " RHEL/Fedora: sudo dnf install nss-tools"
return
fi
local added=0
# Collect NSS database directories from Firefox and Chrome/Chromium
local nss_dirs=()
# Firefox profiles (standard, snap, flatpak)
while IFS= read -r -d '' db_dir; do
nss_dirs+=("$db_dir")
done < <(find \
"$HOME/.mozilla/firefox" \
"$HOME/snap/firefox/common/.mozilla/firefox" \
"$HOME/.var/app/org.mozilla.firefox/.mozilla/firefox" \
2>/dev/null -maxdepth 2 -name "cert9.db" -printf '%h\0' || true)
# Chrome/Chromium shared NSS db
for chrome_db in \
"$HOME/.pki/nssdb" \
"$HOME/.config/google-chrome/Default" \
"$HOME/.config/chromium/Default" \
"$HOME/snap/chromium/current/.pki/nssdb"; do
[[ -d "$chrome_db" ]] && nss_dirs+=("$chrome_db")
done
if [[ ${#nss_dirs[@]} -eq 0 ]]; then
warn "No NSS databases found under \$HOME."
return
fi
for db_dir in "${nss_dirs[@]}"; do
info " NSS: $db_dir"
# Remove any stale entry first (ignore failure if not present)
certutil -D -n "$CERT_NAME" -d "sql:$db_dir" 2>/dev/null || true
if certutil -A -n "$CERT_NAME" -t "CT,," -i "$CERT_FILE" -d "sql:$db_dir" 2>/dev/null; then
((added++))
else
warn "Failed to add cert to $db_dir"
fi
done
info "Added to $added NSS database(s)."
info "Restart Firefox/Chrome for the change to take effect."
}
# ── Java truststore ───────────────────────────────────────────────────────────
install_java() {
local keytool
keytool=$(command -v keytool 2>/dev/null || true)
if [[ -z "$keytool" ]]; then
warn "keytool not found — skipping Java truststore."
return
fi
# Find JAVA_HOME cacerts (handles OpenJDK layout and SDKMAN)
local cacerts=""
for candidate in \
"${JAVA_HOME:-}/lib/security/cacerts" \
"${JAVA_HOME:-}/jre/lib/security/cacerts" \
"$(dirname "$(readlink -f "$(command -v java)")")/../lib/security/cacerts" \
"$(dirname "$(readlink -f "$(command -v java)")")/../jre/lib/security/cacerts"; do
[[ -f "$candidate" ]] && { cacerts="$candidate"; break; }
done
if [[ -z "$cacerts" ]]; then
warn "Could not locate Java cacerts file — skipping Java truststore."
return
fi
info "Adding to Java truststore: $cacerts"
sudo keytool -importcert -noprompt \
-alias "$CERT_NAME" \
-file "$CERT_FILE" \
-keystore "$cacerts" \
-storepass changeit \
&& info "Java truststore updated." \
|| warn "Java truststore update failed (may already be present)."
}
# ── Main ──────────────────────────────────────────────────────────────────────
OS=$(uname -s)
case "$OS" in
Linux) install_linux ;;
Darwin) install_macos ;;
*) die "Unsupported OS: $OS" ;;
esac
if [[ "$OS" == "Linux" ]] && ! $SKIP_BROWSERS; then
echo ""
if $NON_INTERACTIVE; then
install_nss
else
read -r -p "Also install into Firefox/Chrome NSS databases for $USER? [y/N] " ans
[[ "${ans,,}" == "y" ]] && install_nss || true
fi
fi
if ! $SKIP_JAVA; then
echo ""
if $NON_INTERACTIVE; then
install_java
else
read -r -p "Also install into Java truststore? [y/N] " ans
[[ "${ans,,}" == "y" ]] && install_java || true
fi
fi
hr
info "CA certificate installed. New processes and tools will trust it immediately."
info "Browser sessions and Java apps need a restart to pick up the change."

47
scripts/vlq.sh Normal file
View file

@ -0,0 +1,47 @@
# Source this file to define vlq(), a small authenticated VictoriaLogs query
# helper backed by the caller's current Vault session.
vlq() (
set -euo pipefail
export VAULT_ADDR="${VAULT_ADDR:-https://vault.quorate.internal}"
command -v vault >/dev/null 2>&1 || {
printf 'vlq: vault CLI is required\n' >&2
return 127
}
command -v vlogscli-prod >/dev/null 2>&1 || {
printf 'vlq: vlogscli-prod is required\n' >&2
return 127
}
local server="${VLQ_SERVER:-https://logs.quorate.internal/select/logsql/query}"
local vault_path="${VLQ_VAULT_PATH:-secret/victorialogs/vmauth/query}"
local vault_field="${VLQ_VAULT_FIELD:-token}"
local history_file="${VLQ_HISTORY_FILE:-${XDG_STATE_HOME:-$HOME/.local/state}/vlq/history}"
local tmpdir token_file
tmpdir="$(mktemp -d "${TMPDIR:-/tmp}/vlq.XXXXXX")"
chmod 700 "$tmpdir"
trap 'rm -rf "$tmpdir"' EXIT
token_file="$tmpdir/token"
vault kv get -field="$vault_field" "$vault_path" >"$token_file"
chmod 600 "$token_file"
mkdir -p "$(dirname "$history_file")"
if [[ $# -gt 0 ]]; then
printf '%s\n\nq\n' "$*" | vlogscli-prod \
-datasource.url="$server" \
-bearerToken="file://$token_file" \
-historyFile="$history_file"
return
fi
vlogscli-prod \
-datasource.url="$server" \
-bearerToken="file://$token_file" \
-historyFile="$history_file"
)

42
scripts/vmq.sh Normal file
View file

@ -0,0 +1,42 @@
# Source this file to define vmq(), a small authenticated VictoriaMetrics query
# helper backed by the caller's current Vault session.
vmq() (
set -euo pipefail
export VAULT_ADDR="${VAULT_ADDR:-https://vault.quorate.internal}"
if [[ $# -lt 1 ]]; then
printf 'usage: vmq <promql expression>\n' >&2
return 2
fi
command -v vault >/dev/null 2>&1 || {
printf 'vmq: vault CLI is required\n' >&2
return 127
}
command -v promtool >/dev/null 2>&1 || {
printf 'vmq: promtool is required\n' >&2
return 127
}
local server="${VMQ_SERVER:-https://metrics.quorate.internal/prometheus}"
local vault_path="${VMQ_VAULT_PATH:-secret/victoriametrics/vmauth/query}"
local vault_field="${VMQ_VAULT_FIELD:-token}"
local tmpdir token_file http_config
tmpdir="$(mktemp -d "${TMPDIR:-/tmp}/vmq.XXXXXX")"
chmod 700 "$tmpdir"
trap 'rm -rf "$tmpdir"' EXIT
token_file="$tmpdir/token"
http_config="$tmpdir/http-config.yml"
vault kv get -field="$vault_field" "$vault_path" >"$token_file"
chmod 600 "$token_file"
printf 'authorization:\n type: Bearer\n credentials_file: %s\n' "$token_file" >"$http_config"
chmod 600 "$http_config"
promtool query instant --http.config.file="$http_config" "$server" "$*"
)