diff --git a/.envrc b/.envrc index 7ef2e518..a02acf70 100644 --- a/.envrc +++ b/.envrc @@ -1,26 +1,19 @@ # shellcheck disable=SC2148 export DIRENV_WARN_TIMEOUT=0 -export NIXPKGS_ALLOW_UNFREE=1 -use flake . --impure + +use flake . export_sops_secret() { - local var_name="$1" file="$2" key="$3" value - if value=$(sops -d --extract "$key" "$file" 2>/dev/null); then - export "$var_name=$value" + local variable_name="$1" secret_file="$2" secret_key="$3" value + if value=$(sops --decrypt --extract "$secret_key" "$secret_file" 2>/dev/null); then + export "$variable_name=$value" else - echo "direnv: skipping $var_name (could not decrypt $file)" >&2 + echo "direnv: could not decrypt $secret_file" >&2 fi } -export_sops_secret HCLOUD_TOKEN secrets/hetzner.yaml '["api_token"]' - -# Terraform's s3 backend (pointing at B2) reads these. export_sops_secret AWS_ACCESS_KEY_ID secrets/b2.yaml '["B2_KEY_ID"]' export_sops_secret AWS_SECRET_ACCESS_KEY secrets/b2.yaml '["B2_APP_KEY"]' - -# B2 native provider reads these. export_sops_secret B2_APPLICATION_KEY_ID secrets/b2.yaml '["B2_KEY_ID"]' export_sops_secret B2_APPLICATION_KEY secrets/b2.yaml '["B2_APP_KEY"]' - -# Tailscale provider reads this. export_sops_secret TAILSCALE_API_KEY secrets/tailscale-api.yaml '["api_key"]' diff --git a/.github/workflows/build-nix.yml b/.github/workflows/build-nix.yml index 742706ba..4addd476 100644 --- a/.github/workflows/build-nix.yml +++ b/.github/workflows/build-nix.yml @@ -1,47 +1,28 @@ concurrency: cancel-in-progress: true group: ${{ github.workflow }}-${{ github.ref }} + jobs: build-devShell-default: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 - with: - fetch-depth: 1 - - uses: DeterminateSystems/nix-installer-action@main - - uses: cachix/cachix-action@master - with: - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - name: cutehaus - - name: Build devShell default - env: - NIXPKGS_ALLOW_UNFREE: '1' - run: nix build --accept-flake-config --impure --print-out-paths .#devShells.x86_64-linux.default - build-package-gen-files: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - with: - fetch-depth: 1 - - uses: DeterminateSystems/nix-installer-action@main - - uses: cachix/cachix-action@master - with: - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - name: cutehaus - - name: Build package gen-files - run: nix build --accept-flake-config --print-out-paths .#packages.x86_64-linux.gen-files + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 1 + - uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25 # v22 + - name: Build devShell default + run: nix build --accept-flake-config --print-out-paths .#devShells.x86_64-linux.default + name: build-nix -'on': + +"on": pull_request: - paths: - - flake.lock - - flake.nix - - flake/ push: branches: - - master + - master paths: - - flake.lock - - flake.nix - - flake/ + - .github/** + - flake.lock + - flake.nix + - nix/devShells.nix workflow_dispatch: {} diff --git a/.github/workflows/build-nixos.yml b/.github/workflows/build-nixos.yml deleted file mode 100644 index 757555df..00000000 --- a/.github/workflows/build-nixos.yml +++ /dev/null @@ -1,72 +0,0 @@ -concurrency: - cancel-in-progress: true - group: ${{ github.workflow }}-${{ github.ref }} -jobs: - build-jubilife: - runs-on: ubuntu-latest - steps: - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@main - - name: Checkout - uses: actions/checkout@v7 - with: - fetch-depth: 1 - - name: Install Nix - uses: DeterminateSystems/nix-installer-action@main - - name: Cachix - uses: cachix/cachix-action@master - with: - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - name: cutehaus - - name: Build jubilife - run: nix build --accept-flake-config --print-out-paths .#nixosConfigurations.jubilife.config.system.build.toplevel - build-pastoria: - runs-on: ubuntu-latest - steps: - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@main - - name: Checkout - uses: actions/checkout@v7 - with: - fetch-depth: 1 - - name: Install Nix - uses: DeterminateSystems/nix-installer-action@main - - name: Cachix - uses: cachix/cachix-action@master - with: - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - name: cutehaus - - name: Build pastoria - run: nix build --accept-flake-config --print-out-paths .#nixosConfigurations.pastoria.config.system.build.toplevel - build-snowpoint: - runs-on: ubuntu-latest - steps: - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@main - - name: Checkout - uses: actions/checkout@v7 - with: - fetch-depth: 1 - - name: Install Nix - uses: DeterminateSystems/nix-installer-action@main - - name: Cachix - uses: cachix/cachix-action@master - with: - authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - name: cutehaus - - name: Build snowpoint - run: nix build --accept-flake-config --print-out-paths .#nixosConfigurations.snowpoint.config.system.build.toplevel -name: build-nixos -'on': - pull_request: - paths-ignore: - - k8s/** - push: - branches: - - master - paths-ignore: - - k8s/** - - '**/*.md' - - .github/** - - _img/** - workflow_dispatch: {} diff --git a/.github/workflows/check-config.yml b/.github/workflows/check-config.yml deleted file mode 100644 index 5b251430..00000000 --- a/.github/workflows/check-config.yml +++ /dev/null @@ -1,99 +0,0 @@ -name: check-config - -concurrency: - cancel-in-progress: true - group: ${{ github.workflow }}-${{ github.ref }} - -on: - pull_request: - push: - branches: - - master - paths-ignore: - - "**/*.md" - - .github/** - - _img/** - workflow_dispatch: {} - -jobs: - consistency-checks: - name: Bun consistency checks - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - with: { fetch-depth: 1 } - - uses: oven-sh/setup-bun@v2 - - run: bun scripts/check.ts - - chart-templates: - name: render declared Helm releases - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - with: { fetch-depth: 1 } - - uses: oven-sh/setup-bun@v2 - - uses: actions/setup-go@v7 - with: { go-version: "1.26" } - - uses: azure/setup-helm@v5 - - name: Install kubeconform - run: | - go install github.com/yannh/kubeconform/cmd/kubeconform@v0.7.0 - echo "$(go env GOPATH)/bin" >> "$GITHUB_PATH" - - name: lint, render, and schema-check declared local releases - run: bun scripts/render-releases.ts - - flux-kustomize: - name: flux kustomize build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - with: { fetch-depth: 1 } - - uses: azure/setup-kubectl@v5 - - name: kubectl kustomize each flux layer - run: | - set -e - for dir in \ - k8s/flux/system \ - k8s/flux/sources \ - k8s/flux/secrets \ - k8s/flux/infra-crds \ - k8s/flux/infra-core \ - k8s/flux/platform \ - k8s/flux/apps \ - k8s/flux/external-routes; do - echo "::group::$dir" - kubectl kustomize "$dir" >/dev/null - echo "::endgroup::" - done - - ansible-syntax: - name: ansible playbook syntax - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - with: { fetch-depth: 1 } - - uses: actions/setup-python@v7 - with: { python-version: "3.x" } - - name: Install ansible-core + collections - run: | - pip install --quiet ansible-core - ansible-galaxy collection install kubernetes.core community.sops - - name: Syntax check every playbook - run: | - set -e - for playbook in ansible/playbooks/*.yml; do - echo "::group::$playbook" - ansible-playbook --syntax-check "$playbook" - echo "::endgroup::" - done - - terraform-validate: - name: terraform fmt + validate - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v7 - with: { fetch-depth: 1 } - - uses: hashicorp/setup-terraform@v4 - - run: terraform -chdir=terraform fmt -check -diff - - run: terraform -chdir=terraform init -backend=false -input=false - - run: terraform -chdir=terraform validate diff --git a/.github/workflows/check-nix.yml b/.github/workflows/check-nix.yml index 969f1a41..0aa322d8 100644 --- a/.github/workflows/check-nix.yml +++ b/.github/workflows/check-nix.yml @@ -1,27 +1,25 @@ concurrency: cancel-in-progress: true group: ${{ github.workflow }}-${{ github.ref }} + jobs: check-flake: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 - with: - fetch-depth: 1 - - uses: DeterminateSystems/nix-installer-action@main - - name: Check flake evaluation - run: nix -Lv flake check + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + fetch-depth: 1 + - uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25 # v22 + - name: Check flake evaluation + run: nix -Lv flake check + name: check-nix -'on': + +"on": pull_request: - paths-ignore: - - k8s/** push: branches: - - master + - master paths-ignore: - - k8s/** - - '**/*.md' - - .github/** - - _img/** + - "**/*.md" workflow_dispatch: {} diff --git a/.gitignore b/.gitignore index 20936080..2052745d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,12 @@ .DS_Store -.direnv -.helix/ -.pre-commit-config.yaml -.vscode/ +.direnv/ .zed/ result -# Materialized helm subchart deps (regenerated by helm dependency update) -k8s/charts/*/charts/ - -# Bun deps for scripts/ (regenerated by `bun install`) -scripts/node_modules/ - -# Terraform state lives in B2 (aly-backups/cute.haus/terraform/), but the -# local cache + plan files can still appear in this directory. +# OpenTofu state lives in B2, but local state and plans may still appear. +# The provider lock file stays tracked so every machine resolves the same +# provider versions. terraform/.terraform/ -terraform/.terraform.lock.hcl terraform/*.tfstate terraform/*.tfstate.* terraform/*.tfplan diff --git a/.justfile b/.justfile index a502b297..bd322f53 100644 --- a/.justfile +++ b/.justfile @@ -1,278 +1,71 @@ -# just is a command runner, Justfile is very similar to Makefile, but simpler. -############################################################################ -# -# Common recipes -# -############################################################################ - -# List all recipes. _default: - @printf '\033[1;36mnixcfg recipes\033[0m\n\n' - @printf '\033[1;33mUsage:\033[0m just [args...]\n\n' - @just --list --list-heading $'Available recipes:\n\n' - -# Regenerate editor config (.zed/settings.json). -[group('flake')] -gen: - nix run .#gen-files - -# Update flake inputs. -[group('flake')] -update *inputs: - nix flake update {{ inputs }} --commit-lock-file - -# Update all nixpkgs inputs. -[group('flake')] -update-nixpkgs: (update "nixpkgs") - -# Update caddy-tailscale plugin to latest commit (also refreshes hash if stale). -[group('flake')] -update-caddy-tailscale: - bun scripts/update-caddy-tailscale.ts + @just --list -############################################################################ -# -# Servers -# -############################################################################ +[group('opentofu')] +fmt: + tofu -chdir=terraform fmt -# Build a NixOS host locally without deploying. -[group('servers')] -build host: - nix build .#nixosConfigurations.{{host}}.config.system.build.toplevel +[group('opentofu')] +validate: + tofu -chdir=terraform init -backend=false -input=false + tofu -chdir=terraform validate -# Deploy hosts with blzrd. -[group('servers')] -deploy jobs='': - blzrd switch {{ jobs }} +[group('opentofu')] +plan: + tofu -chdir=terraform init + tofu -chdir=terraform plan -# Reboot all servers. -[group('servers')] -reboot: - ansible-playbook -i ansible/inventory.ini ansible/playbooks/reboot.yml +[group('opentofu')] +apply: + tofu -chdir=terraform init + tofu -chdir=terraform apply -# Ping all servers. -[group('servers')] -ping: - ansible-playbook -i ansible/inventory.ini ansible/playbooks/ping.yml - -# Queue offline deployment & reboot. -[group('servers')] -deploy-offline: - blzrd boot - just reboot - -############################################################################ -# -# Secrets (sops + age) -# -############################################################################ - -# Derive this machine's age private key from its ssh ed25519 key, install -# at ~/.config/sops/age/keys.txt. Run once per machine. The corresponding -# public key (age1...) must already be a recipient in .sops.yaml. [group('secrets')] -sops-bootstrap: - #!/usr/bin/env bash - set -euo pipefail - if [[ -f ~/.config/sops/age/keys.txt ]]; then - echo "~/.config/sops/age/keys.txt already exists; skipping." - exit 0 - fi - mkdir -p ~/.config/sops/age - ssh-to-age -private-key -i ~/.ssh/id_ed25519 > ~/.config/sops/age/keys.txt - chmod 600 ~/.config/sops/age/keys.txt - echo "wrote ~/.config/sops/age/keys.txt" - echo "this machine's age recipient (must be in .sops.yaml):" - ssh-to-age -i ~/.ssh/id_ed25519.pub +sops-edit FILE: + sops secrets/{{FILE}}.yaml -# Regenerate .sops.yaml from keys/*.pub, then re-encrypt every managed SOPS -# file. Run after adding or removing a .pub file. [group('secrets')] sops-rekey: #!/usr/bin/env bash set -euo pipefail shopt -s nullglob - user_pubs=(keys/aly_*.pub) - host_pubs=(keys/root_*.pub) - flux_pubs=(keys/flux_*.pub) + user_keys=(keys/aly_*.pub) + host_keys=(keys/root_*.pub) { cat <<'EOF' # Auto-generated by `just sops-rekey` from keys/*.pub. - # User and host keys decrypt legacy secrets/*.yaml. Flux keys decrypt - # only k8s/flux/secrets/*.sops.yaml. + # Every recipient can decrypt every secret. To add or remove a machine, + # add or remove its .pub file and re-run `just sops-rekey`. keys: # === user keys (aly@) === EOF - for f in "${user_pubs[@]}"; do - host=$(basename "$f" .pub); host=${host#aly_} - age=$(ssh-to-age -i "$f") - printf ' - &user_aly_%s %s\n' "$host" "$age" + for key_file in "${user_keys[@]}"; do + host_name=$(basename "$key_file" .pub); host_name=${host_name#aly_} + age_key=$(ssh-to-age -i "$key_file") + printf ' - &user_aly_%s %s\n' "$host_name" "$age_key" done echo " # === host keys (root@) ===" - for f in "${host_pubs[@]}"; do - host=$(basename "$f" .pub); host=${host#root_} - age=$(ssh-to-age -i "$f") - printf ' - &host_%s %s\n' "$host" "$age" + for key_file in "${host_keys[@]}"; do + host_name=$(basename "$key_file" .pub); host_name=${host_name#root_} + age_key=$(ssh-to-age -i "$key_file") + printf ' - &host_%s %s\n' "$host_name" "$age_key" done - if ((${#flux_pubs[@]} > 0)); then - echo " # === flux keys ===" - for f in "${flux_pubs[@]}"; do - name=$(basename "$f" .pub); name=${name#flux_} - age=$(<"$f") - printf ' - &flux_%s %s\n' "$name" "$age" - done - fi cat <<'EOF' creation_rules: - - path_regex: ^k8s/flux/secrets/.*\.sops\.ya?ml$ - key_groups: - - age: - EOF - for f in "${user_pubs[@]}"; do - host=$(basename "$f" .pub); host=${host#aly_} - printf ' - *user_aly_%s\n' "$host" - done - for f in "${host_pubs[@]}"; do - host=$(basename "$f" .pub); host=${host#root_} - printf ' - *host_%s\n' "$host" - done - for f in "${flux_pubs[@]}"; do - name=$(basename "$f" .pub); name=${name#flux_} - printf ' - *flux_%s\n' "$name" - done - cat <<'EOF' - - path_regex: ^secrets/.*\.ya?ml$ key_groups: - age: EOF - for f in "${user_pubs[@]}"; do - host=$(basename "$f" .pub); host=${host#aly_} - printf ' - *user_aly_%s\n' "$host" + for key_file in "${user_keys[@]}"; do + host_name=$(basename "$key_file" .pub); host_name=${host_name#aly_} + printf ' - *user_aly_%s\n' "$host_name" done - for f in "${host_pubs[@]}"; do - host=$(basename "$f" .pub); host=${host#root_} - printf ' - *host_%s\n' "$host" + for key_file in "${host_keys[@]}"; do + host_name=$(basename "$key_file" .pub); host_name=${host_name#root_} + printf ' - *host_%s\n' "$host_name" done } > .sops.yaml - echo "regenerated .sops.yaml" - secret_files=(secrets/*.yaml k8s/flux/secrets/*.sops.yaml) - for f in "${secret_files[@]}"; do - echo "rekeying $f" - sops updatekeys -y "$f" + for secret_file in secrets/*.yaml; do + sops updatekeys -y "$secret_file" done - -# Edit a sops-encrypted secrets file. Usage: just sops-edit vaultwarden.yaml -[group('secrets')] -sops-edit FILE: - sops secrets/{{FILE}} - -############################################################################ -# -# Kubes (k3s + flux) -# -############################################################################ - -# Run all consistency + flake checks. -[group('kubes')] -check: - bun scripts/check.ts - bun scripts/render-releases.ts - for dir in k8s/flux/system k8s/flux/sources k8s/flux/secrets k8s/flux/infra-crds k8s/flux/infra-core k8s/flux/platform k8s/flux/apps k8s/flux/external-routes; do kubectl kustomize "$dir" >/dev/null; done - nix flake check --impure - -# Render every HelmRelease the way Flux does (resolving valuesFrom), like CI. -# flux-local isn't packaged in nixpkgs; run it via uv (uses the devShell's -# kustomize/helm/flux binaries). -[group('kubes')] -flux-test: - uvx flux-local@8.3.0 test --enable-helm --path k8s/flux - -# Concise live Flux, workload, storage, certificate, and warning-event health. -[group('kubes')] -k8s-status: - bun scripts/k8s-status.ts - -# Bump a public digest-pinned Helm or raw-workload image to its current upstream digest. -# Usage: just bump | just bump --all | just bump --check -[group('kubes')] -bump TARGET: - bun scripts/bump-image.ts {{ TARGET }} - -# Flux release helper. Git is the normal deployment path; `diff` previews a -# local in-tree chart, and the other actions operate on its HelmRelease. -# Usage: just k8s {diff|suspend|resume|reconcile} [target-namespace] [helmrelease-namespace] -[group('kubes')] -k8s action release namespace='default' hr_namespace='flux-system': - #!/usr/bin/env bash - set -euo pipefail - chart="k8s/charts/{{release}}" - flux_cmd() { - if command -v flux >/dev/null 2>&1; then - flux "$@" - else - nix develop -c flux "$@" - fi - } - - # Render the cute-haus-global values to a temp file — the same ConfigMap - # Flux feeds every chart via valuesFrom, so local apply/diff match runtime. - global_values() { - local out; out="$(mktemp)" - kubectl kustomize k8s/flux/sources \ - | yq e 'select(.kind == "ConfigMap" and .metadata.name == "cute-haus-global") | .data["values.yaml"]' - \ - > "$out" - echo "$out" - } - - case "{{action}}" in - diff) - if [[ ! -f "$chart/Chart.yaml" ]]; then - echo "just k8s diff supports local charts only: $chart/Chart.yaml not found" >&2 - exit 2 - fi - values="$(global_values)"; trap 'rm -f "$values"' EXIT - helm diff upgrade --allow-unreleased "{{release}}" "$chart" \ - -n "{{namespace}}" -f "$values" - ;; - suspend) - flux_cmd suspend helmrelease "{{release}}" -n "{{hr_namespace}}" - ;; - resume) - flux_cmd resume helmrelease "{{release}}" -n "{{hr_namespace}}" - ;; - reconcile) - flux_cmd reconcile helmrelease "{{release}}" -n "{{hr_namespace}}" --with-source - ;; - *) - echo "usage: just k8s {diff|suspend|resume|reconcile} [target-namespace] [helmrelease-namespace]" >&2 - exit 2 - ;; - esac - -# Bump tranquil-pds to its current atcr.io digest. Separate from `just bump` -# because atcr.io is private — `skopeo --no-creds` can't reach it. -[group('kubes')] -bump-tranquil: - #!/usr/bin/env bash - set -euo pipefail - TEMPLATE=k8s/flux/apps/tranquil-pds/deployment.yaml - FULL=$(grep 'image:.*@sha256:' "$TEMPLATE" | awk '{print $2}') - REPO="${FULL%%:*}" - TAG_WITH_DIGEST="${FULL#*:}" - FLOAT_TAG="${TAG_WITH_DIGEST%%@*}" - CURRENT_DIGEST="${TAG_WITH_DIGEST#*@}" - USERNAME=$(sops -d --extract '["username"]' secrets/atcr.yaml) - PASSWORD=$(sops -d --extract '["password"]' secrets/atcr.yaml) - UPSTREAM=$(skopeo inspect --creds "$USERNAME:$PASSWORD" \ - "docker://${REPO}:${FLOAT_TAG}" --format '{{"{{"}}.Digest{{"}}"}}') - if [[ "$UPSTREAM" == "$CURRENT_DIGEST" ]]; then - echo "tranquil-pds: ✓ up to date" - exit 0 - fi - echo "tranquil-pds: ${CURRENT_DIGEST:7:12} → ${UPSTREAM:7:12}" - sed -i "s|@${CURRENT_DIGEST}|@${UPSTREAM}|" "$TEMPLATE" - git add "$TEMPLATE" - git commit -m "k8s/tranquil-pds: ${FLOAT_TAG}@${CURRENT_DIGEST:7:12} → ${FLOAT_TAG}@${UPSTREAM:7:12}" diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 3d859bfe..00000000 --- a/.prettierignore +++ /dev/null @@ -1,3 +0,0 @@ -.github -flake.lock -k8s/charts/*/templates diff --git a/.sops.yaml b/.sops.yaml index 6d673462..253394cd 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -1,51 +1,25 @@ # Auto-generated by `just sops-rekey` from keys/*.pub. -# User and host keys decrypt legacy secrets/*.yaml. Flux keys decrypt -# only k8s/flux/secrets/*.sops.yaml. +# Every recipient can decrypt every secret. To add or remove a machine, +# add or remove its .pub file and re-run `just sops-rekey`. keys: # === user keys (aly@) === - - &user_aly_fortree age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - &user_aly_jubilife age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku + - &user_aly_fortree age1tgm3rcc2glqjxl5al2r780aweywv5tc2u065fzqlntwjzws4kckqepz7nl + - &user_aly_goldenrod age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku + - &user_aly_mauville age1876lthmlfq2aq6nm6z2qyu0ed4aa5ss68xvnlw5cqxcdtzslaqrqzgcmlm - &user_aly_pacifidlog age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - &user_aly_petalburg age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - &user_aly_rustboro age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - &user_aly_snowpoint age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s + - &user_aly_rustboro age1fczwtlqdqq7pjyzna2yl9nvmhpe68zk5k6nyn0dt4sp0lts04anskhcmu6 - &user_aly_sootopolis age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl # === host keys (root@) === - - &host_jubilife age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - &host_pastoria age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - &host_petalburg age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - &host_snowpoint age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - # === flux keys === - - &flux_k8s age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth creation_rules: - - path_regex: ^k8s/flux/secrets/.*\.sops\.ya?ml$ - key_groups: - - age: - - *user_aly_fortree - - *user_aly_jubilife - - *user_aly_pacifidlog - - *user_aly_petalburg - - *user_aly_rustboro - - *user_aly_snowpoint - - *user_aly_sootopolis - - *host_jubilife - - *host_pastoria - - *host_petalburg - - *host_snowpoint - - *flux_k8s - - path_regex: ^secrets/.*\.ya?ml$ key_groups: - age: - *user_aly_fortree - - *user_aly_jubilife + - *user_aly_goldenrod + - *user_aly_mauville - *user_aly_pacifidlog - *user_aly_petalburg - *user_aly_rustboro - - *user_aly_snowpoint - *user_aly_sootopolis - - *host_jubilife - - *host_pastoria - - *host_petalburg - - *host_snowpoint diff --git a/AGENTS.md b/AGENTS.md index b17120d7..f33a8be0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,105 +1,10 @@ # AGENTS.md -NixOS + k3s cluster IaC for cute.haus. Single operator. Flake-parts -NixOS configs on bare-metal/VPS hosts; Flux-managed in-tree Helm charts on -k3s; SOPS+age secrets; Cloudflare/B2 via Terraform. - -## Environment - -- `direnv allow` loads the flake (`use flake . --impure`, sets - `NIXPKGS_ALLOW_UNFREE=1`) and decrypts `CLOUDFLARE_API_TOKEN`, - `HCLOUD_TOKEN`, and B2 keys into env from `secrets/*.yaml` (used by - terraform). The devShell runs `gen-files` on entry. -- Everything runs through the Nix flake; there is no global toolchain. The - `.justfile` is the command source of truth — run `just` to list recipes. - -## Commands - -| Task | Command | -| ------------------------------ | ------------------------------------------------------------------ | -| Local pre-push gate | `just check` → `bun scripts/check.ts` + `nix flake check --impure` | -| Build a NixOS host (no deploy) | `just build ` (`jubilife` `pastoria` `snowpoint`) | -| Deploy all hosts | `just deploy` (`blzrd switch`) | -| Offline deploy + reboot | `just deploy-offline` | -| Update flake inputs | `just update [inputs]` / `just update-nixpkgs` | -| Regenerate editor config | `just gen` (writes `.zed/settings.json`) | -| Edit a secret | `just sops-edit ` (`secrets/`) | -| Rekey after key change | `just sops-rekey` (after adding/removing `keys/*.pub`) | -| Bump pinned image digests | `just bump ` / `--all` / `--check` | -| Bump private-registry image | `just bump-tranquil` (atcr.io, needs sops creds) | - -`scripts/` is Bun + TypeScript (`bun scripts/.ts`); `scripts/check.ts` -runs three consistency checks (forward-auth, release-names, pinned-images). - -## CI (`.github/workflows/`) - -- `check-config`: bun checks, `helm template` each chart, ansible - `--syntax-check`, terraform `fmt -check` + `init -backend=false` + `validate`. -- `check-nix`: `nix -Lv flake check`. -- `build-nixos`: builds all 4 host toplevels. -- `build-nix`: builds `devShells.default` + `packages.gen-files` (only on - `flake.lock`/`flake.nix` changes). -- PR + push to `master`; `**/*.md`, `.github/**`, `_img/**` ignored (except - build-nix). Renovate auto-merges minor/patch/digest on a schedule. - -## Formatting - -Defined in `nix/treefmt.nix` (no checked-in `treefmt.toml`; generated by -treefmt-nix). Enforced via `nix flake check` in `just check`. - -- Nix: **alejandra** (not nixpkgs-fmt) + deadnix + statix. -- YAML/JSON/MD: prettier. Shell: shfmt (2-space) + shellcheck. -- TOML: taplo. HCL: terraform. - -## Architecture - -- `nix/modules/` — dendritic flake-parts tree loaded wholesale by import-tree. - Shared NixOS files contribute directly to `flake.nixosModules.default` or a - named deferred module. Hosts live in `nix/modules/hosts/nixos//`: - topical sibling files contribute to `flake.nixosModules.`, while - `default.nix` constructs `config.flake.nixosConfigurations.` from the - shared, named, and host deferred modules. Importing a named deferred module - activates it; `myNixOs.*` and `myDisko.*` options only parameterize imported - modules. Disko modules live in `nix/modules/disko/`. k3s node config is in - `nix/modules/nixos/profiles/k3s.nix` (flannel on the configured transport - interface; startup blocks until that interface has an IP). -- `k8s/` — `flux/` is the ordered release graph. `flux/system/layers.yaml` - defines the Flux Kustomization DAG; `flux/*/*.yaml` hold HelmReleases; - `flux/secrets/*.sops.yaml` are first-class Kubernetes Secrets decrypted by - Flux. `charts//` are in-tree charts with **explicit manifests, no - shared helpers** (see `k8s/charts/README.md`). - `flux/sources/global.values.yaml` holds shared non-secret image pins + - constants; kustomize generates the `cute-haus-global` ConfigMap from it - (`configMapGenerator` in `flux/sources/kustomization.yaml`). -- `secrets/` — SOPS, multi-recipient age. `.sops.yaml` is generated; never - hand-edit either. -- `keys/` — `aly_.pub` (user key) + `root_.pub` (host key) age - recipients. Add/remove a `.pub` then `just sops-rekey`. -- `terraform/` — Cloudflare DNS + B2 buckets. Remote state in B2 with **no - locking** (don't run from two places at once). -- `ansible/` — `inventory.ini` (the 4 deployable hosts). Playbooks live in - `playbooks/`. `playbooks/pocket-id-bootstrap.yml` reconciles Pocket ID app - config, OIDC clients, and per‑app SSO integrations. Client declarations are - the source of truth in `playbooks/vars/oidc-clients.yml`; add a client there, - and optionally point `integration:` at a file under - `playbooks/tasks/integrations/` for apps that consume the creds in k3s. - Shared OIDC helpers are in `playbooks/tasks/oidc/`. Run playbooks inside the - flake dev shell: - - ```bash - direnv exec . ansible-playbook -i ansible/inventory.ini ansible/playbooks/pocket-id-bootstrap.yml --check --diff - ``` - -## Conventions & gotchas - -- **Every deployed chart must sha256-pin its container images** - (`image: repo:tag@sha256:...` or `image: {repository, tag: ...@sha256:...}`), - enforced by `check-pinned-images.ts`. Shared images (alpine, rclone) live - in `k8s/flux/sources/global.values.yaml`. Renovate keeps digests fresh (skips - `tranquil`, which is on private atcr.io — use `just bump-tranquil`). -- **forward-auth OIDC slugs** must be `forward-auth-` and match a key in - the plaintext `apps:` map in `k8s/flux/apps/releases.yaml` (enforced by - `check-forward-auth.ts`). -- k3s node labels: `topology.kubernetes.io/zone` (cloud/home), - `cute.haus/ingress=true`, and `cute.haus/intel-gpu=true` (NixOS module). - For GPU pods request the `gpu.intel.com/i915` resource, not a nodeSelector. +This repository manages B2 buckets and the Tailscale ACL. + +- Keep host, Kubernetes, and application changes in `sinnoh`, `johto`, or + `hoenn`. +- Run `tofu -chdir=terraform plan` before any apply. +- B2 stores OpenTofu state without locking. Never run concurrent applies. +- `secrets/` uses every recipient in `keys/`. Do not print decrypted values. +- Use `just fmt` and `just validate` after OpenTofu edits. diff --git a/README.md b/README.md index 9609943f..c1b0c621 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,21 @@ -# ❄️ cute.haus +# Shared infrastructure -Welcome to **cute.haus**! +`infra` holds the shared account-level configuration: Backblaze B2 buckets and +the Tailscale tailnet ACL. It does not run a cluster. -This repository contains NixOS, K8s, and Ansible configurations, along with whatever custom modules and packages required for [cute.haus](https://cute.haus), my production infrastructure running NixOS+Kubernetes. +Sinnoh runs public services. Johto runs home services. Hoenn configures +personal machines. Their NixOS hosts, Kubernetes manifests, application +secrets, and deployment automation stay there. ---- +The Git history still has the former all-in-one configuration. -![](./_img/glance.png) +## Layout ---- +- `terraform/` contains the shared state and provider configuration. +- `secrets/` contains the encrypted B2 and Tailscale credentials. +- `docs/` contains runbooks. -## 📂 Repository Structure +## Runbooks -```plaintext -. -├── flake.nix # Flake entry point -├── nix/ # NixOS + flake modules -│ └── modules/ # Dendritic flake, NixOS, Disko, and host modules -├── k8s/ # k3s: Flux + in-tree Helm charts -│ ├── flux/ # GitOps release graph (Flux Kustomizations/HelmReleases) -│ ├── charts/ # In-tree helm charts (see k8s/charts/README.md) -│ └── values/ # Shared non-secret Helm values -├── secrets/ # SOPS-encrypted yaml (multi-recipient age) -├── keys/ # Per-host + per-user age recipients -├── terraform/ # Cloudflare DNS, etc. -└── ansible/ # Server playbooks (deploy-offline, reboots) -``` - ---- - -## 📜 License - -This repository is licensed under the **[GNU General Public License](LICENSE.md)**. - ---- +- [Change OpenTofu](docs/change-opentofu.md) +- [Change SOPS recipients](docs/sops.md) diff --git a/_img/glance.png b/_img/glance.png deleted file mode 100644 index 7f096bab3c8154aef3530c27fb6fa92ddbe719f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 391016 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

{hwFg5lTMt9M?o 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�Bv> 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

OUG10HH6;f(FL-tRXlqaxx8d~i zE6P)Vju8uFsjEt!fy#&$_Jaq;REht*g%)`4|3n zPB&7$Po6uosKjskiJjtix6BYO`Z#3@Gq+BZv~88i-943u6P7tT9^6v&)JyXCri#}$ z)90H?T1Sf&{q02K!+b-3{3w42> zDud#5@50@+=>kPN{|fCYW16S(WL5A+xzd&2XIwMwKChK|B)sc`m+~X4>c0}QHt8C6 zM(+DkPaoGb+SDgfsCh1~HFn>RUw>~u3x34>SucKFY~t%GZeCsA)#2->P1W6*!7FVx zN6mkp&g*^ueyuL~@jfXfW2>%V*tR#a5aZJ9$-T=YkCv6h4Y-r2jV1 zjICK3_@=kw*0$$NZ!KkdGoDtn`HTh8JGrP+^0&EVqUFnf7ysQ&d(YTWdzoFo{zZkvYRz-QC!la zSgQ>`#b@6RKg`N4uD8f*s+O1g%7=&BxnAcz&Qx0N`#Z{Fim6!pflnD99yqeS46M+T zum5AXHSccQrAwDGZ){jNWlGA9!o!)IKbO=wG}zzWS=>HNCo)O!@FLgl&RFhsF*}`v z)iPv`ywN*ZhFSGMYdBW%y>4<<%-r5Dbu2sj<;-4N3TT8 za$SF{e^PjX=Bc~eudXtCv-Zi|a*d~Qw_HoY|4*q~J?(79lMcl&)7=>tg`)PP%nU8< z-W4?8u6FCXh-EE4Hf&{b5gQT~+UOKMKNl;x{Sa0KR-Wz`SbaFW2-OU z-rnZ^c&+`@X8F1wjbggLt}d8o+!FJC-|uxLtDhQWUGdmec=$qSqy1%D6(+^-!27uw z@?h^Qu;5U5=Bv;5Cha#5kC>C*#D6y$S|xe02HZrHkFC@BjP8_x9%I;|(s750%cmKh5lNt1|hmMX}AD zots%A&Sf2U-Ojd)kx_twQQ(6BldA2r)(NMb^PVWpV{3_V<+*Wr)^`!b@ZGayS0+wP z%bBElPF*uo)bx?oQAcfS_4aG;;vGC!a+c{PM?|n@-LG8Yb3WrtuQ%78BkIrla+l1W z-hb<=dtuy?+5cMP+ai0W&RzRIsNwSB0$V+HzBkLw@7G*@F`?9aiN)7Pzu)gqzcB6H zva?;H+8MXDtk?1TKRbWl(l%b{ps+BpURmq5yt|vu|2-4=c7w6xd1uXU9A^}sY})Z= z1p~MUeUQjfQ@c0wP4L>xAHupvy$kJkryXxvSEUjE~^{Oru;AD49RIh|4UvlE#)MfQLUcb_J$#txv|ww;4b5)zwRV3#FyGpkygP1xO+&-witjHjI{&LX zIq9fU@1lj(w{GX}civn5eOhURh-v*lo5~+fnt_3VO2_`ohpr5Y%ya9NJe-;RCHCx& zb;d0*$;Wz@etc}ou77P!r1Sjxe=`|RSABie{j+X`uP&!z_{95pFTkad!+};7fzMeo zWyVG!8c&QKpO`vHB}hA};8v32^~JoWPydv)6?f;p7Qb-y_BX|eAB5J$Fxto|rfgdJ zB;~nB`L#PTb;9fZC3&7WYFzQ_uAzuo#@e)`L@+``>a=Hx6(#Ens8ns5CXyZ;8p;A$`@JjbrDP{cfwI7OHdX zJk)gR!sWFtRzmXmoAY9RpU+$P+1$_K$o{gsWg(mWtTmrq^4+*%N#T>{f6lBaxwZeH zdZE#&9gC+rGiw~`wgl~VwLdx8KPKWfyEWUJTt;qOmpe^0Zgi*3SMfzoew< zMNDKzn6RA@2jh;zg)Uq16m)Jw`VDb$)y$X`}e7}zwVhbMNC{$ z6jH(1%yM{nf#KKv`)t8~Z%v(JblzEg-9`I<+uMSIjOSjOr!5t@c*5$~-DY3fWM6Lh z|NErLOP^KId!)B3efqlmj&hq}hjLBrFP?>S7FT!Xz0SWjg_D1|d0egIi{nkXS^wjsaB%OJ6D*7ua&-?Ew({Amxlk9#co9=MkA# zqD8D6?t1pYeKDSzRZbPj-zTk`&~1PI?CGUz+4C;1-ygs5$P}I3dG`77@{{;t@7*(t zJ>MQ{d^C~4`;qZ%Dcz=1*En`Y7#zLH?=_WcAv?cZ$Ct;4zXo-F-Vj%nsb%~1N^nt& zrsl~{2M!$Vp5D4zvhy%k=#hnO`ySbrWlq$6sAHOa?aY!1-Ru9qTAg|8`(>HMc{esV z?l=)Q{m|OHySoCfuDbZ>?yJnIFBh+=-7b7qF$Y}#x)w+;@C22X42=BB4KubYfC|jR zdGC~F@wLRbvRn(E{gp*A{Qt7%6+snKnatN6%H(f-@ha?(>8*;2*5GLyYo}ink&1Ji zoMdRfbdlQCq`FhCA3yh=KK|m-MEkjy=4(rL_VrC$8TRAg^^nRR1{3eqez!0A@j-F3 zb9aY^_M9E}mjC+tdiI**{3rkay8gejch%%D-^q75?0!C}zp`g%LA-JBuF}_8--^?> z9-ez<)>q@u^>MLw7x-nZLUR1>ZqL&5Qgv^Md3|lI`0Qjyv#-ae-aPx})z#IvUMoD= zB&n#!0Iml%G&^iPmHJ}xe*R@AxR$=%aqElf^*p-;*YCx;l|Py^_f}q@>9S+KYo{;Y zr{H2b%cNr46lV7ROHJ|9rD7h%Zs&YzTjNlAJ6UoI~p1`wRRq2()7!g z&|}G4cIwyH*Dp7px10KL^~Og$isIXEFLZV{yjP!fG`aP6l6iF5)4z|p^`E*66p6mn zZ9C=&E+%7K7!235ZIMcjdn(4kA>yQ0FT7H8tw7OU6!rhHaCV16sJm6*iRdIPp%+_+frOTwP%x`X%S*Ub0X|~>>k0+u(A6RcueDZj) z-`f+(f?~1k|7Un+p5%Y?a#6(khwK;j)&34z?l*U(Td&k77kg{d*!^|A-`?F-*I5%T zRmxysmf?5#^5%5?nQY6#)<$j8-L^8Vecj#NN=%Z_#8lwS^i;{| z#qs}q%Ri->`Z=D{(|I=Q&$;zerYx#+4>8TlIy=vFuG7(zrPZhY|NX7(CB(P7wLAPK z*Oc=3`)j*jKdG#oT>dociKr$YU(3{~$CW+_J<@!C&GgjX%Bg!SCT!c}!Zm%B`TY(0 zu8(3L=9s3Q3em1E@-?*!F-$nX@KEkTOpZqABxY&f6WgchMsud$P1!-){Y-1D!RT; zNqKl8Rk8H+q#3SAKpw}d@j!&u;hBAXxUy4hNDj=$A)$@}}u)^BgsSE2XoR-fLQ zqJG;r{oJKXOTAydxoHeKfh=02s4#j?RNajY4-f6!W*oXE!tuyG&61awT%&e;2)8PF zvO%Et@AWkkPS1Q?IE~?SfDX&N%Cr`b+|PU7{I>u9bGwgtGprk~u)trz z;>7%Ywe=cT*MzO}xH!kAeDc3f?^CBtU3zcw3m%8u*-@dZLYA%H_vg&Jt&y9*@!#5$ zy8G$t)(>}gI~IS+yVbUbsn@#e+0tbJ?>;h5seZNLSxQT*QGrAJt6NK(mu9Ki&$r0z z^10mvw~&FUPsriSYX5*-!}af8ShOyjUw@Hv=ahYVF}@2dSL}j*~=Ip$p`K;(mKF{@LaF4iwfkVWe@yMQI$#EPzyZ+xRX%}=j@sw}% zl0}BQHcwccxAfPQoq7CgrN#5VZfNKd4ZS4lZSzKL$&t(Xzn@9Zxudy<#aFsy@vDB5 zsYz?P!}~6syc~UY-K6dP`lWA7JO40wPrS6ggjIV=-p3=;Sf@yoJG*N4Ewq??;LXkA z6;WHWrp%b(;oN4UYSy=T&P|(JOyDA%fw5oV!>c2CCOi5&Hpc|i#qF8?!~3jj?(C@8 zT_uaAFW;A8zNuS${e|uJXH4pAJu*MNw4AZ$^tA1(=HJ=9T{Hc$*P@WmFOBZkBx|{b zt;z_UeN3zN*G=&)>F4csuRq=jNh%<6fq=uA)%E%-be~<7ox8X%=KbCqJz4Iv%br|% ztL?wX@?Pl^J>7rGZSRgPzx|c{@!Q9`EU}DFvej6(Uox28xs=mAd}5*iE4X(AF0<$O zF&M7@I78e?Z~6T!xtj_tF>*WCxSDI0ix&N?_<3Q2*vMrQy--2aBx`5q7|y)%e`Mt{gOcS?v#$q zmovY7c@jBgM$Ub;PHnc8+kDr4Om+|c&)9$4wp47>{-5XSed6ECd+cj=pB$bs!?*Uy zvAav(gnsr}7WGB=WtiR17x&G!M(+63)Y_eK)5zk56^o!aJn;x5#T}mQ07`=#vZYUc z{g@gSqI+rEl#g$u{``I?y`?0XCp9IiY@X@2^rw$sE3?MhDQ#V_^UzDt%a^bGwrTl) z8d7UBFbWj-Gj&w@9^WHSwDY;`+gE|kC!S_K%DXpzH`mTtA-R5QvpY<*x_)@AVdmZt zVRLj{#G4bPU*Eajs!Q5?Q*@P7Xn&NcXp+v$B}+4#*FW8q|DS7Dx%sg-U)S#HT{OXH zs>$`|{jKav|D1U{_x9E%xjQ=^JS*pFi=S}-G*{zq^Rea6S8jcug~sXU7=*xe8v{p! zgCf)a?_Tm%Ym#lJ7e(%QW>9NWSI1+zb#PdQhwZD6SX z#LJb zKfguRy{_(`+ua=z9aAUI_SP={@3d0VQ?2sHPu8IIe#s~F6(Y{}dQYAgm{R2Fy(~BS zd4QkavXf?~rt~jcHn%;CC1KIDYjeBn(-LQ9Xg_^eYxQw=Yl*ShS}84YbH@7m`lwwc zlC5oRK{+`(z0&5}cC@$rgC)vRmL{gZFSg&DeA0i8OnKPMZ=b`WcE42NeRa2IS`h|-9O5L~`j|?yt}oI&-@kcx?!FISUK)Qn|KIqr+OvSyh)`ajBH(Z)yJqTDvCpsi zF2!>!{Bb%$GfQ#$rSvyzQ)cadCj=h4uoo_S{^|R71o{P~ygz5txrjE+9 zpu}nUSnu;6GleIg{+O1%;<+1m;_5E9>a3uxt$p2M+$&5LX`Y=fKDWox#a&Oze(!pQ zH&>o%YKaGi-uBDe_o2)F`L_sxvftk-t%@F)Z$2}-OwMiT>FisHt`hOfcT{Wo#fyJm zv+&32f}EmPXSpViEFr!NqJQ7|GXMG;|C`|zMc&us7Ot=k8Eq7N>R|&_JH}Q2#laKpLZFzWinf6bUyr%)TEq9v*y_>n1 zE!QOT&V*zAvJV4pUtbruI6Ut6YUkVsNs!in07K&>Ur=H8H9Y#vYHP3hhiOmc6Ji*q z&eDJ(Zo}sbwb(1GEiv=X4BbP z)8gdL#8*zJo3lN5YQ>dpD^2U~<#6%vlyqF3v~+dm_j`ZYa({f0_PQ5%k#Fl<>EgyB zvvo!pi$hPRnG_unXuq|uT)$7vzw+clvjRhS;c-%}VaD|zzgB}Pm!*;JdfF{9@%yi~ zopNWfe0%J?;7XbQcgmZmS|t@%yP%~#MPyF{HtUm?`L?q9_@X7p>=MF)wc~NMZbOf zCOW(8v4(-h5wMJR;f<;p75(4xW_wpwF1!5MGBAX{k!&j zH}C4VY_;Y`6i;3(jW6Z<7gU*QTiIOqnJARTPlnyk9~RU862y*x9(+&TX=LazD$9?%&SG$9e78*PAyjr_9Tme|q}axsRD($(gZV zyOVX-)$Mfo zKOf7TH`T;97T)y>S?%Wi_ezh>o=4wG=Iq^}ta(N#{<&Yy($&-XX66`MtdTK&ZyMLN z!(!{=d8eo6OxMu;$vF34Zq>=1I}L(iZfF$pO*r}ee9+NP3;B$HWIYRu+O|(&>%A@i zc^0PeuAY(m{nOQIlXs@hANvnC7dnAMamNGkPv5_nXQaKZzwc6?b0_ISTX0Lv_q^b9 zt18)Yw`W{yaqE|Qbz#TlmI>J+EirtCM~*_1Ou!{hg=eO9?BKS|(n`hY9&0sZHl3L& z|L?XCQl%F|`dW;MU~)!%zP zb1k1{b*^`>hh@FguGOZwmpYF1O6I*R+B{#~ro!R8->gT-)%1cCVNeC~7gB))y044; z|IXo{W1sEw7k%mfJ9nGp-%Z^m{eH)XQ|IsZGchr17%K6+n z`%Uw7)0O(VBr8<E_wAk6*9PQk-6}_$$B3JCE73bb_>>&GKLSLPs$iR3q zrYYvUL^{0BV|@ow_vf4fEKeK1GdiEo?4)--K6&}M3$ZORYgcVwoOad4%Ehp{*Td_+ zVfWFnaP{P?7F+NODO5QMX4-Gp!Od4lbO6SD@1bg;a9ewqP*5#9z0&^u#i4xTxjTC@ zxDjYD!p?uZ z(3$<^RsFQc*!xpOuWnoU_5A+*zGr83OWbVybhh01#igebi*sfTE)pko0!x$d$;6DSC!UH3wj>_J}Vc;gw zeujy40UQf@rf!*HGV$%fJ(I7lmoMM?`roNjrxuo4ufP21?8Ye*Gvjp9Rx*oa|NQwo zYjtXBYOvd^NwX&2uW>$-+No&A4lC0(%!AeL*Y10(?o?}uQLX&?cE)aNj-67Wc}}_6 z<=1uHQYEQ}s_xx-M4qE$Ghnl-ob~ z_jGl1?@wQ%e)-Rn|D}qOVZY+FI`r7FWRYjSuFAa^4=(NYw*B?{ik+En)z4px zzdSv&)-3k%s#96Fugv=KrsCD@?c1F%|Nmb7e{nm%?~)cy9<}?8$|to=&MdPl5`Lsv zeU|CdsQ|MjU-Z9=ZT$1!?pMFZ-aN~z%U1S@>&3WuPhYzsGiC)m#2J`&u?T#Y+An_v z+;Cr`JYAsZsaWHLY&CUCRCI_#{W&4WcF*R88 z{bq^v)ElP+il*LJx;_8VJB24wx6({n*;;3oJU(^y^x~KX?=`;g$b-9kXH)YZO;g?AxbUSx5@-LE zOz~Np;a&OIcH*>;Gt_h!-|D($wslv@OBa3r+KYKUbB;ZI|Nqy8KVKCeKKcFQa#;7y zPnRxhRv(pFG(~0e+kL-2rF8X~z5SJz86;o#!%)_$=17of4IeD!GBBxunge}q;KtP7 zKds8)3pm}^g*-el^{tKjx*O3aO{%Z5S`{BXvXEW-|F%6xA3kCDIOoaZT&tzYMUw=I zI=??b?hEC>0@Lz$-{&*m6rOxKQ>wcua%Jp^(5-Kjuk0?Y_tkRwxYVLRQ&aTkck_40 zFHBp!`mE8byI&)@xcE#0vcXJ9Z!W{(HOL<(09g&wjg}a>4tF zw8$iVj??08Ppum@|Hef8v`tl06}fq9Q6i#n((q&2x9{GTvTq`*T_WPo-Elg7UH-DP zUi|;V?T1(T^>Uf{D%&d0{?+@pZ_{R3@9?DH<~D8_Q%CG$rs_ag^x_m z&f0w7)7M7FCzrSG_t+e9Hs|i08QoJhS1&%{J}+nES;oJ=1HP}5)xBmMn)qbJ#wqji ztW0;`<$de~b4a6*GpL`m6jCU}D?Z`c5`5z6^VhD$_Ain?{`2!VwZK(+-Gyn)+g)PW zFUfQ{A8K@DeDXSag4@NA=bD`-XB|F)9I`3!kp0>A`NA`WC!a2~>aNOM8GGXD_LmM_ zTESOWNQdj$vvmK@wf!a?yTAOV%AyUIp012;pXhdX#|~aw_H{Li(?y~?#kje5R#+RD zo40>kGe?cjVy4|((VHujL$fXg#-C7KceV7-uKI5VcW>@rxMG^vTgciNP;@U!iwF#LZcR5Ho?&|AF;a6Wh5nVJnEAYtm%EEFD{bzgrtP5{)_UYPnqqjSD=NnDK zjT^uGdYyl>SaTg@Rt-D~WXsf1$(zq%dTh@rjlX|tT6c#oxVYOw*EH6mD0TLp!_CaK z8Q1EqX8y5JSD*gxM)l;nzkiKVQ>=(MJLUjKBt=9SXNUT1xlKE0hj zgEe$}TK1~=?R&TJilrA`^j(>;R(krgkGH%1-o|+G=fxY|T))5If0o4y*R>43v*!gK zXVg)*?$*9#X+))hzOSj}Y7n##Yl^764s`)}xMTy`dM({!;lHZHoeT`srh^KN)1 zwAbp*G1EUsBSq#fxaZ4bnwRA}%cAkumzSy5`47{+zW;8wu!qMvTzkFNRn70`d_SEk zy72MT_4#|EOBdYPd+casef4Wmt@wR&&L+q2EHXViH@$W8jI+9k-cREsHwMG?54%oQ(H>kke|dE0cQXO3E6%)-*+mwZ=h97&4d3exGSKe44N&Z^01k@oRz zm(G4>Kl3em^Kk>Nl_7f%O!Yqg*PH8*%k1rCYnQf*f4$7{@Eejt{FMw!Ys9O5eSD@j z^U|HCzh5qA-5q;r`rf%K3WHaNuAcVg-0k|Um0q*W@|WMg_BXL$?)T(ojqejWF3R88 zywf*Xydre9Yuv=p-maauw&b}UZs*&ybH4fgns&Wdvs#10&)5nXVNGX;PPK*^;q^bS zN_^H*{_I@>X<~A7u<% z7I@{YhPH9H(FDCair)}}Q3tF*%?Qv?Qe^r6DPN)lil%k>d+HUU%z!$zGd%S z_lRX*$%9M2jVI2U+QN!0zb!Q`VIopWfZwv`aTztICzzFg#?7Kyj|wihs|fgEcn=xn|FrSo-MQ(Tksh z<2LQGgD$=U6)+8|OdXY9IaiuKdm8xb*RP<24YeypPq(sPFn_;g@?>AHvrCrNAG+SfnrF=edYkCfzP4UwUrIdVXGvv7-8S&|B*{kUqqnX(!tMpND(Iy7P2cN!ewCh#sw~p>HRMu^dU};0@Q>{~J zm~q_zv?^d~`GViySQV%LUKhKuCuXhFx_@WqFX2iIWXp@$xu)xse{aRFSAteWb?v@) znwq?VGhP;nNJaHEIiKd({pym@(S;&~nwsLD_j50uRv_WAWXlrvDRU&;SMonT!d$e- z_wUs=#%)cfLa&`!ykYZyyNf%HPTg-i_S)d*`OGt4Q+K8+rerqo2-+79YLW zvE1A~!c*s2QTw86zH2{xFqmcdxBAnkZF@Su{BHBz^6njVHLEt5_TuSaQ@GW`rO1S!<}@fA;wK z=}k>F=hTW1N+{jea6$SIeK5X zQCGryw?q3@uaf)1@SJ;7PnqW|fBb8z{)S-KNc5Mxlz!19?=+9)0?DEv0?KvL{cUb%}J%oHBE!>N%C@`njgL zi}_#$Cn|yPYw6;yY@mHxzV*Pc${rhZJruXZ)9iKF5lGEhndt6qo?6cIk zQF{525~8K(%3!$u*hej8=h~I$Yg;?C3~uaD4zG&ZB~WBJP4D83-gBA)e_g!X?I&Kk zc$`g9%>H%3s^dI6PEK3#|Nns$XzDr;3tDn>%Ax2=5kZ)Ny;PSdIzNwQ%-xo29elj+uBP{#oZl~(>mOB{wX3CKPv*@nFBgaGuS?bnR&#p8TXp$x zJO7I}H!qj`_z-89S9(8x)y_r(0cenHXmZ%uAu!8k6LV>9{OmujRl?a`QB`VxH~!T* z8?j@yoZ8C#;1jbfS45sT`dHqqgo9T!zV-CR$ICOm>9@{VbEad*sh0NO<$iBh#Lf;A z(YSQ%Ms%O7wdd{fHw#Z2Zfx^qX`gVy-FeE41>Ym@-?Lp2em;-wYyBL%$^U*l_OEUa zT5|p4vAAxr+!cOv+k!qE^E<-H`LX2XB}=PTe-Ci$W_mG+&;3e^=?;KAD^9_cf)p6%`knRDOE>X>lue`o&)9 zaNboPf4_b{zdqEaoaN%d=IV^s*Lb%rDD%AACAv6ePyE(b$|5o{I%YMOUp(`j_q%Ra zo$WEzWCwLYw$5|4litd?vu00CM$UB2BYZKpOuB;J zOwoTOv_I4(;PkeC8gZXizfWy=x2W$8rZIi&ki<5+x`h3_A|#|L9~?R>Oc zDLy~js^ZVbvrmFa>r`qD!}r_u2cAE^E9-UK zzM9s5zn)q9$xhxZ#m&Vf_GsruCBC&8TTZsLus>RGL`Jav)%l6q(LzO`t3qbF^$KOa zc8%OyWjNQq{#NASGB4}Ez|hPK3j~XdPe<%5ddjpm=BM`4j$R+wXj?%#Q%B|1%~ffw zF@An)B@|?KL~O|SK6&!&LZ8A0RrTAOAI(oYE4TFB-QTC0Hy=Co?rwDFelGFsmY9CK zTaCL)UTV%0-JE%>Cv(c2IT_ral-A$gQ_nf0HthUPyKjv#j2`^fAW9R(Nvl|}ye!jHGHT$E(U4OsFhgywG{`^pU zIBTkw`BbZt7j6p|E?p{pphq(PWUw=M;g!G4$HP|nhtACTX{st#uD_I9F9 z>-ITan5q|Kzwg_x*-F!PM~56PT5-3LxjpFZE#8zjl`k&HRc18R_w}vw%e_@HX?Fb^ zn*)3-t=+1M*AFxvcDemk)6T9h?d-2(3k$7&C;f|_Vers3$$j0IFD5%HkA6;3Z*}XP z)p=OeH)VP|-`mBy(bueZS8oAtm;!kqpoQg%%;#C+MV9lTCbnAsWBm6>yCME(RP2ok zZEfY|O>^FGqys@FM=$*{u;xpC%|JibJ zYbz)JJ#pgHri-Dg#ZG>|i0Gugb9U$iC5ZW^+UF)Zod})tGy@cYYPG4qq?$_5FHJ!z1fr z3=P}*QdZ3pU}J`jbS;Qt%DQ*uQma|T1>q~3LbYevEe<%9qxtBRfM3in%}qBOU(bB# zzq94{y1TzKUw(3uHc?DGGCM6!^VjnC>|fqHxAVy@*jxR5XG+etvP0~uH@05$w$abI z_h+}y^R>~hu4d~z3gEq7`FYvpx3|r|+L^0A>FUr>e_WpT`}_Uy&X8939ND;u*YYne zT5Iv*qPyIZh#dvXJXRMwuirn<_ILM|=WA0|9hI;9aVDkeq>`+P6ud9Cp}S#La-7&d zmZ@AuR{DOaGp0_>y*}rsQvSuV1`q9b%9k{61x4(cs(Fd$)b|r|5mjHSnr4|~I(m9` zJ}NkP-DqEM*K~^shGlP3w8Gald1%+o3tJPh!2Q6a39BIr-Q6w9V=Jz zNSVyZy1GjJ`M=NS?+2x&wUt%;IahOL#`B|hv`>jl{`~xWz~u{uV$d3zfsva<;mIN0 zByL8IojD6zcPWY2YI-)tPP-CNWiIV8F?G>azObD+d#CC*oVqGn`f^FMkC*QPiHB!O zzaES9^45>Lo$~)us>Yru<|M)C@h=OUzw5T0`5X|W^X&f_{+FG{zXu%p=X-P;&r+|} z3sW@nPyF-koXW;4r6y zFRRs%|HCbQFCkg+);!zj%vocg7`TV@SFYdISX5DY5_~_N0 zjdOjLzc^L&=}P3RpPz01>N&RvN36S1;q80v-@c+0SHb;ni=JM{dF5?saG>y0czmtG z~g)LI!EA>C63 z4i6@QqK9r9S{Yhmwq0Q}gMJ7QahXQOZ@9il3blFUhpKzM~}bmB7*^ zs)0_AY^!EeOrJFA@zHP@Rdvy`nsXL>;1ZFD>tphozIZ`Lmx#u`nkMHbGfeZ6x_(bf z`*TWp#wX)?y}7$gE-#sqE&lQ!TdlZG_`O9rg|=yDQf@vyGxPF`gUrr(vAe%53tM~Z z;@R2e83&u@e`!niJ8{&HA@%gM>EABo2(R6CX_>G4t1B-Jt9}^FtNWEX>*B+WtYueM z^> zf5qZ;1&MZZ4o&=>5GXsJ@64%FORB%W>wL|3d1G?>l{VhT@PWt;%?-26xAyohckiE9 z^6-+VlHwyJJKK57-XFQT?(Jfek`oTr9u{>cZx)NcJU&0|wYdskFo)?Bk>b#`Q8UZl z-gs8w?s}u?k=N8Yb2MU>+nL|G{Nm#I;Gea$O^mY#Yv^VvR+^_$&}y*%di_0`sum7lLI%9|o`x-fpv%u{_FGT+7h z-Uhd9XPU(Z9meZdTJUX#xrIu^zWv%Ums+*Mw)w8){e0qlJjaede_g7tJr6u1m^Amy z7oSsw2mYR(n>S-+@cn7hb7ejkz6sxPWkulhc{N2Xf4)wS|Makp>9}68lV0riTb9N9 z#NP+LU%_`;d;K5hlpPv0AnH$lu?EhhocF zH?EdUKl5Nl#o;znqknHNE}rk>FDYFexonD$@6~#{+^k~QT7a;}W;3n#|6Uild7Z@) z8NJKfjPJMe%b(iz?fw0gvz-5}inih5fOd^_1R5rAZ|~3rjZL z)YnNl^-527TcOGl`)T(x@7YNc>!<&(-n%Pm;&eBTX%lDq&5X=^RIQbon$E?YyzQi) zFu(51TP5w6es)Wr7EjoC;?!~b2{lK#YvuPVe41v@-o4)8lhFTb;#r!R!lDl)|L=Z~ zZppsy{-@UHsKQx~%+%~o)l|%Xr}uN;jdx!6UPzc`O?p%R>x=%;lYd#7H*UDmDgWo) zy}iEs|9on`_k3AP%+~Dd%Nv>7PwqN)>7dB%mQt&*IRa}6pJ?q7T*k5UN28_Is#P@~ zo{ICtl)b;FRk?KO(#-nw9Obn|Pcx*9Qnu7gFbnNjx;uo~x`z=O5Do{-n6mC)(XyG{ z(7=#&XC3$5ou!laaP9o@?cLS6zdF`G(h=8-TPC^rS?3SC%?T1o%}PopE$3wJC?{=h zx}tj2(l5And*0nftMYf6WXlw94y3@riOHBB>7!jrIUQhJR0xVf=xHnjQTNk1k z^n3S{Cn^s;%zX2mCs=1+U1eMP_SR{gHr;45j(62v(xSg$b>nvB1>a^|cehAqWo4Br zI4j_!=U1HJ`|;z|C4nYt9LA-!>k96j5-QZLKRNw^>XJR5PTfykb8Jzy-HWIlHlI9n zKjxK8`LlK1jL!eLekV-J-iRa}oV;;LPnM%~-5>8q4aJtXb{2Pge9x;m;Zpd-%in)- z{=T0P);X>xMCIkx`8hr_@}?bR=l^lQv6;;`wdOQ?(@(iQ6(4&n{w%0(m^Jr+TVG8W z$AKdYWrSP#?Q~)+POsqb(d9AZgVvt`+Ke1Kuk12F@`lx5AMfJ)0%?G@8`aQ2&8oPFJSlxZr zrnP@wPchW|`($_fNi*(vWxu4%y7k&0PL)ds&pG<(_=L$*UAL!++pO97Yni5&;`I{~ zCm%T$oLXs=adJ|8jIHkKUypm`{ca11i0Ite#$%ps@sxXc-ASSBBeNYeH9c>Yi7JZk zPCq->dhU;hyP~(-9qL@Y_KrdF$EcV)u@6NqOqQ$N(){C(-Pu`Rx8Bg?&rm z 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

9tz)+pDYXP4n-yotyi6x|rUd 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≧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.yml and set -# `integration: ` on the client. -# 3. If the app is configured elsewhere (NixOS, manual UI), omit -# `integration`; the oidc-client- K8s Secret still holds the creds. -# Requires an admin API key in secrets/pocket-id.yaml. -- name: Bootstrap Pocket ID - hosts: localhost - connection: local - gather_facts: false - - vars: - pocket_id_url: https://id.cute.haus - k8s_namespace: default - oidc_client_list_limit: 200 - - vars_files: - - vars/pocket-id.yml - - vars/oidc-clients.yml - - tasks: - - name: Load Pocket ID secrets from sops - community.sops.load_vars: - file: "{{ playbook_dir }}/../../secrets/pocket-id.yaml" - name: pocket_id_secrets - - - name: Reconcile application configuration (incl. SMTP) - ansible.builtin.include_tasks: tasks/ensure-app-config.yml - - - name: List existing OIDC clients - ansible.builtin.uri: - url: "{{ pocket_id_url }}/api/oidc/clients?pagination[limit]={{ oidc_client_list_limit }}" - headers: - X-API-KEY: "{{ pocket_id_secrets.admin_api_key }}" - return_content: true - register: existing_clients_response - check_mode: false - - - name: Index existing clients by name - ansible.builtin.set_fact: - existing_clients_by_name: >- - {{ - dict( - (existing_clients_response.json.data | default([])) - | map(attribute='name') - | zip(existing_clients_response.json.data | default([])) - ) - }} - - - name: Reconcile each declared client - ansible.builtin.include_tasks: tasks/ensure-oidc-client.yml - loop: "{{ oidc_clients }}" - loop_control: - loop_var: client_spec - label: "{{ client_spec.slug }}" - - - name: Wire each client into its target app - ansible.builtin.include_tasks: "tasks/integrations/{{ client_spec.integration }}.yml" - loop: "{{ oidc_clients | selectattr('integration', 'defined') }}" - loop_control: - loop_var: client_spec - label: "{{ client_spec.integration }}" - vars: - oidc_client_credentials: "{{ oidc_client_credentials_by_slug[client_spec.slug] }}" diff --git a/ansible/playbooks/reboot.yml b/ansible/playbooks/reboot.yml deleted file mode 100644 index 139b8485..00000000 --- a/ansible/playbooks/reboot.yml +++ /dev/null @@ -1,64 +0,0 @@ -- hosts: cutehaus - remote_user: root - serial: 1 - any_errors_fatal: true - - vars: - drain_timeout: 600 - ready_timeout: 600 - systemctl_path: /run/current-system/sw/bin/systemctl - - tasks: - - name: Cordon node - ansible.builtin.command: kubectl cordon {{ inventory_hostname }} - delegate_to: localhost - changed_when: true - - - block: - # --disable-eviction bypasses PDBs (Longhorn instance-manager blocks otherwise). - - name: Drain node - ansible.builtin.command: >- - kubectl drain {{ inventory_hostname }} - --ignore-daemonsets - --delete-emptydir-data - --force - --disable-eviction - --timeout={{ drain_timeout }}s - delegate_to: localhost - changed_when: true - - - name: Reboot host - ansible.builtin.reboot: - reboot_command: "{{ systemctl_path }} reboot" - - - name: Wait for node to be Ready - ansible.builtin.command: >- - kubectl wait --for=condition=Ready node/{{ inventory_hostname }} - --timeout={{ ready_timeout }}s - delegate_to: localhost - changed_when: false - - - name: Mark node as ready - ansible.builtin.set_fact: - node_ready: true - - - name: Uncordon node - ansible.builtin.command: kubectl uncordon {{ inventory_hostname }} - delegate_to: localhost - changed_when: true - - rescue: - # Restore scheduling capacity so the cluster isn't left with a cordoned - # node. The operator should still verify node health before re-running. - # Only uncordon if the block failed before the normal uncordon ran. - - name: Uncordon node on failure - when: not (node_ready | default(false)) - ansible.builtin.command: kubectl uncordon {{ inventory_hostname }} - delegate_to: localhost - changed_when: true - - - name: Abort reboot sequence - ansible.builtin.fail: - msg: >- - Reboot sequence failed for {{ inventory_hostname }}. Node has - been uncordoned; verify its health before re-running. diff --git a/ansible/playbooks/tasks/ensure-app-config.yml b/ansible/playbooks/tasks/ensure-app-config.yml deleted file mode 100644 index 420ffa84..00000000 --- a/ansible/playbooks/tasks/ensure-app-config.yml +++ /dev/null @@ -1,36 +0,0 @@ ---- -- name: Get current application configuration - ansible.builtin.uri: - url: "{{ pocket_id_url }}/api/application-configuration/all" - headers: - X-API-KEY: "{{ pocket_id_secrets.admin_api_key }}" - return_content: true - register: app_config_response - check_mode: false - -- name: Flatten current config (list → dict) - ansible.builtin.set_fact: - pocket_id_current_config: >- - {{ - dict( - app_config_response.json - | map(attribute='key') - | zip(app_config_response.json | map(attribute='value')) - ) - }} - -- name: Apply application configuration - ansible.builtin.uri: - url: "{{ pocket_id_url }}/api/application-configuration" - method: PUT - headers: - X-API-KEY: "{{ pocket_id_secrets.admin_api_key }}" - body_format: json - body: >- - {{ - pocket_id_current_config - | combine(pocket_id_app_config) - | combine({'smtpPassword': pocket_id_secrets.smtp_password}) - }} - status_code: [200, 204] - no_log: true diff --git a/ansible/playbooks/tasks/ensure-oidc-client.yml b/ansible/playbooks/tasks/ensure-oidc-client.yml deleted file mode 100644 index c12c6e60..00000000 --- a/ansible/playbooks/tasks/ensure-oidc-client.yml +++ /dev/null @@ -1,74 +0,0 @@ ---- -# Orchestrate the lifecycle of one OIDC client: -# 1. Resolve the current K8s + Pocket ID state. -# 2. Create the client if it does not exist. -# 3. Sync any configuration drift. -# 4. Ensure a K8s Secret exists with valid credentials. -# 5. Upload the app logo if provided. - -# ----------------------------------------------------------------------------- -# Phase 1: Resolve current state -# ----------------------------------------------------------------------------- -- name: "[{{ client_spec.slug }}] Look up K8s Secret" - kubernetes.core.k8s_info: - api_version: v1 - kind: Secret - namespace: "{{ k8s_namespace }}" - name: "oidc-client-{{ client_spec.slug }}" - register: kubernetes_secret_lookup - -- name: "[{{ client_spec.slug }}] Initialize state facts" - ansible.builtin.set_fact: - oidc_client_record: "{{ existing_clients_by_name[client_spec.name] | default(none) }}" - kubernetes_secret_exists: "{{ (kubernetes_secret_lookup.resources | length) > 0 }}" - -- name: "[{{ client_spec.slug }}] Delete stale K8s Secret" - when: - - oidc_client_record is none - - kubernetes_secret_exists - kubernetes.core.k8s: - state: absent - api_version: v1 - kind: Secret - namespace: "{{ k8s_namespace }}" - name: "oidc-client-{{ client_spec.slug }}" - -# ----------------------------------------------------------------------------- -# Phase 2: Build payloads and create the client if missing -# ----------------------------------------------------------------------------- -- name: "[{{ client_spec.slug }}] Build desired/current client payloads" - ansible.builtin.include_tasks: oidc/build-client-payloads.yml - -- name: "[{{ client_spec.slug }}] Create client if missing" - ansible.builtin.include_tasks: oidc/create-client.yml - -# ----------------------------------------------------------------------------- -# Phase 3: Sync configuration drift for existing clients -# ----------------------------------------------------------------------------- -- name: "[{{ client_spec.slug }}] Sync client configuration" - when: - - existing_clients_by_name[client_spec.name] is defined - - (desired_oidc_client | to_json) != (current_oidc_client | default({}) | to_json) - ansible.builtin.uri: - url: "{{ pocket_id_url }}/api/oidc/clients/{{ oidc_client_record.id }}" - method: PUT - headers: - X-API-KEY: "{{ pocket_id_secrets.admin_api_key }}" - body_format: json - body: "{{ desired_oidc_client }}" - status_code: [200, 204] - -# ----------------------------------------------------------------------------- -# Phase 4: Ensure credentials are available in K8s -# ----------------------------------------------------------------------------- -- name: "[{{ client_spec.slug }}] Ensure credentials Secret" - ansible.builtin.include_tasks: oidc/ensure-credentials-secret.yml - -# ----------------------------------------------------------------------------- -# Phase 5: Upload app logo -# ----------------------------------------------------------------------------- -- name: "[{{ client_spec.slug }}] Upload logo" - when: - - client_spec.logoUrl is defined - - not (oidc_client_record.hasLogo | default(false)) - ansible.builtin.include_tasks: oidc/upload-logo.yml diff --git a/ansible/playbooks/tasks/integrations/_write-secret-and-restart.yml b/ansible/playbooks/tasks/integrations/_write-secret-and-restart.yml deleted file mode 100644 index dfc2a7dd..00000000 --- a/ansible/playbooks/tasks/integrations/_write-secret-and-restart.yml +++ /dev/null @@ -1,43 +0,0 @@ ---- -# Shared helper: write/update an SSO env Secret and rollout-restart the -# Deployment if it changed. Caller passes: -# secret_name — K8s Secret name -# secret_data — dict of env var names → values -# deployment_name — Deployment to restart on change -- name: "[{{ client_spec.slug }}] Resolve target namespace" - ansible.builtin.set_fact: - sso_target_namespace: "{{ client_spec.namespace | default(k8s_namespace) }}" - -- name: "[{{ client_spec.slug }}] Write SSO env Secret" - kubernetes.core.k8s: - state: present - definition: - apiVersion: v1 - kind: Secret - metadata: - name: "{{ secret_name }}" - namespace: "{{ sso_target_namespace }}" - labels: - app.kubernetes.io/managed-by: ansible-oidc-bootstrap - app.kubernetes.io/component: sso-env - annotations: - helm.sh/resource-policy: keep - type: Opaque - stringData: "{{ secret_data }}" - no_log: true - register: sso_secret - -- name: "[{{ client_spec.slug }}] Rollout restart to pick up new env" - when: sso_secret.changed - kubernetes.core.k8s: - state: patched - api_version: apps/v1 - kind: Deployment - namespace: "{{ sso_target_namespace }}" - name: "{{ deployment_name }}" - definition: - spec: - template: - metadata: - annotations: - kubectl.kubernetes.io/restartedAt: "{{ lookup('pipe', 'date -u +%FT%TZ') }}" diff --git a/ansible/playbooks/tasks/integrations/forgejo.yml b/ansible/playbooks/tasks/integrations/forgejo.yml deleted file mode 100644 index 68d903b3..00000000 --- a/ansible/playbooks/tasks/integrations/forgejo.yml +++ /dev/null @@ -1,88 +0,0 @@ ---- -# `cute.haus` is both the auth source name (button label) and the URL slug -# in the Pocket ID callback (/user/oauth2/cute.haus/callback) — keep aligned. -- name: "[forgejo] Find a running pod" - kubernetes.core.k8s_info: - api_version: v1 - kind: Pod - namespace: "{{ k8s_namespace }}" - label_selectors: - - app=forgejo - field_selectors: - - status.phase=Running - register: forgejo_pods - -- name: "[forgejo] Fail if no pod is running" - ansible.builtin.fail: - msg: "No running forgejo pod in namespace {{ k8s_namespace }}" - when: (forgejo_pods.resources | length) == 0 - -- name: "[forgejo] Pick a pod" - ansible.builtin.set_fact: - forgejo_pod: >- - {{ (forgejo_pods.resources | map(attribute='metadata') | map(attribute='name') | list | sort)[0] }} - -- name: "[forgejo] List auth sources" - kubernetes.core.k8s_exec: - namespace: "{{ k8s_namespace }}" - pod: "{{ forgejo_pod }}" - command: su -s /bin/sh git -c "forgejo admin auth list" - register: forgejo_auth_list - -# Output is a whitespace-aligned table: ` `. -# cute.haus only appears in the name column; the ID is that row's first token. -- name: "[forgejo] Find cute.haus auth source rows" - ansible.builtin.set_fact: - forgejo_matching_rows: >- - {{ forgejo_auth_list.stdout_lines | select('search', '^\s*\d+\s+cute\.haus\s') | list }} - -- name: "[forgejo] Fail on duplicate cute.haus auth sources" - when: (forgejo_matching_rows | length) > 1 - ansible.builtin.fail: - msg: >- - Found {{ forgejo_matching_rows | length }} auth sources named cute.haus - in forgejo — expected at most one. Resolve duplicates manually. - -- name: "[forgejo] Extract cute.haus auth source ID (empty if absent)" - ansible.builtin.set_fact: - forgejo_source_id: >- - {{ - (forgejo_matching_rows | first | default('')).split() - | first | default('') - }} - -# Explicit empty strings clear fields that update-oauth's cli.IsSet semantics -# would otherwise leave untouched on re-runs. -- name: "[forgejo] Build shared OAuth flags" - ansible.builtin.set_fact: - forgejo_oauth_flags: >- - --name 'cute.haus' - --provider 'openidConnect' - --key '{{ oidc_client_credentials.client_id }}' - --secret '{{ oidc_client_credentials.client_secret }}' - --auto-discover-url '{{ pocket_id_url }}/.well-known/openid-configuration' - --scopes 'openid profile email' - --group-claim-name '' - --admin-group '' - --required-claim-name '' - --required-claim-value '' - --restricted-group '' - no_log: true - -- name: "[forgejo] Add auth source" - when: forgejo_source_id == '' - kubernetes.core.k8s_exec: - namespace: "{{ k8s_namespace }}" - pod: "{{ forgejo_pod }}" - command: >- - su -s /bin/sh git -c "forgejo admin auth add-oauth {{ forgejo_oauth_flags }}" - no_log: true - -- name: "[forgejo] Update auth source" - when: forgejo_source_id != '' - kubernetes.core.k8s_exec: - namespace: "{{ k8s_namespace }}" - pod: "{{ forgejo_pod }}" - command: >- - su -s /bin/sh git -c "forgejo admin auth update-oauth --id {{ forgejo_source_id }} {{ forgejo_oauth_flags }}" - no_log: true diff --git a/ansible/playbooks/tasks/integrations/forward-auth.yml b/ansible/playbooks/tasks/integrations/forward-auth.yml deleted file mode 100644 index 287004ee..00000000 --- a/ansible/playbooks/tasks/integrations/forward-auth.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -- ansible.builtin.include_tasks: _write-secret-and-restart.yml - vars: - secret_name: "{{ client_spec.slug }}-oidc-env" - secret_data: - PROVIDERS_OIDC_CLIENT_ID: "{{ oidc_client_credentials.client_id }}" - PROVIDERS_OIDC_CLIENT_SECRET: "{{ oidc_client_credentials.client_secret }}" - deployment_name: "{{ client_spec.slug }}" diff --git a/ansible/playbooks/tasks/integrations/nextcloud.yml b/ansible/playbooks/tasks/integrations/nextcloud.yml deleted file mode 100644 index 1ea1a723..00000000 --- a/ansible/playbooks/tasks/integrations/nextcloud.yml +++ /dev/null @@ -1,25 +0,0 @@ ---- -- name: "[{{ client_spec.slug }}] Configure local Nextcloud OIDC" - ansible.builtin.raw: | - docker exec --user=33:33 \ - -e OIDC_CLIENT_ID={{ oidc_client_credentials.client_id | quote }} \ - -e OIDC_CLIENT_SECRET={{ oidc_client_credentials.client_secret | quote }} \ - nextcloud /bin/sh -ec ' - occ() { - php /var/www/html/occ "$@" - } - - occ app:install user_oidc || true - occ app:enable user_oidc - occ user_oidc:provider cute.haus \ - --clientid="$OIDC_CLIENT_ID" \ - --clientsecret="$OIDC_CLIENT_SECRET" \ - --discoveryuri="https://id.cute.haus/.well-known/openid-configuration" \ - --scope="openid email profile" \ - --mapping-uid=preferred_username \ - --mapping-email=email \ - --mapping-display-name=name \ - --unique-uid=0 - ' - delegate_to: jubilife - no_log: true diff --git a/ansible/playbooks/tasks/integrations/paperless.yml b/ansible/playbooks/tasks/integrations/paperless.yml deleted file mode 100644 index 509ddd07..00000000 --- a/ansible/playbooks/tasks/integrations/paperless.yml +++ /dev/null @@ -1,21 +0,0 @@ ---- -- name: "[paperless] Build PAPERLESS_SOCIALACCOUNT_PROVIDERS JSON" - ansible.builtin.set_fact: - paperless_social_providers: - openid_connect: - APPS: - - provider_id: pocket-id - name: cute.haus - client_id: "{{ oidc_client_credentials.client_id }}" - secret: "{{ oidc_client_credentials.client_secret }}" - settings: - server_url: "{{ pocket_id_url }}/.well-known/openid-configuration" - OAUTH_PKCE_ENABLED: true - no_log: true - -- ansible.builtin.include_tasks: _write-secret-and-restart.yml - vars: - secret_name: paperless-sso-env - secret_data: - PAPERLESS_SOCIALACCOUNT_PROVIDERS: "{{ paperless_social_providers | to_json }}" - deployment_name: paperless diff --git a/ansible/playbooks/tasks/oidc/build-client-payloads.yml b/ansible/playbooks/tasks/oidc/build-client-payloads.yml deleted file mode 100644 index 24984965..00000000 --- a/ansible/playbooks/tasks/oidc/build-client-payloads.yml +++ /dev/null @@ -1,35 +0,0 @@ ---- -# Central mapping between our client spec and Pocket ID's client API shape. -# When adding/removing client fields, update only this file. -- name: "[{{ client_spec.slug }}] Build desired OIDC client payload" - ansible.builtin.set_fact: - desired_oidc_client: - name: "{{ client_spec.name }}" - callbackURLs: "{{ client_spec.callbackURLs }}" - logoutCallbackURLs: "{{ client_spec.logoutCallbackURLs | default([]) }}" - isPublic: "{{ client_spec.isPublic | default(false) }}" - pkceEnabled: "{{ client_spec.pkceEnabled | default(true) }}" - requiresReauthentication: "{{ client_spec.requiresReauthentication | default(false) }}" - -- name: "[{{ client_spec.slug }}] Add optional launchURL to desired payload" - when: (client_spec.launchURL | default('')) | length > 0 - ansible.builtin.set_fact: - desired_oidc_client: "{{ desired_oidc_client | combine({'launchURL': client_spec.launchURL}) }}" - -- name: "[{{ client_spec.slug }}] Build current OIDC client payload from API" - when: existing_clients_by_name[client_spec.name] is defined - ansible.builtin.set_fact: - current_oidc_client: - name: "{{ oidc_client_record.name }}" - callbackURLs: "{{ oidc_client_record.callbackURLs }}" - logoutCallbackURLs: "{{ oidc_client_record.logoutCallbackURLs | default([]) }}" - isPublic: "{{ oidc_client_record.isPublic | default(false) }}" - pkceEnabled: "{{ oidc_client_record.pkceEnabled | default(true) }}" - requiresReauthentication: "{{ oidc_client_record.requiresReauthentication | default(false) }}" - -- name: "[{{ client_spec.slug }}] Add optional launchURL to current payload" - when: - - existing_clients_by_name[client_spec.name] is defined - - (client_spec.launchURL | default('')) | length > 0 - ansible.builtin.set_fact: - current_oidc_client: "{{ current_oidc_client | combine({'launchURL': oidc_client_record.launchURL | default('')}) }}" diff --git a/ansible/playbooks/tasks/oidc/create-client.yml b/ansible/playbooks/tasks/oidc/create-client.yml deleted file mode 100644 index 7bcf4d20..00000000 --- a/ansible/playbooks/tasks/oidc/create-client.yml +++ /dev/null @@ -1,17 +0,0 @@ ---- -- name: "[{{ client_spec.slug }}] Create client in Pocket ID" - when: oidc_client_record is none - ansible.builtin.uri: - url: "{{ pocket_id_url }}/api/oidc/clients" - method: POST - headers: - X-API-KEY: "{{ pocket_id_secrets.admin_api_key }}" - body_format: json - body: "{{ desired_oidc_client }}" - status_code: [200, 201] - register: created_oidc_client - -- name: "[{{ client_spec.slug }}] Adopt newly created client" - when: created_oidc_client is changed - ansible.builtin.set_fact: - oidc_client_record: "{{ created_oidc_client.json }}" diff --git a/ansible/playbooks/tasks/oidc/ensure-credentials-secret.yml b/ansible/playbooks/tasks/oidc/ensure-credentials-secret.yml deleted file mode 100644 index 7a182bf7..00000000 --- a/ansible/playbooks/tasks/oidc/ensure-credentials-secret.yml +++ /dev/null @@ -1,68 +0,0 @@ ---- -# The K8s Secret may be missing even when the client exists (manual cleanup, -# restore from backup, etc.). Generate a fresh secret and write it back. -- name: "[{{ client_spec.slug }}] Warn about rotating a missing Secret" - when: - - not kubernetes_secret_exists - - existing_clients_by_name[client_spec.name] is defined - ansible.builtin.debug: - msg: >- - Client existed in Pocket ID but K8s Secret was missing — rotating - client_secret. Apps using the old value will break until they pick - up the new K8s Secret. - -- name: "[{{ client_spec.slug }}] Generate client_secret" - when: not kubernetes_secret_exists - ansible.builtin.uri: - url: "{{ pocket_id_url }}/api/oidc/clients/{{ oidc_client_record.id }}/secret" - method: POST - headers: - X-API-KEY: "{{ pocket_id_secrets.admin_api_key }}" - status_code: [200, 201] - register: secret_rotation_response - no_log: true - -- name: "[{{ client_spec.slug }}] Write K8s Secret" - when: not kubernetes_secret_exists - kubernetes.core.k8s: - state: present - definition: - apiVersion: v1 - kind: Secret - metadata: - name: "oidc-client-{{ client_spec.slug }}" - namespace: "{{ k8s_namespace }}" - labels: - app.kubernetes.io/managed-by: ansible-oidc-bootstrap - app.kubernetes.io/component: oidc-client - annotations: - helm.sh/resource-policy: keep - oidc.cute.haus/client-name: "{{ client_spec.name }}" - oidc.cute.haus/client-id: "{{ oidc_client_record.id }}" - type: Opaque - stringData: - client_id: "{{ oidc_client_record.id }}" - client_secret: "{{ secret_rotation_response.json.secret }}" - no_log: true - -- name: "[{{ client_spec.slug }}] Read back credentials" - kubernetes.core.k8s_info: - api_version: v1 - kind: Secret - namespace: "{{ k8s_namespace }}" - name: "oidc-client-{{ client_spec.slug }}" - register: kubernetes_secret_final - no_log: true - -- name: "[{{ client_spec.slug }}] Stash credentials for integration tasks" - ansible.builtin.set_fact: - oidc_client_credentials_by_slug: >- - {{ - (oidc_client_credentials_by_slug | default({})) | combine({ - client_spec.slug: { - 'client_id': kubernetes_secret_final.resources[0].data.client_id | b64decode, - 'client_secret': kubernetes_secret_final.resources[0].data.client_secret | b64decode, - } - }) - }} - no_log: true diff --git a/ansible/playbooks/tasks/oidc/upload-logo.yml b/ansible/playbooks/tasks/oidc/upload-logo.yml deleted file mode 100644 index b21c2df9..00000000 --- a/ansible/playbooks/tasks/oidc/upload-logo.yml +++ /dev/null @@ -1,26 +0,0 @@ ---- -- name: "[{{ client_spec.slug }}] Download logo" - ansible.builtin.get_url: - url: "{{ client_spec.logoUrl }}" - # Pocket ID rejects uploads without a file extension. - dest: "/tmp/oidc-logo-{{ client_spec.slug }}.{{ client_spec.logoUrl | split('.') | last }}" - mode: "0644" - register: logo_download_result - -# ansible.builtin.uri's form-multipart can't handle binary file content -# (treats it as a UTF-8 string), so shell out to curl. -- name: "[{{ client_spec.slug }}] POST logo to Pocket ID" - ansible.builtin.command: - argv: - - curl - - --silent - - --show-error - - --fail - - -X - - POST - - -H - - "X-API-KEY: {{ pocket_id_secrets.admin_api_key }}" - - -F - - "file=@{{ logo_download_result.dest }}" - - "{{ pocket_id_url }}/api/oidc/clients/{{ oidc_client_record.id }}/logo" - no_log: true diff --git a/ansible/playbooks/vars/oidc-clients.yml b/ansible/playbooks/vars/oidc-clients.yml deleted file mode 100644 index 2687d94b..00000000 --- a/ansible/playbooks/vars/oidc-clients.yml +++ /dev/null @@ -1,56 +0,0 @@ -oidc_clients: - - slug: tranquil - name: Tranquil - launchURL: https://aly.social/ - callbackURLs: - - https://aly.social/oauth/sso/callback - isPublic: false - pkceEnabled: true - # Slug must match the forward-auth- Deployment name. - - slug: forward-auth-navidrome - name: Navidrome - namespace: identity - logoUrl: https://cdn.jsdelivr.net/gh/selfhst/icons@main/png/navidrome.png - launchURL: https://navidrome.cute.haus/ - callbackURLs: - - https://auth-navidrome.cute.haus/_oauth - isPublic: false - pkceEnabled: false - integration: forward-auth - - # immich runs in k3s (moved off NixOS in b524c29c). No integration task — - # OAuth creds live in the immich-config / immich-env SOPS secrets and are - # wired into the chart manually (OIDC client config is baked into - # config.json, not env-driven). - - slug: immich - name: Immich - logoUrl: https://cdn.jsdelivr.net/gh/selfhst/icons@main/png/immich.png - launchURL: https://immich.cute.haus/ - callbackURLs: - - https://immich.cute.haus/auth/login - - https://immich.cute.haus/user-settings - - app.immich:///oauth-callback - isPublic: false - pkceEnabled: true - - - slug: paperless - name: Paperless - logoUrl: https://cdn.jsdelivr.net/gh/selfhst/icons@main/png/paperless-ngx.png - launchURL: https://paperless.cute.haus/ - callbackURLs: - - https://paperless.cute.haus/accounts/oidc/pocket-id/login/callback/ - isPublic: false - pkceEnabled: true - - - slug: nextcloud - name: Nextcloud - logoUrl: https://cdn.jsdelivr.net/gh/selfhst/icons@main/png/nextcloud.png - launchURL: https://nextcloud.cute.haus/ - callbackURLs: - - https://nextcloud.cute.haus/apps/user_oidc/code - isPublic: false - pkceEnabled: true - integration: nextcloud - # nextcloud runs in its own namespace; write the SSO env Secret and - # restart the Deployment there instead of the playbook default. - namespace: nextcloud diff --git a/ansible/playbooks/vars/pocket-id.yml b/ansible/playbooks/vars/pocket-id.yml deleted file mode 100644 index 388896ba..00000000 --- a/ansible/playbooks/vars/pocket-id.yml +++ /dev/null @@ -1,7 +0,0 @@ -pocket_id_app_config: - appName: cute.haus - smtpHost: smtp.resend.com - smtpPort: "2465" - smtpUser: resend - smtpFrom: id@aly.social - smtpTls: tls diff --git a/docs/change-opentofu.md b/docs/change-opentofu.md new file mode 100644 index 00000000..5358fa30 --- /dev/null +++ b/docs/change-opentofu.md @@ -0,0 +1,78 @@ +# Change OpenTofu + +Use this guide to change a B2 bucket or the Tailscale ACL. + +1. From the repository root, load the encrypted credentials. + + ```sh + direnv allow + ``` + +2. Initialize OpenTofu, then inspect the plan. + + ```sh + tofu -chdir=terraform init + tofu -chdir=terraform plan + ``` + +3. If the plan has only the changes you expect, apply it. + + ```sh + tofu -chdir=terraform apply + ``` + +## Recover OpenTofu state + +The state file is `cute.haus/terraform/terraform.tfstate` in the versioned +`aly-backups` bucket. B2 does not provide a state lock for this backend. + +1. Stop every planned or running `tofu apply`. + +2. In B2, open the file versions for + `cute.haus/terraform/terraform.tfstate`. Download the current version and + the version that you want to recover. + +3. Inspect the candidate state before you replace the current file. + + ```sh + tofu -chdir=terraform state list -state=/path/to/candidate.tfstate + ``` + +4. Upload the verified candidate as + `cute.haus/terraform/terraform.tfstate`. B2 retains the replaced state as + another file version. + +5. Reinitialize the backend, then inspect the plan. + + ```sh + tofu -chdir=terraform init -reconfigure + tofu -chdir=terraform plan + ``` + +Apply only after the plan describes the expected remote objects. + +## Rotate provider credentials + +1. Create replacement credentials in B2 or Tailscale. Keep the old + credential valid until the replacement works. + +2. Update the encrypted credential. + + ```sh + just sops-edit b2 + just sops-edit tailscale-api + ``` + +3. Reload the environment, then verify that OpenTofu can read the state and + both providers. + + ```sh + direnv reload + tofu -chdir=terraform init -reconfigure + tofu -chdir=terraform plan + ``` + +4. If another repository uses the replaced credential, update its encrypted + secret before you revoke the old credential. + +5. Revoke the old credential after the new one works. diff --git a/docs/sops.md b/docs/sops.md new file mode 100644 index 00000000..aa3acaa6 --- /dev/null +++ b/docs/sops.md @@ -0,0 +1,48 @@ +# Change SOPS recipients + +Use this guide to add or remove a machine that can decrypt this repository's +secrets. + +Every public key in `keys/` can decrypt every file in `secrets/`. The +`sops-rekey` recipe writes `.sops.yaml` from those public keys and updates the +recipient metadata in each secret. + +## Add a recipient + +1. Add the recipient's SSH public key to `keys/`. + + Use `aly_.pub` for Aly's user key. Use `root_.pub` for a host + root key. + +2. Regenerate the SOPS policy and recipient metadata. + + ```sh + just sops-rekey + ``` + +3. Review the generated policy and encrypted metadata. Do not print decrypted + secret values. + + ```sh + git diff -- .sops.yaml secrets + ``` + +4. Verify that SOPS can decrypt every secret with your current key. + + ```sh + for secret in secrets/*.yaml; do + sops --decrypt "$secret" >/dev/null + done + ``` + +## Remove a recipient + +1. Confirm that the machine no longer needs access to `secrets/`. + +2. Remove the matching public key from `keys/`. + +3. Run `just sops-rekey`. + +4. Review the policy and secret metadata as in the add-recipient procedure. + +Never add a private key to this repository. diff --git a/flake.lock b/flake.lock index 2f8b4c98..af82df9e 100644 --- a/flake.lock +++ b/flake.lock @@ -1,37 +1,5 @@ { "nodes": { - "absolute": { - "flake": false, - "locked": { - "lastModified": 1779397808, - "narHash": "sha256-u3MMV5YAKwfQd6XtU3XaDkxY8Hg0iZ9uWzS7Gmkx/E0=", - "owner": "ZeroQI", - "repo": "Absolute-Series-Scanner", - "rev": "a72a58f764d1884a3007811576440a6cf3b7f21a", - "type": "github" - }, - "original": { - "owner": "ZeroQI", - "repo": "Absolute-Series-Scanner", - "type": "github" - } - }, - "audnexus": { - "flake": false, - "locked": { - "lastModified": 1770741795, - "narHash": "sha256-n+iKjhr1qAhSOfPiugUICmy3jieMc2VYycBP3V9bs7U=", - "owner": "djdembeck", - "repo": "Audnexus.bundle", - "rev": "4d204bf387e1a6ae844ebd2cc73b61db7540c11e", - "type": "github" - }, - "original": { - "owner": "djdembeck", - "repo": "Audnexus.bundle", - "type": "github" - } - }, "blzrd": { "inputs": { "flake-parts": [ @@ -58,72 +26,6 @@ "type": "github" } }, - "crane": { - "locked": { - "lastModified": 1781825982, - "narHash": "sha256-SlXKwIRIhrOSAcTjCB3ftPLzJWZStQIPS7J1FlZPnKk=", - "owner": "ipetkov", - "repo": "crane", - "rev": "469fd08d0bcf6926321fa973c6777fbc87785dd7", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, - "disko": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1781152676, - "narHash": "sha256-RxWs5ND31KzTG7wvMM+PMfUjyNpmIEr999lqNARaM5o=", - "owner": "nix-community", - "repo": "disko", - "rev": "ff8702b4de27f72b4c78573dfb89ec74e36abdf1", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "disko", - "type": "github" - } - }, - "files": { - "locked": { - "lastModified": 1753414454, - "narHash": "sha256-IMdHZjva8z354/TAjkKqgHJ0k7qGZeaf460EPq/awDA=", - "owner": "alyraffauf", - "repo": "flake-files", - "rev": "fdfd673e34933a6836e6dccda820e448300e4c05", - "type": "github" - }, - "original": { - "owner": "alyraffauf", - "repo": "flake-files", - "type": "github" - } - }, - "flake-compat": { - "flake": false, - "locked": { - "lastModified": 1767039857, - "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", - "owner": "NixOS", - "repo": "flake-compat", - "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "flake-compat", - "type": "github" - } - }, "flake-parts": { "inputs": { "nixpkgs-lib": "nixpkgs-lib" @@ -142,44 +44,6 @@ "type": "github" } }, - "gitignore": { - "inputs": { - "nixpkgs": [ - "lanzaboote", - "pre-commit", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1709087332, - "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", - "owner": "hercules-ci", - "repo": "gitignore.nix", - "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", - "type": "github" - }, - "original": { - "owner": "hercules-ci", - "repo": "gitignore.nix", - "type": "github" - } - }, - "hama": { - "flake": false, - "locked": { - "lastModified": 1783782000, - "narHash": "sha256-hK4QZbl5ddHnMAE30RB8wIWQ4edvD09mgC10+Fy/R/I=", - "owner": "ZeroQI", - "repo": "Hama.bundle", - "rev": "2250fabb1dbc6d3209baa204e308b2d0fb239029", - "type": "github" - }, - "original": { - "owner": "ZeroQI", - "repo": "Hama.bundle", - "type": "github" - } - }, "import-tree": { "locked": { "lastModified": 1784254960, @@ -195,42 +59,18 @@ "type": "github" } }, - "lanzaboote": { - "inputs": { - "crane": "crane", - "nixpkgs": [ - "nixpkgs" - ], - "pre-commit": "pre-commit", - "rust-overlay": "rust-overlay" - }, - "locked": { - "lastModified": 1782141370, - "narHash": "sha256-hqijVSEETttmo8Okql9/LG0Ua34hdciKW1a5zzlj8mU=", - "owner": "nix-community", - "repo": "lanzaboote", - "rev": "7c9a54a7f87b4539ddbd8bda09a8a5f5f9361aa9", - "type": "github" - }, - "original": { - "owner": "nix-community", - "ref": "v1.1.0", - "repo": "lanzaboote", - "type": "github" - } - }, "nixpkgs": { "locked": { - "lastModified": 1786711500, - "narHash": "sha256-QvnceIGTBeDvDd9oCn+GvdsnkquliuwbVgpiRH68qaQ=", + "lastModified": 1787135253, + "narHash": "sha256-RD2kNWCG+Bjo6h+JVjWVNntZs2GtRoeY2xHjts/FNkA=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "02e08985a27c65ffd33d434eeb2e660a2e4dc84d", + "rev": "ffb3c9b700e759be2ef13237c9d8f953b32a1e46", "type": "github" }, "original": { "owner": "NixOS", - "ref": "nixos-26.05", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } @@ -250,86 +90,15 @@ "type": "github" } }, - "pre-commit": { - "inputs": { - "flake-compat": "flake-compat", - "gitignore": "gitignore", - "nixpkgs": [ - "lanzaboote", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1781733627, - "narHash": "sha256-U3yTuGBnmXvXoQI3qkpfEDsn9RovQPAjN7ndRco+3u0=", - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "3bbec39bc90eadfa031e6f3b77272f3f60803e39", - "type": "github" - }, - "original": { - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "type": "github" - } - }, "root": { "inputs": { - "absolute": "absolute", - "audnexus": "audnexus", "blzrd": "blzrd", - "disko": "disko", - "files": "files", "flake-parts": "flake-parts", - "hama": "hama", "import-tree": "import-tree", - "lanzaboote": "lanzaboote", "nixpkgs": "nixpkgs", - "sops-nix": "sops-nix", "treefmt-nix": "treefmt-nix" } }, - "rust-overlay": { - "inputs": { - "nixpkgs": [ - "lanzaboote", - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1782012058, - "narHash": "sha256-9mWUnReOUXfKjZuJAL/bAFH3LUyECTRtXgSNVjRw3UY=", - "owner": "oxalica", - "repo": "rust-overlay", - "rev": "8534567325bd8a8d2928e6afd81e0a87d19efd3c", - "type": "github" - }, - "original": { - "owner": "oxalica", - "repo": "rust-overlay", - "type": "github" - } - }, - "sops-nix": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1786629091, - "narHash": "sha256-gkig4nPi1CWc4Z50GBsjE4ygSE7hMpl/TwID2an2Cck=", - "owner": "Mic92", - "repo": "sops-nix", - "rev": "a8627b21b9107c5711c96b84f32a9a4b3d45295f", - "type": "github" - }, - "original": { - "owner": "Mic92", - "repo": "sops-nix", - "type": "github" - } - }, "treefmt-nix": { "inputs": { "nixpkgs": [ diff --git a/flake.nix b/flake.nix index 8cd9033a..57a8b255 100644 --- a/flake.nix +++ b/flake.nix @@ -1,22 +1,10 @@ { - description = "cute.haus infra"; + description = "Shared cute.haus infrastructure"; inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05"; - - disko = { - url = "github:nix-community/disko"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - - files.url = "github:alyraffauf/flake-files"; - flake-parts.url = "github:hercules-ci/flake-parts"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; import-tree.url = "github:denful/import-tree"; - - lanzaboote = { - url = "github:nix-community/lanzaboote/v1.1.0"; - inputs.nixpkgs.follows = "nixpkgs"; - }; + flake-parts.url = "github:hercules-ci/flake-parts"; blzrd = { url = "github:alyraffauf/blzrd"; @@ -25,43 +13,24 @@ inputs.treefmt-nix.follows = "treefmt-nix"; }; - sops-nix = { - url = "github:Mic92/sops-nix"; - inputs.nixpkgs.follows = "nixpkgs"; - }; - treefmt-nix = { url = "github:numtide/treefmt-nix"; inputs.nixpkgs.follows = "nixpkgs"; }; - - # Non-flake inputs - absolute = { - url = "github:ZeroQI/Absolute-Series-Scanner"; - flake = false; - }; - - audnexus = { - url = "github:djdembeck/Audnexus.bundle"; - flake = false; - }; - - hama = { - url = "github:ZeroQI/Hama.bundle"; - flake = false; - }; }; nixConfig = { accept-flake-config = true; extra-substituters = [ - "https://cutehaus.cachix.org" + "https://install.determinate.systems" + "https://alyraffauf.cachix.org" "https://nix-community.cachix.org" ]; extra-trusted-public-keys = [ - "cutehaus.cachix.org-1:KiifTsseQBitoaHH8rkDUDwzyz9akLeOM+K+e2eK8dA=" + "cache.flakehub.com-3:hJuILl5sVK4iKm86JzgdXW12Y2Hwd5G07qKtHTOcDCM=" + "alyraffauf.cachix.org-1:GQVrRGfjTtkPGS8M6y7Ik0z4zLt77O0N25ynv2gWzDM=" "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" ]; }; @@ -74,6 +43,8 @@ sharedPackageSets = { aarch64-darwin = import nixpkgs { system = "aarch64-darwin"; + config.allowUnfree = true; + overlays = [inputs.self.overlays.default]; }; x86_64-linux = import nixpkgs { @@ -94,9 +65,7 @@ }; imports = [ - (inputs.import-tree ./nix/modules) - inputs.files.flakeModules.default - inputs.flake-parts.flakeModules.modules + (inputs.import-tree ./nix) inputs.blzrd.flakeModule inputs.treefmt-nix.flakeModule ]; diff --git a/k8s/OPERATIONS.md b/k8s/OPERATIONS.md deleted file mode 100644 index 617388f1..00000000 --- a/k8s/OPERATIONS.md +++ /dev/null @@ -1,119 +0,0 @@ -# Kubernetes operations - -Flux is the deployment controller. Git is the desired state: make and review a -change here, merge it, then let Flux reconcile it. Use `just k8s-status` first -when the cluster looks unhealthy; it prints only actionable failures. - -## Normal changes and incidents - -```bash -just check -git push -flux reconcile kustomization apps -n flux-system --with-source -just k8s-status -``` - -Preview a local chart with `just k8s diff `. Use -`just k8s suspend`, `resume`, and `reconcile` for a HelmRelease; do not use -`helm upgrade` as a deployment path. - -For an emergency live recovery: suspend the affected HelmRelease, make the -minimum live recovery change, commit the desired fix, then resume and reconcile -the release. Flux must regain Git authority before the incident is closed. - -Useful incident commands: - -```bash -flux get kustomizations -A -flux get helmreleases -A -kubectl get pods,pvc,certificate -A -flux suspend helmrelease -n flux-system -flux reconcile helmrelease -n flux-system --with-source -kubectl rollout undo deployment/ -n -``` - -`kubectl rollout undo` is temporary recovery only: capture the resulting desired -configuration in Git, then reconcile Flux. Helm rollback is likewise an -emergency measure (`helm history` then `helm rollback`) while the release is -suspended. - -## Platform and identity namespace migration - -Apply the Tika, Gotenberg, and forward-auth namespace move as a controlled -maintenance operation. The new HelmRelease targets must not overlap the old -release state. - -```bash -flux suspend helmrelease tika -n flux-system -flux suspend helmrelease gotenberg -n flux-system -flux suspend helmrelease forward-auth -n flux-system - -# Merge the desired state, then create namespaces and the identity Secret. -flux reconcile kustomization secrets -n flux-system --with-source - -# Once the identity Secret exists, remove the old release records only. -helm uninstall tika -n default -helm uninstall gotenberg -n default -helm uninstall forward-auth -n default - -flux resume helmrelease tika -n flux-system -flux resume helmrelease gotenberg -n flux-system -flux resume helmrelease forward-auth -n flux-system -flux reconcile kustomization platform -n flux-system --with-source -flux reconcile kustomization apps -n flux-system --with-source -``` - -Then verify `paperless` starts with `tika.platform.svc` and -`gotenberg.platform.svc`, and open Navidrome through -`identity-forward-auth-navidrome`. This intentionally causes a short outage for -the three moved services. - -## Service inventory - -This table is maintained with the Flux workload declarations. `local-path` means -node-local or host-mounted data and must be recovered on its owning node. - -| Release | Delivery | Namespace | URL | Dependencies | Persistence | Backup / restore owner | Data-loss expectation | -| ------------ | ------------ | ----------- | --------------------------- | ----------------------------------------- | ------------------------------------- | --------------------------- | --------------------------------------- | -| collabora | Docker | Jubilife | https://collabora.cute.haus | nextcloud | none | configuration only | rebuildable | -| error-pages | Kustomize | default | internal | traefik | none | Git | rebuildable | -| forward-auth | forward-auth | identity | internal | Pocket ID | SOPS secret | SOPS / identity operator | reconfigure clients | -| gotenberg | NixOS | jubilife | internal | paperless | none | Git | rebuildable | -| immich | NixOS | jubilife | https://immich.cute.haus | local PostgreSQL, Valkey | local host data | node owner / Immich export | photo loss possible without node data | -| navidrome | navidrome | default | https://navidrome.cute.haus | forward-auth | Longhorn config, host media | Longhorn / media host owner | media is external; config may be lost | -| nextcloud | NixOS | jubilife | https://nextcloud.cute.haus | local PostgreSQL, Valkey, Garage | local host data | node owner | file loss possible without node data | -| paperless | NixOS | jubilife | https://paperless.cute.haus | local PostgreSQL, Valkey, Tika, Gotenberg | local host data | node owner | documents may be lost without node data | -| pg-shared | pg-shared | cnpg-system | internal | CNPG | Longhorn database volumes, B2 backups | CNPG backup owner | point-in-time limited to backups | -| plex | NixOS | jubilife | https://plex.cute.haus | media host | local-path config and media mounts | node/media owner | config or metadata loss possible | -| pocket-id | Kustomize | identity | https://id.cute.haus | pg-shared | CNPG | CNPG backup owner | identity records depend on DB backup | -| slingshot | NixOS | jubilife | https://slingshot.cute.haus | — | ephemeral cache | Git | rebuildable | -| tika | NixOS | jubilife | internal | paperless | none | Git | rebuildable | -| uptime-kuma | uptime-kuma | default | https://kuma.cute.haus | — | Longhorn | Longhorn backup owner | monitor history/config loss possible | -| vaultwarden | vaultwarden | default | https://vault.cute.haus | — | Longhorn | Longhorn backup owner | vault loss is critical | - -## Stateful recovery - -- Longhorn: inspect replicas and backups with `kubectl -n longhorn-system get -volumes,longhornbackups`; restore to a new volume/PVC, verify it, then point - the workload at it. Do not delete the original volume while diagnosing. -- local-path and host-path: identify the PVC's node with `kubectl get pv` and - recover the data on that node before rescheduling. The storage class does not - provide replication. -- CNPG: use the `pg-shared` ScheduledBackup/B2 path, restore to a separate - Cluster, validate databases and roles, then plan the controlled cutover. - Never overwrite the live cluster as the first recovery action. - -## Uptime Kuma checklist (v1) - -Kuma is configured in its UI; this checklist is the versioned source of -monitoring intent. After every deployment, configure HTTPS monitors for every -public URL in the inventory, including all `pds.cute.haus`, `aly.social`, -`status.cute.haus` and `status.aly.social` routes. - -- Confirm each monitor runs externally, follows the intended HTTP success rule, - and validates TLS expiry/certificate hostname. -- Put public customer-facing endpoints on the correct Kuma status page. -- Open each status page from outside the cluster and confirm its monitor state - and TLS certificate are visible. -- Record new URLs here before adding their UI monitor; remove UI monitors only - after removing the URL from this checklist. diff --git a/k8s/charts/README.md b/k8s/charts/README.md deleted file mode 100644 index 63d155d5..00000000 --- a/k8s/charts/README.md +++ /dev/null @@ -1,184 +0,0 @@ -# Charts - -In-tree Helm charts deployed by Flux HelmReleases under [`../flux`](../flux). -Small hand-authored workloads live as raw Kustomize manifests in their Flux -layer instead of as charts. - -Helm is reserved for upstream packages, reusable releases, and charts that -need data-driven rendering. Avoid shared Deployment/Service/PVC helpers; -app-specific behavior should stay visible in direct manifests. - -## Layout - -```text -charts/ -├── cert-manager-issuers/ # Let's Encrypt ClusterIssuer + wildcard Certificates -├── external-routes/ # Ingress + Service + EndpointSlice for off-cluster targets -├── forward-auth/ # Per-app traefik-forward-auth frontends -├── longhorn-creds/ # B2 backup Secret + recurring backup job + UI ingress -├── paperless/ # Document management with rclone media mount -├── pg-shared/ # CloudNativePG cluster using local-path replicas -└── ... -``` - -Undeployed charts live in [`../drafts`](../drafts), outside the Flux chart -inventory. See its README before promoting a draft to production. - -## Workload Styles - -Use raw Kustomize manifests for fixed, hand-authored workloads. Their files -live beside the Flux layer that applies them, for example -`../flux/apps/watsup/` or `../flux/platform/tika/`. Each directory has a -small `kustomization.yaml` that sets its namespace and lists its resources. - -Use Helm only when release reuse or structured rendering is meaningful. The -remaining local Helm charts are data-driven or stateful; they are not generic -wrappers around otherwise static YAML. - -## Chart Style - -Prefer direct manifests: - -```yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: { { .Chart.Name } } - labels: - app: { { .Chart.Name } } -spec: - selector: - matchLabels: - app: { { .Chart.Name } } - template: - metadata: - labels: - app: { { .Chart.Name } } - spec: - automountServiceAccountToken: false - enableServiceLinks: false - containers: - - name: { { .Chart.Name } } - image: example/app:1.0.0@sha256:... -``` - -Use this pod-spec order when practical: - -```yaml -automountServiceAccountToken: false -enableServiceLinks: false -terminationGracePeriodSeconds: 30 -securityContext: -tolerations: -hostNetwork: -dnsPolicy: -nodeSelector: -imagePullSecrets: -topologySpreadConstraints: -initContainers: -containers: -volumes: -``` - -Only include fields that the app actually needs. Do not add shared helpers just -to make every chart identical. - -## Templating Rules - -Keep these: - -- `.Chart.Name` for names, labels, selectors, and PVC names. -- Small `range` loops for charts that are naturally data-driven. - -Avoid these: - -- Common Deployment/Service/PVC helper templates. -- Values that model arbitrary pod specs, containers, sidecars, volumes, or env. -- Large `_helpers.tpl` files for simple app charts. - -## Chart Tiers - -Charts fall into three readability tiers: - -- **Configurable application charts** such as Paperless, Nextcloud, and Immich - render meaningful values that affect the workload. -- **Data-driven charts** render repeated resources from structured values: - `forward-auth`, `external-routes`, `pg-shared`, and - `cert-manager-issuers`. - -Do not move Helm charts into namespace-named directories. The HelmRelease is -the deployment boundary, and a chart can be reused by multiple releases. Fixed -hand-authored workloads belong in their Flux layer as raw manifests instead. - -## Data-Driven Exceptions - -Some charts intentionally render repeated resources from values: - -- **`forward-auth`** renders one auth Deployment/Service/Ingress/Middleware set - per `.Values.apps` entry. -- **`external-routes`** renders off-cluster Service, EndpointSlice, and Ingress - resources from `.Values.routes`. -- **`pg-shared`** renders CNPG roles/databases and backup resources from chart - values. -- **`cert-manager-issuers`** renders repeated certificate resources from values. - -Those are data charts rather than app workload charts, so a little looping is -acceptable there. - -## Intel GPU Scheduling - -Intel GPU nodes are labeled from the NixOS `intel-gpu` module: - -```yaml -nodeSelector: - cute.haus/intel-gpu: "true" -``` - -For pods that need actual GPU access, also request and limit the Intel device -plugin resource: - -```yaml -resources: - requests: - gpu.intel.com/i915: "1" - limits: - gpu.intel.com/i915: "1" -``` - -Do not use `gpu.intel.com/i915` as a `nodeSelector`; the Intel device plugin -publishes that as node capacity/allocatable, not as a stable node label. - -## Secret Flow - -```text -k8s/flux/secrets/foo.sops.yaml SOPS-encrypted Kubernetes Secret - | - v -Flux kustomize-controller decrypts with flux-system/sops-age - | - v -Kubernetes Secret first-class object in target namespace - | - v -Deployment envFrom/secretRef app consumes the Secret -``` - -Flux decrypts only `k8s/flux/secrets/*.sops.yaml`; host/Terraform secrets under -`secrets/*.yaml` remain user/host-key scoped. - -## Adding An App - -1. Create `charts//Chart.yaml`. -2. Add explicit templates for only the resources the app needs, usually - `deployment.yaml`, `service.yaml`, `ingress.yaml`, optional `pvc.yaml`, and - optional `secret.yaml`. -3. Put app-specific behavior directly in those manifests. -4. If the app needs secrets, create first-class SOPS Secret manifests under - `../flux/secrets/` and reference those Secret names from the chart. -5. Add a HelmRelease under `../flux/apps/`. -6. Render before applying: - -```bash -helm template charts/ -flux reconcile kustomization apps -n flux-system -``` diff --git a/k8s/charts/cert-manager-issuers/Chart.yaml b/k8s/charts/cert-manager-issuers/Chart.yaml deleted file mode 100644 index b256b6af..00000000 --- a/k8s/charts/cert-manager-issuers/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v2 -name: cert-manager-issuers -description: ClusterIssuers + wildcard Certificates for cluster TLS via Let's Encrypt + Cloudflare DNS-01 -type: application -version: 0.1.0 diff --git a/k8s/charts/cert-manager-issuers/templates/certificates.yaml b/k8s/charts/cert-manager-issuers/templates/certificates.yaml deleted file mode 100644 index 3b46877b..00000000 --- a/k8s/charts/cert-manager-issuers/templates/certificates.yaml +++ /dev/null @@ -1,24 +0,0 @@ -{{- range .Values.wildcards }} ---- -apiVersion: cert-manager.io/v1 -kind: Certificate -metadata: - name: {{ .name }} - namespace: {{ .namespace }} -spec: - secretName: {{ .name }} - {{- with .replicateTo }} - secretTemplate: - annotations: - reflector.v1.k8s.emberstack.com/reflection-allowed: "true" - reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: {{ join "," . | quote }} - reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true" - reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: {{ join "," . | quote }} - {{- end }} - issuerRef: - name: letsencrypt - kind: ClusterIssuer - dnsNames: - - {{ .domain }} - - "*.{{ .domain }}" -{{- end }} diff --git a/k8s/charts/cert-manager-issuers/templates/clusterissuer-letsencrypt.yaml b/k8s/charts/cert-manager-issuers/templates/clusterissuer-letsencrypt.yaml deleted file mode 100644 index b1e7b6bc..00000000 --- a/k8s/charts/cert-manager-issuers/templates/clusterissuer-letsencrypt.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: cert-manager.io/v1 -kind: ClusterIssuer -metadata: - name: letsencrypt -spec: - acme: - server: {{ .Values.letsencrypt.server }} - email: {{ .Values.letsencrypt.email }} - privateKeySecretRef: - name: letsencrypt-account-key - solvers: - - dns01: - cloudflare: - apiTokenSecretRef: - name: cloudflare-api-token - key: api-token diff --git a/k8s/charts/cert-manager-issuers/values.schema.json b/k8s/charts/cert-manager-issuers/values.schema.json deleted file mode 100644 index ab39cf5d..00000000 --- a/k8s/charts/cert-manager-issuers/values.schema.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "required": ["letsencrypt", "wildcards"], - "properties": { - "letsencrypt": { - "type": "object", - "required": ["email", "server"], - "properties": { - "email": { "type": "string", "format": "email" }, - "server": { "type": "string", "format": "uri" } - }, - "additionalProperties": true - }, - "cloudflare": { "type": "object" }, - "wildcards": { - "type": "array", - "items": { - "type": "object", - "required": ["name", "namespace", "domain"], - "properties": { - "name": { "type": "string", "minLength": 1 }, - "namespace": { "type": "string", "minLength": 1 }, - "domain": { "type": "string", "minLength": 1 }, - "replicateTo": { "type": "array", "items": { "type": "string" } } - }, - "additionalProperties": true - } - } - }, - "additionalProperties": true -} diff --git a/k8s/charts/cert-manager-issuers/values.yaml b/k8s/charts/cert-manager-issuers/values.yaml deleted file mode 100644 index fc67d122..00000000 --- a/k8s/charts/cert-manager-issuers/values.yaml +++ /dev/null @@ -1,25 +0,0 @@ -letsencrypt: - email: aly@aly.codes - server: https://acme-v02.api.letsencrypt.org/directory # use https://acme-staging-v02.api.letsencrypt.org/directory for testing - -# Populated from values/secrets/cert-manager.yaml. -cloudflare: - apiToken: "" - -# Wildcard certs to issue, one per zone. Each becomes a Secret in the named -# namespace; reflector mirrors it into the replicateTo namespaces so their -# ingresses can reference the same secretName without a second issuance. -wildcards: - - name: cute-haus-tls - namespace: default - domain: cute.haus - replicateTo: - - identity - - nextcloud - - websites - - name: aly-social-tls - namespace: default - domain: aly.social - - name: cute-haus-tls - namespace: microcosm - domain: cute.haus diff --git a/k8s/charts/external-routes/Chart.yaml b/k8s/charts/external-routes/Chart.yaml deleted file mode 100644 index d887f083..00000000 --- a/k8s/charts/external-routes/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v2 -name: external-routes -description: Ingress routes for non-cluster services -type: application -version: 0.1.0 diff --git a/k8s/charts/external-routes/templates/routes.yaml b/k8s/charts/external-routes/templates/routes.yaml deleted file mode 100644 index 9cc0c29e..00000000 --- a/k8s/charts/external-routes/templates/routes.yaml +++ /dev/null @@ -1,84 +0,0 @@ -{{- range $route := .Values.routes }} ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ $route.name }} - labels: - app: {{ $route.name }} -spec: - ports: - - name: http - port: {{ $route.target.port }} - protocol: TCP - targetPort: {{ $route.target.port }} ---- -apiVersion: discovery.k8s.io/v1 -kind: EndpointSlice -metadata: - name: {{ $route.name }} - labels: - app: {{ $route.name }} - kubernetes.io/service-name: {{ $route.name }} -addressType: IPv4 -ports: - - name: http - port: {{ $route.target.port }} - protocol: TCP -endpoints: - - addresses: - - {{ $route.target.ip }} - conditions: - ready: true ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: {{ $route.name }} - labels: - app: {{ $route.name }} - {{- if or $route.tailscaleHostname $route.middlewares }} - annotations: - {{- if $route.tailscaleHostname }} - tailscale.com/hostname: {{ $route.tailscaleHostname | quote }} - {{- end }} - {{- if $route.middlewares }} - traefik.ingress.kubernetes.io/router.middlewares: {{ join "," $route.middlewares | quote }} - {{- end }} - {{- end }} -spec: - {{- $class := $route.ingressClassName | default $.Values.ingressClassName }} - ingressClassName: {{ $class }} - {{- $hosts := prepend (default (list) $route.aliases) $route.host }} - {{- if or $route.tls (eq $class "tailscale") }} - tls: - - hosts: - {{- range $hosts }} - - {{ . }} - {{- end }} - {{- if and $route.tls $route.tls.secretName }} - secretName: {{ $route.tls.secretName }} - {{- end }} - {{- end }} - {{- if eq $class "tailscale" }} - defaultBackend: - service: - name: {{ $route.name }} - port: - number: {{ $route.target.port }} - {{- else }} - rules: - {{- range $hosts }} - - host: {{ . }} - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: {{ $route.name }} - port: - number: {{ $route.target.port }} - {{- end }} - {{- end }} -{{- end }} diff --git a/k8s/charts/external-routes/values.schema.json b/k8s/charts/external-routes/values.schema.json deleted file mode 100644 index 8b029f57..00000000 --- a/k8s/charts/external-routes/values.schema.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "required": ["routes"], - "properties": { - "ingressClassName": { "type": "string" }, - "routes": { - "type": "array", - "items": { - "type": "object", - "required": ["name", "host", "target"], - "properties": { - "name": { "type": "string", "minLength": 1 }, - "host": { "type": "string", "minLength": 1 }, - "aliases": { "type": "array", "items": { "type": "string" } }, - "target": { - "type": "object", - "required": ["ip", "port"], - "properties": { - "ip": { "type": "string", "minLength": 1 }, - "port": { "type": "integer", "minimum": 1, "maximum": 65535 } - }, - "additionalProperties": true - }, - "tls": { "type": "object" }, - "middlewares": { "type": "array", "items": { "type": "string" } }, - "tailscaleHostname": { "type": "string" }, - "ingressClassName": { "type": "string" } - }, - "additionalProperties": true - } - } - }, - "additionalProperties": true -} diff --git a/k8s/charts/external-routes/values.yaml b/k8s/charts/external-routes/values.yaml deleted file mode 100644 index 0cc49f77..00000000 --- a/k8s/charts/external-routes/values.yaml +++ /dev/null @@ -1,5 +0,0 @@ -ingressClassName: traefik - -# Each route gets a Service + Endpoints + Ingress. -# Service name == route name. TLS secrets must exist in the release namespace. -routes: [] diff --git a/k8s/charts/forward-auth/Chart.yaml b/k8s/charts/forward-auth/Chart.yaml deleted file mode 100644 index c2a67d32..00000000 --- a/k8s/charts/forward-auth/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v2 -name: forward-auth -description: traefik-forward-auth (thomseddon) for SSO-gating apps, one TFA per app -type: application -version: 0.2.0 diff --git a/k8s/charts/forward-auth/templates/deployment.yaml b/k8s/charts/forward-auth/templates/deployment.yaml deleted file mode 100644 index c34d10a6..00000000 --- a/k8s/charts/forward-auth/templates/deployment.yaml +++ /dev/null @@ -1,100 +0,0 @@ -{{- range $key, $app := .Values.apps }} ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: forward-auth-{{ $key }} - labels: - app: forward-auth-{{ $key }} -spec: - replicas: 1 - strategy: - type: Recreate - selector: - matchLabels: - app: forward-auth-{{ $key }} - template: - metadata: - labels: - app: forward-auth-{{ $key }} - spec: - automountServiceAccountToken: false - enableServiceLinks: false - terminationGracePeriodSeconds: 15 - securityContext: - seccompProfile: - type: RuntimeDefault - tolerations: - - key: node.kubernetes.io/not-ready - operator: Exists - effect: NoExecute - tolerationSeconds: {{ $.Values.global.failover.fastTolerationSeconds | default 60 }} - - key: node.kubernetes.io/unreachable - operator: Exists - effect: NoExecute - tolerationSeconds: {{ $.Values.global.failover.fastTolerationSeconds | default 60 }} - affinity: - nodeAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - preference: - matchExpressions: - - key: topology.kubernetes.io/zone - operator: In - values: - - cloud - containers: - - name: forward-auth - image: "{{ $.Values.image.repository }}:{{ $.Values.image.tag }}" - imagePullPolicy: {{ $.Values.image.pullPolicy }} - ports: - - name: http - containerPort: 4181 - env: - - name: DEFAULT_PROVIDER - value: oidc - - name: PROVIDERS_OIDC_ISSUER_URL - value: {{ $.Values.issuerURL | quote }} - - name: AUTH_HOST - value: "auth-{{ $key }}.cute.haus" - - name: COOKIE_DOMAIN - value: {{ $.Values.cookieDomain | quote }} - # Each TFA pod needs its own cookie names, otherwise they overwrite each other's cookies on cute.haus. - - name: COOKIE_NAME - value: "_fa_{{ $key }}" - - name: CSRF_COOKIE_NAME - value: "_fa_csrf_{{ $key }}" - - name: URL_PATH - value: /_oauth - - name: LIFETIME - value: {{ $.Values.lifetime | quote }} - - name: LOG_LEVEL - value: {{ $.Values.logLevel | quote }} - envFrom: - - secretRef: - name: forward-auth-{{ $key }}-env - - secretRef: - name: forward-auth-{{ $key }}-oidc-env - resources: - {{- toYaml $.Values.resources | nindent 12 }} - # No dedicated health endpoint; unauthenticated GET / returns a 3xx - # redirect, which httpGet probes treat as success. - startupProbe: - httpGet: - path: / - port: http - periodSeconds: 5 - failureThreshold: 30 - readinessProbe: - httpGet: - path: / - port: http - periodSeconds: 5 - failureThreshold: 2 - livenessProbe: - httpGet: - path: / - port: http - periodSeconds: 10 - failureThreshold: 5 -{{- end }} diff --git a/k8s/charts/forward-auth/templates/ingress.yaml b/k8s/charts/forward-auth/templates/ingress.yaml deleted file mode 100644 index 9adee50c..00000000 --- a/k8s/charts/forward-auth/templates/ingress.yaml +++ /dev/null @@ -1,30 +0,0 @@ -{{- range $key, $app := .Values.apps }} ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: forward-auth-{{ $key }} - labels: - app: forward-auth-{{ $key }} - # TFA needs the X-Forwarded-Uri header to handle its own /_oauth callback, - # so this ingress goes through the middleware too. - annotations: - traefik.ingress.kubernetes.io/router.middlewares: "{{ $.Release.Namespace }}-forward-auth-{{ $key }}@kubernetescrd" -spec: - ingressClassName: {{ $.Values.ingressClassName }} - tls: - - hosts: - - "auth-{{ $key }}.cute.haus" - secretName: {{ $.Values.tlsSecret }} - rules: - - host: "auth-{{ $key }}.cute.haus" - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: forward-auth-{{ $key }} - port: - number: 80 -{{- end }} diff --git a/k8s/charts/forward-auth/templates/middleware.yaml b/k8s/charts/forward-auth/templates/middleware.yaml deleted file mode 100644 index 2b911437..00000000 --- a/k8s/charts/forward-auth/templates/middleware.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- range $key, $app := .Values.apps }} ---- -apiVersion: traefik.io/v1alpha1 -kind: Middleware -metadata: - name: forward-auth-{{ $key }} - labels: - app: forward-auth-{{ $key }} -spec: - forwardAuth: - address: "http://forward-auth-{{ $key }}.{{ $.Release.Namespace }}.svc/" - trustForwardHeader: true - authResponseHeaders: - - X-Forwarded-User -{{- end }} diff --git a/k8s/charts/forward-auth/templates/service.yaml b/k8s/charts/forward-auth/templates/service.yaml deleted file mode 100644 index 3ca3a90a..00000000 --- a/k8s/charts/forward-auth/templates/service.yaml +++ /dev/null @@ -1,18 +0,0 @@ -{{- range $key, $app := .Values.apps }} ---- -apiVersion: v1 -kind: Service -metadata: - name: forward-auth-{{ $key }} - labels: - app: forward-auth-{{ $key }} -spec: - type: ClusterIP - selector: - app: forward-auth-{{ $key }} - ports: - - name: http - port: 80 - targetPort: 4181 - protocol: TCP -{{- end }} diff --git a/k8s/charts/forward-auth/values.schema.json b/k8s/charts/forward-auth/values.schema.json deleted file mode 100644 index 426dc70d..00000000 --- a/k8s/charts/forward-auth/values.schema.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "properties": { - "apps": { - "type": "object", - "additionalProperties": { "type": "object" } - }, - "image": { "type": "object" }, - "resources": { "type": "object" }, - "ingressClassName": { "type": "string" }, - "tlsSecret": { "type": "string" }, - "issuerURL": { "type": "string", "format": "uri" }, - "cookieDomain": { "type": "string" }, - "lifetime": { "type": ["string", "integer"] }, - "logLevel": { "type": "string" } - }, - "additionalProperties": true -} diff --git a/k8s/charts/forward-auth/values.yaml b/k8s/charts/forward-auth/values.yaml deleted file mode 100644 index 837d4d1b..00000000 --- a/k8s/charts/forward-auth/values.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# Per-app traefik-forward-auth deployments. Each entry renders a -# Deployment + Service + Ingress + Middleware + Secret pair. - -image: - repository: thomseddon/traefik-forward-auth - tag: "2@sha256:69a2c985d2c518b6f0e77161a98628a148a5d964e4e84fc52cc62e19bb4da634" - pullPolicy: IfNotPresent - -resources: - requests: - cpu: 25m - memory: 32Mi - limits: - cpu: 500m - memory: 128Mi - -ingressClassName: traefik -tlsSecret: cute-haus-tls -issuerURL: https://id.cute.haus -cookieDomain: cute.haus -lifetime: "604800" -logLevel: warn - -# apps: -# : -# # signing Secret lives in k8s/flux/secrets/forward-auth--env.sops.yaml -apps: {} diff --git a/k8s/charts/longhorn-creds/Chart.yaml b/k8s/charts/longhorn-creds/Chart.yaml deleted file mode 100644 index 07c6bc85..00000000 --- a/k8s/charts/longhorn-creds/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v2 -name: longhorn-creds -description: B2 credentials Secret for Longhorn's S3-compatible backup target. -type: application -version: 0.1.0 diff --git a/k8s/charts/longhorn-creds/templates/recurring-job.yaml b/k8s/charts/longhorn-creds/templates/recurring-job.yaml deleted file mode 100644 index 3358f1cd..00000000 --- a/k8s/charts/longhorn-creds/templates/recurring-job.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: longhorn.io/v1beta2 -kind: RecurringJob -metadata: - name: {{ .Values.recurringJob.name }} - labels: - app: longhorn-creds -spec: - cron: {{ .Values.recurringJob.cron | quote }} - task: backup - groups: - - default - retain: {{ .Values.recurringJob.retain }} - concurrency: {{ .Values.recurringJob.concurrency }} diff --git a/k8s/charts/longhorn-creds/templates/tailscale-proxyclass.yaml b/k8s/charts/longhorn-creds/templates/tailscale-proxyclass.yaml deleted file mode 100644 index 3d37c463..00000000 --- a/k8s/charts/longhorn-creds/templates/tailscale-proxyclass.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- if .Values.tailnet.enabled }} -apiVersion: tailscale.com/v1alpha1 -kind: ProxyClass -metadata: - name: {{ .Values.tailnet.proxyClass.name }} -spec: - statefulSet: - pod: - affinity: - podAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - - labelSelector: - matchLabels: - app: {{ .Values.tailnet.affinity.matchLabels.app }} - namespaces: - {{- range .Values.tailnet.affinity.namespaces }} - - {{ . }} - {{- end }} - topologyKey: kubernetes.io/hostname -{{- end }} diff --git a/k8s/charts/longhorn-creds/templates/ui-ingress.yaml b/k8s/charts/longhorn-creds/templates/ui-ingress.yaml deleted file mode 100644 index fc0655ee..00000000 --- a/k8s/charts/longhorn-creds/templates/ui-ingress.yaml +++ /dev/null @@ -1,19 +0,0 @@ -{{- if .Values.tailnet.enabled }} -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: {{ .Values.tailnet.ingressName }} - labels: - app: longhorn-creds - tailscale.com/proxy-class: {{ .Values.tailnet.proxyClass.name }} -spec: - ingressClassName: tailscale - tls: - - hosts: - - {{ .Values.tailnet.hostname }} - defaultBackend: - service: - name: {{ .Values.tailnet.serviceName }} - port: - number: {{ .Values.tailnet.servicePort }} -{{- end }} diff --git a/k8s/charts/longhorn-creds/values.yaml b/k8s/charts/longhorn-creds/values.yaml deleted file mode 100644 index 1512cf38..00000000 --- a/k8s/charts/longhorn-creds/values.yaml +++ /dev/null @@ -1,26 +0,0 @@ -# Longhorn's helm release references the first-class longhorn-b2 Secret via -# defaultBackupStore.backupTargetCredentialSecret. - -# Daily backup of every volume in the implicit `default` group (i.e. all of -# them). retain is per-volume; concurrency caps parallel jobs cluster-wide. -recurringJob: - name: daily-backup - cron: "0 5 * * *" # 5am UTC, after CNPG's base backup at 4am - retain: 14 - concurrency: 2 - -# Expose the Longhorn UI on the tailnet. Longhorn-frontend has no built-in -# auth — do NOT expose publicly. -tailnet: - enabled: true - hostname: longhorn - ingressName: longhorn-ui - serviceName: longhorn-frontend - servicePort: 80 - proxyClass: - name: longhorn-ui-same-node - affinity: - matchLabels: - app: longhorn-ui - namespaces: - - longhorn-system diff --git a/k8s/charts/navidrome/Chart.yaml b/k8s/charts/navidrome/Chart.yaml deleted file mode 100644 index 2aadedc6..00000000 --- a/k8s/charts/navidrome/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v2 -name: navidrome -description: Navidrome music server -type: application -version: 0.1.0 diff --git a/k8s/charts/navidrome/templates/deployment.yaml b/k8s/charts/navidrome/templates/deployment.yaml deleted file mode 100644 index ba77be81..00000000 --- a/k8s/charts/navidrome/templates/deployment.yaml +++ /dev/null @@ -1,119 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: navidrome - labels: - app: navidrome -spec: - replicas: 1 - strategy: - type: Recreate - selector: - matchLabels: - app: navidrome - template: - metadata: - labels: - app: navidrome - spec: - automountServiceAccountToken: false - enableServiceLinks: false - terminationGracePeriodSeconds: 30 - securityContext: - fsGroup: 1000 - seccompProfile: - type: RuntimeDefault - tolerations: - - key: node.kubernetes.io/not-ready - operator: Exists - effect: NoExecute - tolerationSeconds: {{ $.Values.global.failover.fastTolerationSeconds | default 60 }} - - key: node.kubernetes.io/unreachable - operator: Exists - effect: NoExecute - tolerationSeconds: {{ $.Values.global.failover.fastTolerationSeconds | default 60 }} - nodeSelector: - kubernetes.io/hostname: jubilife - containers: - - name: navidrome - image: deluan/navidrome:0.63.2@sha256:9012939114fbb1bb641b81cf96dec5ded15f0aafefe8d47a511d7cb919658e40 - imagePullPolicy: IfNotPresent - command: - - /bin/sh - - -ec - args: - - | - set -a - . /run/secrets/navidrome/navidrome.env - set +a - exec /app/navidrome - env: - - name: ND_ADDRESS - value: "0.0.0.0" - - name: ND_PORT - value: "4533" - - name: ND_DATAFOLDER - value: "/data" - - name: ND_MUSICFOLDER - value: "/mnt/Media/Music" - - name: ND_LYRICSPRIORITY - value: ".lrc,nd-lyrics,.txt,embedded" - - name: ND_DEFAULTTHEME - value: "Auto" - - name: ND_ENABLEUSEREDITING - value: "false" - - name: ND_SUBSONICARTISTPARTICIPATIONS - value: "true" - - name: ND_UIWELCOMEMESSAGE - value: "Welcome to Navidrome @ k3s" - - name: ND_EXTAUTH_USERHEADER - value: "X-Forwarded-User" - - name: ND_EXTAUTH_TRUSTEDSOURCES - value: "100.64.0.0/10,10.42.0.0/16" - ports: - - name: http - containerPort: 4533 - resources: - requests: - cpu: 50m - memory: 256Mi - limits: - cpu: "1" - memory: 1Gi - volumeMounts: - - name: data - mountPath: /data - - name: media - mountPath: /mnt/Media - readOnly: true - - name: env - mountPath: /run/secrets/navidrome - readOnly: true - startupProbe: - httpGet: - path: / - port: http - periodSeconds: 10 - failureThreshold: 60 - livenessProbe: - httpGet: - path: / - port: http - periodSeconds: 30 - readinessProbe: - httpGet: - path: / - port: http - periodSeconds: 10 - failureThreshold: 3 - volumes: - - name: data - persistentVolumeClaim: - claimName: navidrome-data - - name: media - persistentVolumeClaim: - claimName: navidrome-media - readOnly: true - - name: env - secret: - secretName: navidrome-env diff --git a/k8s/charts/navidrome/templates/ingress.yaml b/k8s/charts/navidrome/templates/ingress.yaml deleted file mode 100644 index 94b4fe50..00000000 --- a/k8s/charts/navidrome/templates/ingress.yaml +++ /dev/null @@ -1,51 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: navidrome - labels: - app: navidrome - annotations: - traefik.ingress.kubernetes.io/router.middlewares: identity-forward-auth-navidrome@kubernetescrd -spec: - ingressClassName: traefik - tls: - - hosts: - - "navidrome.cute.haus" - secretName: cute-haus-tls - rules: - - host: "navidrome.cute.haus" - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: navidrome - port: - number: 80 ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: navidrome-rest - labels: - app: navidrome - annotations: - traefik.ingress.kubernetes.io/router.middlewares: {{ .Release.Namespace }}-navidrome-drop-auth-header@kubernetescrd -spec: - ingressClassName: traefik - tls: - - hosts: - - "navidrome.cute.haus" - secretName: cute-haus-tls - rules: - - host: "navidrome.cute.haus" - http: - paths: - - path: /rest/ - pathType: Prefix - backend: - service: - name: navidrome - port: - number: 80 diff --git a/k8s/charts/navidrome/templates/middleware.yaml b/k8s/charts/navidrome/templates/middleware.yaml deleted file mode 100644 index ff63de7d..00000000 --- a/k8s/charts/navidrome/templates/middleware.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: traefik.io/v1alpha1 -kind: Middleware -metadata: - name: navidrome-drop-auth-header - labels: - app: navidrome -spec: - headers: - customRequestHeaders: - X-Forwarded-User: "" diff --git a/k8s/charts/navidrome/templates/pvc.yaml b/k8s/charts/navidrome/templates/pvc.yaml deleted file mode 100644 index b6c4252b..00000000 --- a/k8s/charts/navidrome/templates/pvc.yaml +++ /dev/null @@ -1,57 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: navidrome-data - labels: - app: navidrome - annotations: - helm.sh/resource-policy: keep -spec: - accessModes: - - ReadWriteOnce - storageClassName: longhorn - resources: - requests: - storage: 10Gi ---- -apiVersion: v1 -kind: PersistentVolume -metadata: - name: navidrome-media - labels: - app: navidrome -spec: - capacity: - storage: 1Ti - accessModes: - - ReadOnlyMany - persistentVolumeReclaimPolicy: Retain - storageClassName: "" - mountOptions: - - nfsvers=3 - - hard - - rsize=1048576 - - wsize=1048576 - - noatime - - nodiratime - nfs: - server: 100.81.61.31 - path: /mnt/Media - readOnly: true ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: navidrome-media - labels: - app: navidrome - annotations: - helm.sh/resource-policy: keep -spec: - accessModes: - - ReadOnlyMany - storageClassName: "" - volumeName: navidrome-media - resources: - requests: - storage: 1Ti diff --git a/k8s/charts/navidrome/templates/service.yaml b/k8s/charts/navidrome/templates/service.yaml deleted file mode 100644 index 582f7228..00000000 --- a/k8s/charts/navidrome/templates/service.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: navidrome - labels: - app: navidrome -spec: - type: ClusterIP - selector: - app: navidrome - ports: - - name: http - port: 80 - targetPort: 4533 diff --git a/k8s/charts/pg-shared/Chart.yaml b/k8s/charts/pg-shared/Chart.yaml deleted file mode 100644 index 661ce60e..00000000 --- a/k8s/charts/pg-shared/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v2 -name: pg-shared -description: Shared CNPG postgres cluster (operator-managed) -type: application -version: 0.1.0 diff --git a/k8s/charts/pg-shared/templates/cluster.yaml b/k8s/charts/pg-shared/templates/cluster.yaml deleted file mode 100644 index d43a2065..00000000 --- a/k8s/charts/pg-shared/templates/cluster.yaml +++ /dev/null @@ -1,87 +0,0 @@ -apiVersion: postgresql.cnpg.io/v1 -kind: Cluster -metadata: - name: {{ .Values.cluster.name }} -spec: - instances: {{ .Values.cluster.instances }} - imageName: {{ .Values.cluster.imageName }} - - storage: - storageClass: {{ .Values.cluster.storage.storageClass }} - size: {{ .Values.cluster.storage.size }} - - resources: - {{- toYaml .Values.cluster.resources | nindent 4 }} - - affinity: - enablePodAntiAffinity: true - podAntiAffinityType: required - topologyKey: {{ .Values.cluster.topologyKey }} - # Soft preference: cloud providers (100) > home (50, default). - nodeAffinity: - preferredDuringSchedulingIgnoredDuringExecution: - - weight: 100 - preference: - matchExpressions: - - key: topology.kubernetes.io/zone - operator: In - values: [cloud] - - weight: 50 - preference: - matchExpressions: - - key: topology.kubernetes.io/zone - operator: In - values: [home] - tolerations: - - key: node.kubernetes.io/not-ready - operator: Exists - effect: NoExecute - tolerationSeconds: {{ $.Values.global.failover.fastTolerationSeconds | default 60 }} - - key: node.kubernetes.io/unreachable - operator: Exists - effect: NoExecute - tolerationSeconds: {{ $.Values.global.failover.fastTolerationSeconds | default 60 }} - - topologySpreadConstraints: - - maxSkew: 1 - topologyKey: topology.kubernetes.io/zone - whenUnsatisfiable: ScheduleAnyway - labelSelector: - matchLabels: - cnpg.io/cluster: {{ .Values.cluster.name }} - - postgresql: - {{- toYaml .Values.postgresql | nindent 4 }} - - monitoring: - enablePodMonitor: false - - {{- with .Values.roles }} - managed: - roles: - {{- range $name, $role := . }} - {{- $ensure := $role.ensure | default "present" }} - - name: {{ $name }} - ensure: {{ $ensure }} - {{- if ne $ensure "absent" }} - login: true - passwordSecret: - name: {{ $name }}-pg-creds - {{- end }} - {{- end }} - {{- end }} - - {{- if .Values.backup.enabled }} - backup: - barmanObjectStore: - destinationPath: {{ .Values.backup.destinationPath }} - endpointURL: {{ .Values.backup.endpointURL }} - s3Credentials: - accessKeyId: - name: {{ .Values.cluster.name }}-b2 - key: KEY_ID - secretAccessKey: - name: {{ .Values.cluster.name }}-b2 - key: APP_KEY - retentionPolicy: {{ .Values.backup.retentionPolicy | quote }} - {{- end }} diff --git a/k8s/charts/pg-shared/templates/databases.yaml b/k8s/charts/pg-shared/templates/databases.yaml deleted file mode 100644 index 622a9dd7..00000000 --- a/k8s/charts/pg-shared/templates/databases.yaml +++ /dev/null @@ -1,14 +0,0 @@ -{{- range $name, $role := .Values.roles }} -{{- $db := $role.database | default $name }} ---- -apiVersion: postgresql.cnpg.io/v1 -kind: Database -metadata: - name: {{ $db }} -spec: - name: {{ $db }} - owner: {{ $name }} - ensure: {{ $role.ensure | default "present" }} - cluster: - name: {{ $.Values.cluster.name }} -{{- end }} diff --git a/k8s/charts/pg-shared/templates/scheduled-backup.yaml b/k8s/charts/pg-shared/templates/scheduled-backup.yaml deleted file mode 100644 index db9eb416..00000000 --- a/k8s/charts/pg-shared/templates/scheduled-backup.yaml +++ /dev/null @@ -1,11 +0,0 @@ -{{- if .Values.backup.enabled }} -apiVersion: postgresql.cnpg.io/v1 -kind: ScheduledBackup -metadata: - name: {{ .Values.cluster.name }}-daily -spec: - schedule: "{{ .Values.backup.schedule }}" - cluster: - name: {{ .Values.cluster.name }} - backupOwnerReference: self -{{- end }} diff --git a/k8s/charts/pg-shared/values.schema.json b/k8s/charts/pg-shared/values.schema.json deleted file mode 100644 index b92efdc2..00000000 --- a/k8s/charts/pg-shared/values.schema.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "type": "object", - "required": ["cluster", "roles", "backup"], - "properties": { - "cluster": { - "type": "object", - "required": ["name", "instances", "storage"], - "properties": { - "name": { "type": "string", "minLength": 1 }, - "instances": { "type": "integer", "minimum": 1 }, - "storage": { - "type": "object", - "required": ["storageClass", "size"], - "properties": { - "storageClass": { "type": "string", "minLength": 1 }, - "size": { "type": "string", "minLength": 1 } - }, - "additionalProperties": true - } - }, - "additionalProperties": true - }, - "roles": { "type": "object", "additionalProperties": { "type": "object" } }, - "backup": { - "type": "object", - "required": ["enabled"], - "properties": { "enabled": { "type": "boolean" } }, - "additionalProperties": true - } - }, - "additionalProperties": true -} diff --git a/k8s/charts/pg-shared/values.yaml b/k8s/charts/pg-shared/values.yaml deleted file mode 100644 index 1196146a..00000000 --- a/k8s/charts/pg-shared/values.yaml +++ /dev/null @@ -1,50 +0,0 @@ -cluster: - name: pg-shared - instances: 3 - imageName: ghcr.io/cloudnative-pg/postgresql:18.6@sha256:d7a81cb5da3182d95d0da5fabfb9e484e375db899dcd54b684105f1e8966e9ca - postgresVersion: 17 - - # local-path: node-local SSD for low-latency fsync. CNPG handles HA via - # streaming replication across instances; replicated block storage - # underneath is double-paying for HA at the cost of write latency. - storage: - storageClass: local-path - size: 5Gi - - resources: - requests: - cpu: 200m - memory: 1Gi - limits: - cpu: "3" - memory: 3Gi - - # Spread instances across control-plane nodes - topologyKey: kubernetes.io/hostname - -# Tuned for a small shared cluster; bump if individual apps need more -# connections or heavier analytical workloads. -postgresql: - parameters: - max_connections: "200" - shared_buffers: 1GB - effective_cache_size: 2GB - work_mem: 16MB - maintenance_work_mem: 128MB - random_page_cost: "1.1" - effective_io_concurrency: "200" - -# Declarative CNPG roles + databases. Password Secrets are first-class SOPS -# manifests under k8s/flux/secrets and are referenced by roles that are present. -# Set ensure: absent temporarily to delete a database and its role explicitly. -roles: {} - -# B2 backup target for CNPG base backups + WAL archiving. -# Credentials come from the first-class pg-shared-b2 Secret. -backup: - enabled: false - destinationPath: s3://aly-backups/cute.haus/cnpg - endpointURL: https://s3.us-east-005.backblazeb2.com - # Quartz cron (6 fields: sec min hour dom mon dow). Daily at 04:00 UTC. - schedule: "0 0 4 * * *" - retentionPolicy: "30d" diff --git a/k8s/drafts/README.md b/k8s/drafts/README.md deleted file mode 100644 index 23cb4f0a..00000000 --- a/k8s/drafts/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Draft charts - -These charts are deliberately not reconciled by Flux. They are retained as -work-in-progress manifests, not deployable production state. Move a chart back -to `k8s/charts/` and add exactly one HelmRelease before deploying it. - -- `audiobookshelf` -- `forgejo` -- `jellyfin` diff --git a/k8s/drafts/audiobookshelf/Chart.yaml b/k8s/drafts/audiobookshelf/Chart.yaml deleted file mode 100644 index bf46d03e..00000000 --- a/k8s/drafts/audiobookshelf/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v2 -name: audiobookshelf -description: Audiobookshelf with an rclone B2 sidecar for media -type: application -version: 0.1.0 diff --git a/k8s/drafts/audiobookshelf/templates/deployment.yaml b/k8s/drafts/audiobookshelf/templates/deployment.yaml deleted file mode 100644 index 067cdb5d..00000000 --- a/k8s/drafts/audiobookshelf/templates/deployment.yaml +++ /dev/null @@ -1,118 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Chart.Name }} - labels: - app: {{ .Chart.Name }} -spec: - replicas: 1 - strategy: - type: Recreate - selector: - matchLabels: - app: {{ .Chart.Name }} - template: - metadata: - labels: - app: {{ .Chart.Name }} - spec: - automountServiceAccountToken: false - enableServiceLinks: false - terminationGracePeriodSeconds: 30 - securityContext: - seccompProfile: - type: RuntimeDefault - tolerations: - - key: node.kubernetes.io/not-ready - operator: Exists - effect: NoExecute - tolerationSeconds: {{ $.Values.global.failover.fastTolerationSeconds | default 60 }} - - key: node.kubernetes.io/unreachable - operator: Exists - effect: NoExecute - tolerationSeconds: {{ $.Values.global.failover.fastTolerationSeconds | default 60 }} - containers: - - name: {{ .Chart.Name }} - image: ghcr.io/advplyr/audiobookshelf:2.36.0@sha256:180acad33d69c99ed208676465d8edcb268fa46967735579a7810859885b1a8e - imagePullPolicy: IfNotPresent - env: - - name: TZ - value: "America/New_York" - ports: - - name: http - containerPort: 80 - resources: - requests: - cpu: 100m - memory: 256Mi - limits: - cpu: "2" - memory: 1Gi - volumeMounts: - - name: data - mountPath: /config - subPath: config - - name: data - mountPath: /metadata - subPath: metadata - - name: data - mountPath: /podcasts - subPath: podcasts - - name: rclone-media - mountPath: /audiobooks - mountPropagation: HostToContainer - startupProbe: - httpGet: - path: /healthcheck - port: http - periodSeconds: 5 - failureThreshold: 60 - livenessProbe: - httpGet: - path: /healthcheck - port: http - periodSeconds: 30 - readinessProbe: - httpGet: - path: /healthcheck - port: http - periodSeconds: 5 - failureThreshold: 3 - - name: rclone - image: {{ .Values.global.images.rclone }} - imagePullPolicy: IfNotPresent - args: - - mount - - "b2:aly-audiobooks" - - "/audiobooks" - - --allow-non-empty - - --vfs-cache-mode=full - - --vfs-cache-max-age=168h - - --vfs-cache-max-size=5G - - --transfers=4 - - --uid=99 - - --gid=100 - - --umask=022 - - --log-level=INFO - securityContext: - privileged: true - envFrom: - - secretRef: - name: audiobookshelf-rclone - resources: - requests: - cpu: 50m - memory: 128Mi - limits: - cpu: "1" - memory: 512Mi - volumeMounts: - - name: rclone-media - mountPath: /audiobooks - mountPropagation: Bidirectional - volumes: - - name: data - persistentVolumeClaim: - claimName: {{ .Chart.Name }}-data - - name: rclone-media - emptyDir: {} diff --git a/k8s/drafts/audiobookshelf/templates/ingress.yaml b/k8s/drafts/audiobookshelf/templates/ingress.yaml deleted file mode 100644 index f3b2ca57..00000000 --- a/k8s/drafts/audiobookshelf/templates/ingress.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: { { .Chart.Name } } - labels: - app: { { .Chart.Name } } -spec: - ingressClassName: traefik - tls: - - hosts: - - "audiobookshelf.cute.haus" - secretName: cute-haus-tls - rules: - - host: "audiobookshelf.cute.haus" - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: { { .Chart.Name } } - port: - number: 80 diff --git a/k8s/drafts/audiobookshelf/templates/pvc.yaml b/k8s/drafts/audiobookshelf/templates/pvc.yaml deleted file mode 100644 index 421b09e5..00000000 --- a/k8s/drafts/audiobookshelf/templates/pvc.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: {{ .Chart.Name }}-data - labels: - app: {{ .Chart.Name }} - annotations: - helm.sh/resource-policy: keep -spec: - accessModes: - - ReadWriteOnce - storageClassName: longhorn - resources: - requests: - storage: 30Gi diff --git a/k8s/drafts/audiobookshelf/templates/service.yaml b/k8s/drafts/audiobookshelf/templates/service.yaml deleted file mode 100644 index c68a5eab..00000000 --- a/k8s/drafts/audiobookshelf/templates/service.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: { { .Chart.Name } } - labels: - app: { { .Chart.Name } } -spec: - type: ClusterIP - selector: - app: { { .Chart.Name } } - ports: - - name: http - port: 80 - targetPort: 80 diff --git a/k8s/drafts/forgejo/Chart.yaml b/k8s/drafts/forgejo/Chart.yaml deleted file mode 100644 index eb7760e0..00000000 --- a/k8s/drafts/forgejo/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v2 -name: forgejo -description: Forgejo (gitea fork) — git hosting -type: application -version: 0.1.0 diff --git a/k8s/drafts/forgejo/templates/deployment.yaml b/k8s/drafts/forgejo/templates/deployment.yaml deleted file mode 100644 index fb037c00..00000000 --- a/k8s/drafts/forgejo/templates/deployment.yaml +++ /dev/null @@ -1,120 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Chart.Name }} - labels: - app: {{ .Chart.Name }} -spec: - replicas: 1 - strategy: - type: Recreate - selector: - matchLabels: - app: {{ .Chart.Name }} - template: - metadata: - labels: - app: {{ .Chart.Name }} - spec: - automountServiceAccountToken: false - enableServiceLinks: false - terminationGracePeriodSeconds: 15 - securityContext: - fsGroup: 1000 - seccompProfile: - type: RuntimeDefault - tolerations: - - key: node.kubernetes.io/not-ready - operator: Exists - effect: NoExecute - tolerationSeconds: {{ $.Values.global.failover.fastTolerationSeconds | default 60 }} - - key: node.kubernetes.io/unreachable - operator: Exists - effect: NoExecute - tolerationSeconds: {{ $.Values.global.failover.fastTolerationSeconds | default 60 }} - containers: - - name: {{ .Chart.Name }} - image: data.forgejo.org/forgejo/forgejo:16.0.2@sha256:2fdfe28b5c68f82f49580e227b84e2afb43af0250e0631a54a386ef3b1d9b759 - imagePullPolicy: IfNotPresent - env: - - name: FORGEJO_CUSTOM - value: "/var/lib/forgejo/custom" - - name: FORGEJO_WORK_DIR - value: "/var/lib/forgejo" - - name: FORGEJO__cache__ADAPTER - value: "redis" - - name: FORGEJO__cache__ENABLED - value: "true" - - name: FORGEJO__cache__HOST - value: "redis://valkey.default.svc:6379/1" - - name: FORGEJO__database__DB_TYPE - value: "postgres" - - name: FORGEJO__database__HOST - value: "pg-shared-rw.cnpg-system.svc:5432" - - name: FORGEJO__database__NAME - value: "forgejo" - - name: FORGEJO__database__USER - value: "forgejo" - - name: FORGEJO__log__LOGGER_SSH_MODE - value: "file" - - name: FORGEJO__oauth2_client__ACCOUNT_LINKING - value: "login" - - name: FORGEJO__oauth2_client__ENABLE_AUTO_REGISTRATION - value: "true" - - name: FORGEJO__queue__CONN_STR - value: "redis://valkey.default.svc:6379/3" - - name: FORGEJO__queue__TYPE - value: "redis" - - name: FORGEJO__repository__ENABLE_PUSH_CREATE_ORG - value: "true" - - name: FORGEJO__repository__ENABLE_PUSH_CREATE_USER - value: "true" - - name: FORGEJO__session__PROVIDER - value: "redis" - - name: FORGEJO__session__PROVIDER_CONFIG - value: "redis://valkey.default.svc:6379/2" - - name: USER_GID - value: "1000" - - name: USER_UID - value: "1000" - envFrom: - - secretRef: - name: forgejo-env - ports: - - name: http - containerPort: 3001 - - name: ssh - containerPort: 2222 - resources: - requests: - cpu: 100m - memory: 512Mi - limits: - cpu: "2" - memory: 4Gi - volumeMounts: - - name: data - mountPath: /var/lib/forgejo - startupProbe: - httpGet: - path: /api/healthz - port: http - periodSeconds: 10 - failureThreshold: 30 - livenessProbe: - httpGet: - path: /api/healthz - port: http - periodSeconds: 60 - timeoutSeconds: 15 - readinessProbe: - httpGet: - path: /api/healthz - port: http - periodSeconds: 10 - timeoutSeconds: 10 - failureThreshold: 2 - volumes: - - name: data - persistentVolumeClaim: - claimName: {{ .Chart.Name }}-data diff --git a/k8s/drafts/forgejo/templates/ingress.yaml b/k8s/drafts/forgejo/templates/ingress.yaml deleted file mode 100644 index fda4dcda..00000000 --- a/k8s/drafts/forgejo/templates/ingress.yaml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: {{ .Chart.Name }} - labels: - app: {{ .Chart.Name }} - annotations: - traefik.ingress.kubernetes.io/router.middlewares: {{ .Release.Namespace }}-{{ .Chart.Name }}-ratelimit@kubernetescrd -spec: - ingressClassName: traefik - tls: - - hosts: - - "git.aly.codes" - secretName: aly-codes-tls - rules: - - host: "git.aly.codes" - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: {{ .Chart.Name }} - port: - number: 80 diff --git a/k8s/drafts/forgejo/templates/ingressroute-ssh.yaml b/k8s/drafts/forgejo/templates/ingressroute-ssh.yaml deleted file mode 100644 index 4feefe93..00000000 --- a/k8s/drafts/forgejo/templates/ingressroute-ssh.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: traefik.io/v1alpha1 -kind: IngressRouteTCP -metadata: - name: {{ .Chart.Name }}-ssh - labels: - app: {{ .Chart.Name }} -spec: - entryPoints: - - ssh - routes: - - match: HostSNI(`*`) - services: - - name: {{ .Chart.Name }} - port: 2222 diff --git a/k8s/drafts/forgejo/templates/middleware.yaml b/k8s/drafts/forgejo/templates/middleware.yaml deleted file mode 100644 index 17c5abde..00000000 --- a/k8s/drafts/forgejo/templates/middleware.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: traefik.io/v1alpha1 -kind: Middleware -metadata: - name: {{ .Chart.Name }}-ratelimit - labels: - app: {{ .Chart.Name }} -spec: - # Crawlers (esp. AI scrapers) hammer repo browse/commit/blame pages, each of - # which forks git subprocesses — concurrency spikes memory and OOM-kills the - # pod. Cap the request rate per real client. Behind Cloudflare, Traefik only - # sees CF edge IPs, so key on the Cf-Connecting-Ip header instead. - rateLimit: - average: 30 - burst: 60 - period: 1s - sourceCriterion: - requestHeaderName: Cf-Connecting-Ip diff --git a/k8s/drafts/forgejo/templates/pvc.yaml b/k8s/drafts/forgejo/templates/pvc.yaml deleted file mode 100644 index c5b4df72..00000000 --- a/k8s/drafts/forgejo/templates/pvc.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: {{ .Chart.Name }}-data - labels: - app: {{ .Chart.Name }} - annotations: - helm.sh/resource-policy: keep -spec: - accessModes: - - ReadWriteOnce - storageClassName: longhorn - resources: - requests: - storage: 10Gi diff --git a/k8s/drafts/forgejo/templates/service.yaml b/k8s/drafts/forgejo/templates/service.yaml deleted file mode 100644 index a60969a6..00000000 --- a/k8s/drafts/forgejo/templates/service.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: { { .Chart.Name } } - labels: - app: { { .Chart.Name } } -spec: - type: ClusterIP - selector: - app: { { .Chart.Name } } - ports: - - name: http - port: 80 - targetPort: http - - name: ssh - port: 2222 - targetPort: ssh diff --git a/k8s/drafts/jellyfin/Chart.yaml b/k8s/drafts/jellyfin/Chart.yaml deleted file mode 100644 index 394c34d5..00000000 --- a/k8s/drafts/jellyfin/Chart.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v2 -name: jellyfin -description: Jellyfin media server -type: application -version: 0.1.0 diff --git a/k8s/drafts/jellyfin/templates/deployment.yaml b/k8s/drafts/jellyfin/templates/deployment.yaml deleted file mode 100644 index 5c0e7684..00000000 --- a/k8s/drafts/jellyfin/templates/deployment.yaml +++ /dev/null @@ -1,93 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ .Chart.Name }} - labels: - app: {{ .Chart.Name }} -spec: - replicas: 1 - strategy: - type: Recreate - selector: - matchLabels: - app: {{ .Chart.Name }} - template: - metadata: - labels: - app: {{ .Chart.Name }} - spec: - automountServiceAccountToken: false - enableServiceLinks: false - terminationGracePeriodSeconds: 30 - securityContext: - seccompProfile: - type: RuntimeDefault - tolerations: - - key: node.kubernetes.io/not-ready - operator: Exists - effect: NoExecute - tolerationSeconds: {{ $.Values.global.failover.fastTolerationSeconds | default 60 }} - - key: node.kubernetes.io/unreachable - operator: Exists - effect: NoExecute - tolerationSeconds: {{ $.Values.global.failover.fastTolerationSeconds | default 60 }} - nodeSelector: - kubernetes.io/hostname: jubilife - containers: - - name: {{ .Chart.Name }} - image: docker.io/jellyfin/jellyfin:10.11.11@sha256:aefb67e6a7ff1debdd154a78a7bbb780fd0c873d8639210a7f6a2016ad2b35db - imagePullPolicy: IfNotPresent - env: - - name: TZ - value: "America/New_York" - ports: - - name: http - containerPort: 8096 - resources: - requests: - cpu: 200m - memory: 512Mi - gpu.intel.com/i915: "1" - limits: - cpu: "4" - memory: 4Gi - gpu.intel.com/i915: "1" - volumeMounts: - - name: config - mountPath: /config - - name: media - mountPath: /mnt/Media - readOnly: true - - name: backblaze - mountPath: /mnt/Backblaze - readOnly: true - mountPropagation: HostToContainer - startupProbe: - httpGet: - path: /health - port: http - periodSeconds: 10 - failureThreshold: 30 - livenessProbe: - httpGet: - path: /health - port: http - periodSeconds: 30 - readinessProbe: - httpGet: - path: /health - port: http - periodSeconds: 10 - failureThreshold: 3 - volumes: - - name: config - persistentVolumeClaim: - claimName: {{ .Chart.Name }}-config - - name: media - persistentVolumeClaim: - claimName: {{ .Chart.Name }}-media - readOnly: true - - name: backblaze - hostPath: - path: /mnt/Backblaze - type: Directory diff --git a/k8s/drafts/jellyfin/templates/ingress.yaml b/k8s/drafts/jellyfin/templates/ingress.yaml deleted file mode 100644 index e7eb203c..00000000 --- a/k8s/drafts/jellyfin/templates/ingress.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: { { .Chart.Name } } - labels: - app: { { .Chart.Name } } -spec: - ingressClassName: traefik - tls: - - hosts: - - "jellyfin.cute.haus" - secretName: cute-haus-tls - rules: - - host: "jellyfin.cute.haus" - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: { { .Chart.Name } } - port: - number: 80 diff --git a/k8s/drafts/jellyfin/templates/pvc.yaml b/k8s/drafts/jellyfin/templates/pvc.yaml deleted file mode 100644 index 61c20bea..00000000 --- a/k8s/drafts/jellyfin/templates/pvc.yaml +++ /dev/null @@ -1,83 +0,0 @@ -apiVersion: v1 -kind: PersistentVolume -metadata: - name: {{ .Chart.Name }}-config - labels: - app: {{ .Chart.Name }} -spec: - capacity: - storage: 10Gi - accessModes: - - ReadWriteOnce - persistentVolumeReclaimPolicy: Retain - storageClassName: "" - nodeAffinity: - required: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/hostname - operator: In - values: - - jubilife - hostPath: - path: /mnt/Data/jellyfin - type: Directory ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: {{ .Chart.Name }}-config - labels: - app: {{ .Chart.Name }} - annotations: - helm.sh/resource-policy: keep -spec: - accessModes: - - ReadWriteOnce - storageClassName: "" - volumeName: {{ .Chart.Name }}-config - resources: - requests: - storage: 10Gi ---- -apiVersion: v1 -kind: PersistentVolume -metadata: - name: {{ .Chart.Name }}-media - labels: - app: {{ .Chart.Name }} -spec: - capacity: - storage: 14Ti - accessModes: - - ReadOnlyMany - persistentVolumeReclaimPolicy: Retain - storageClassName: "" - nodeAffinity: - required: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/hostname - operator: In - values: - - jubilife - hostPath: - path: /mnt/Media - type: Directory ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: {{ .Chart.Name }}-media - labels: - app: {{ .Chart.Name }} - annotations: - helm.sh/resource-policy: keep -spec: - accessModes: - - ReadOnlyMany - storageClassName: "" - volumeName: {{ .Chart.Name }}-media - resources: - requests: - storage: 14Ti diff --git a/k8s/drafts/jellyfin/templates/service.yaml b/k8s/drafts/jellyfin/templates/service.yaml deleted file mode 100644 index e44fcd47..00000000 --- a/k8s/drafts/jellyfin/templates/service.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: { { .Chart.Name } } - labels: - app: { { .Chart.Name } } -spec: - type: ClusterIP - selector: - app: { { .Chart.Name } } - ports: - - name: http - port: 80 - targetPort: 8096 diff --git a/k8s/flux/apps/error-pages/deployment.yaml b/k8s/flux/apps/error-pages/deployment.yaml deleted file mode 100644 index 3add5f61..00000000 --- a/k8s/flux/apps/error-pages/deployment.yaml +++ /dev/null @@ -1,63 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: error-pages - labels: - app: error-pages -spec: - replicas: 1 - selector: - matchLabels: - app: error-pages - template: - metadata: - labels: - app: error-pages - spec: - automountServiceAccountToken: false - enableServiceLinks: false - securityContext: - seccompProfile: - type: RuntimeDefault - tolerations: - - key: node.kubernetes.io/not-ready - operator: Exists - effect: NoExecute - tolerationSeconds: 60 - - key: node.kubernetes.io/unreachable - operator: Exists - effect: NoExecute - tolerationSeconds: 60 - containers: - - name: error-pages - image: ghcr.io/tarampampam/error-pages:4@sha256:f23f8042a2804669315fd232281d0ccecf1959332314a46e02ca2482064064a6 - imagePullPolicy: IfNotPresent - env: - - name: TEMPLATE_NAME - value: "app-down" - ports: - - name: http - containerPort: 8080 - resources: - requests: - cpu: 5m - memory: 16Mi - limits: - cpu: 100m - memory: 32Mi - startupProbe: - httpGet: - path: /healthz - port: http - periodSeconds: 5 - failureThreshold: 30 - livenessProbe: - httpGet: - path: /healthz - port: http - periodSeconds: 30 - readinessProbe: - httpGet: - path: /healthz - port: http - periodSeconds: 10 diff --git a/k8s/flux/apps/error-pages/kustomization.yaml b/k8s/flux/apps/error-pages/kustomization.yaml deleted file mode 100644 index d4001524..00000000 --- a/k8s/flux/apps/error-pages/kustomization.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -namespace: default -resources: - - deployment.yaml - - middleware.yaml - - service.yaml diff --git a/k8s/flux/apps/error-pages/middleware.yaml b/k8s/flux/apps/error-pages/middleware.yaml deleted file mode 100644 index 09f42b9d..00000000 --- a/k8s/flux/apps/error-pages/middleware.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: traefik.io/v1alpha1 -kind: Middleware -metadata: - name: error-pages -spec: - errors: - status: - - "500-599" - service: - name: error-pages - port: 80 - query: "/{status}.html" diff --git a/k8s/flux/apps/error-pages/service.yaml b/k8s/flux/apps/error-pages/service.yaml deleted file mode 100644 index 04f02f33..00000000 --- a/k8s/flux/apps/error-pages/service.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: error-pages - labels: - app: error-pages -spec: - type: ClusterIP - selector: - app: error-pages - ports: - - name: http - port: 80 - targetPort: 8080 diff --git a/k8s/flux/apps/forward-auth.yaml b/k8s/flux/apps/forward-auth.yaml deleted file mode 100644 index 84f1e209..00000000 --- a/k8s/flux/apps/forward-auth.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: forward-auth - namespace: flux-system -spec: - interval: 15m - releaseName: forward-auth - targetNamespace: identity - install: { remediation: { retries: 3 } } - upgrade: { remediation: { retries: 3 } } - chart: - spec: - chart: ./k8s/charts/forward-auth - interval: 15m - reconcileStrategy: Revision - sourceRef: - { kind: GitRepository, name: flux-system, namespace: flux-system } - valuesFrom: - - { kind: ConfigMap, name: cute-haus-global, valuesKey: values.yaml } - values: - apps: - navidrome: {} diff --git a/k8s/flux/apps/kustomization.yaml b/k8s/flux/apps/kustomization.yaml deleted file mode 100644 index b44f5462..00000000 --- a/k8s/flux/apps/kustomization.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - error-pages - - forward-auth.yaml - - navidrome.yaml diff --git a/k8s/flux/apps/navidrome.yaml b/k8s/flux/apps/navidrome.yaml deleted file mode 100644 index a53eb094..00000000 --- a/k8s/flux/apps/navidrome.yaml +++ /dev/null @@ -1,22 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: navidrome - namespace: flux-system -spec: - dependsOn: - - name: forward-auth - interval: 15m - releaseName: navidrome - targetNamespace: default - install: { remediation: { retries: 3 } } - upgrade: { remediation: { retries: 3 } } - chart: - spec: - chart: ./k8s/charts/navidrome - interval: 15m - reconcileStrategy: Revision - sourceRef: - { kind: GitRepository, name: flux-system, namespace: flux-system } - valuesFrom: - - { kind: ConfigMap, name: cute-haus-global, valuesKey: values.yaml } diff --git a/k8s/flux/external-routes/external-routes.yaml b/k8s/flux/external-routes/external-routes.yaml deleted file mode 100644 index 3760ca1e..00000000 --- a/k8s/flux/external-routes/external-routes.yaml +++ /dev/null @@ -1,72 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: external-routes - namespace: flux-system -spec: - interval: 15m - releaseName: external-routes - targetNamespace: default - install: - remediation: - retries: 3 - upgrade: - remediation: - retries: 3 - chart: - spec: - chart: ./k8s/charts/external-routes - interval: 15m - reconcileStrategy: Revision - sourceRef: - kind: GitRepository - name: flux-system - namespace: flux-system - valuesFrom: - - kind: ConfigMap - name: cute-haus-global - valuesKey: values.yaml - values: - routes: - - name: plex - host: plex.cute.haus - target: - ip: 10.254.0.1 - port: 32400 - tls: - secretName: cute-haus-tls - - name: immich - host: immich.cute.haus - target: - ip: 10.254.0.1 - port: 2283 - tls: - secretName: cute-haus-tls - - name: nextcloud - host: nextcloud.cute.haus - target: - ip: 10.254.0.1 - port: 8081 - tls: - secretName: cute-haus-tls - - name: collabora - host: collabora.cute.haus - target: - ip: 10.254.0.1 - port: 9980 - tls: - secretName: cute-haus-tls - - name: paperless - host: paperless.cute.haus - target: - ip: 10.254.0.1 - port: 8001 - tls: - secretName: cute-haus-tls - - name: slingshot - host: slingshot.cute.haus - target: - ip: 10.254.0.1 - port: 8765 - tls: - secretName: cute-haus-tls diff --git a/k8s/flux/external-routes/kustomization.yaml b/k8s/flux/external-routes/kustomization.yaml deleted file mode 100644 index 0e14160d..00000000 --- a/k8s/flux/external-routes/kustomization.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - external-routes.yaml diff --git a/k8s/flux/infra-core/cert-manager-issuers.yaml b/k8s/flux/infra-core/cert-manager-issuers.yaml deleted file mode 100644 index fea392db..00000000 --- a/k8s/flux/infra-core/cert-manager-issuers.yaml +++ /dev/null @@ -1,30 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: cert-manager-issuers - namespace: flux-system -spec: - dependsOn: - - name: cert-manager - interval: 15m - releaseName: cert-manager-issuers - targetNamespace: cert-manager - install: - remediation: - retries: 3 - upgrade: - remediation: - retries: 3 - chart: - spec: - chart: ./k8s/charts/cert-manager-issuers - interval: 15m - reconcileStrategy: Revision - sourceRef: - kind: GitRepository - name: flux-system - namespace: flux-system - valuesFrom: - - kind: ConfigMap - name: cute-haus-global - valuesKey: values.yaml diff --git a/k8s/flux/infra-core/intel-device-plugins-operator.yaml b/k8s/flux/infra-core/intel-device-plugins-operator.yaml deleted file mode 100644 index d27e7183..00000000 --- a/k8s/flux/infra-core/intel-device-plugins-operator.yaml +++ /dev/null @@ -1,27 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: intel-device-plugins-operator - namespace: flux-system -spec: - dependsOn: - - name: node-feature-discovery - interval: 15m - releaseName: intel-device-plugins-operator - targetNamespace: intel-device-plugin - install: - createNamespace: true - remediation: - retries: 3 - upgrade: - remediation: - retries: 3 - chart: - spec: - chart: intel-device-plugins-operator - interval: 15m - sourceRef: - kind: HelmRepository - name: intel - namespace: flux-system - version: 0.36.0 diff --git a/k8s/flux/infra-core/intel-gpu-plugin.yaml b/k8s/flux/infra-core/intel-gpu-plugin.yaml deleted file mode 100644 index c9868597..00000000 --- a/k8s/flux/infra-core/intel-gpu-plugin.yaml +++ /dev/null @@ -1,28 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: intel-gpu-plugin - namespace: flux-system -spec: - dependsOn: - - name: intel-device-plugins-operator - interval: 15m - releaseName: intel-gpu-plugin - targetNamespace: intel-device-plugin - install: - remediation: - retries: 3 - upgrade: - remediation: - retries: 3 - chart: - spec: - chart: intel-device-plugins-gpu - interval: 15m - sourceRef: - kind: HelmRepository - name: intel - namespace: flux-system - version: 0.36.0 - values: - sharedDevNum: 4 diff --git a/k8s/flux/infra-core/kustomization.yaml b/k8s/flux/infra-core/kustomization.yaml deleted file mode 100644 index f8cd299a..00000000 --- a/k8s/flux/infra-core/kustomization.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - cert-manager-issuers.yaml - - intel-device-plugins-operator.yaml - - intel-gpu-plugin.yaml - - longhorn-creds.yaml - - longhorn.yaml - - node-feature-discovery.yaml - - reflector.yaml - - tailscale-operator.yaml - - traefik.yaml diff --git a/k8s/flux/infra-core/longhorn-creds.yaml b/k8s/flux/infra-core/longhorn-creds.yaml deleted file mode 100644 index 686750cc..00000000 --- a/k8s/flux/infra-core/longhorn-creds.yaml +++ /dev/null @@ -1,32 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: longhorn-creds - namespace: flux-system -spec: - dependsOn: - - name: longhorn - - name: tailscale-operator - interval: 15m - releaseName: longhorn-creds - targetNamespace: longhorn-system - install: - createNamespace: true - remediation: - retries: 3 - upgrade: - remediation: - retries: 3 - chart: - spec: - chart: ./k8s/charts/longhorn-creds - interval: 15m - reconcileStrategy: Revision - sourceRef: - kind: GitRepository - name: flux-system - namespace: flux-system - valuesFrom: - - kind: ConfigMap - name: cute-haus-global - valuesKey: values.yaml diff --git a/k8s/flux/infra-core/longhorn.yaml b/k8s/flux/infra-core/longhorn.yaml deleted file mode 100644 index 2bb68392..00000000 --- a/k8s/flux/infra-core/longhorn.yaml +++ /dev/null @@ -1,46 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: longhorn - namespace: flux-system -spec: - interval: 15m - releaseName: longhorn - targetNamespace: longhorn-system - install: - createNamespace: true - remediation: - retries: 3 - upgrade: - remediation: - retries: 3 - chart: - spec: - chart: longhorn - interval: 15m - sourceRef: - kind: HelmRepository - name: longhorn - namespace: flux-system - version: 1.12.0 - values: - defaultSettings: - defaultDataPath: /var/lib/longhorn - defaultReplicaCount: 2 - replicaSoftAntiAffinity: false - replicaZoneSoftAntiAffinity: false - replicaAutoBalance: least-effort - concurrentReplicaRebuildPerNodeLimit: 3 - nodeDownPodDeletionPolicy: delete-both-statefulset-and-deployment-pod - allowRecurringJobWhileVolumeDetached: true - nodeDrainPolicy: block-for-eviction - defaultBackupStore: - backupTarget: s3://aly-backups@us-east-005/cute.haus/longhorn - backupTargetCredentialSecret: longhorn-b2 - pollInterval: 300 - persistence: - defaultClass: false - defaultClassReplicaCount: 2 - defaultDataLocality: best-effort - ingress: - enabled: false diff --git a/k8s/flux/infra-core/node-feature-discovery.yaml b/k8s/flux/infra-core/node-feature-discovery.yaml deleted file mode 100644 index 2de8c6b2..00000000 --- a/k8s/flux/infra-core/node-feature-discovery.yaml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: node-feature-discovery - namespace: flux-system -spec: - interval: 15m - releaseName: node-feature-discovery - targetNamespace: node-feature-discovery - install: - createNamespace: true - remediation: - retries: 3 - upgrade: - remediation: - retries: 3 - chart: - spec: - chart: node-feature-discovery - interval: 15m - sourceRef: - kind: HelmRepository - name: nfd - namespace: flux-system - version: 0.18.3 diff --git a/k8s/flux/infra-core/reflector.yaml b/k8s/flux/infra-core/reflector.yaml deleted file mode 100644 index ea13f593..00000000 --- a/k8s/flux/infra-core/reflector.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: reflector - namespace: flux-system -spec: - interval: 15m - releaseName: reflector - targetNamespace: kube-system - install: - remediation: - retries: 3 - upgrade: - remediation: - retries: 3 - chart: - spec: - chart: reflector - interval: 15m - sourceRef: - kind: HelmRepository - name: emberstack - namespace: flux-system - version: 10.0.55 diff --git a/k8s/flux/infra-core/tailscale-operator.yaml b/k8s/flux/infra-core/tailscale-operator.yaml deleted file mode 100644 index f2a718ac..00000000 --- a/k8s/flux/infra-core/tailscale-operator.yaml +++ /dev/null @@ -1,29 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: tailscale-operator - namespace: flux-system -spec: - interval: 15m - releaseName: tailscale-operator - targetNamespace: tailscale - install: - createNamespace: true - remediation: - retries: 3 - upgrade: - remediation: - retries: 3 - chart: - spec: - chart: tailscale-operator - interval: 15m - sourceRef: - kind: HelmRepository - name: tailscale - namespace: flux-system - version: 1.98.4 - valuesFrom: - - kind: Secret - name: tailscale-operator-values - valuesKey: values.yaml diff --git a/k8s/flux/infra-core/traefik.yaml b/k8s/flux/infra-core/traefik.yaml deleted file mode 100644 index e7fc84b6..00000000 --- a/k8s/flux/infra-core/traefik.yaml +++ /dev/null @@ -1,70 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: traefik - namespace: flux-system -spec: - interval: 15m - releaseName: traefik - targetNamespace: kube-system - install: - remediation: - retries: 3 - upgrade: - remediation: - retries: 3 - chart: - spec: - chart: traefik - interval: 15m - sourceRef: - kind: HelmRepository - name: traefik - namespace: flux-system - version: 41.0.1 - values: - deployment: - kind: DaemonSet - service: - type: ClusterIP - ports: - web: - hostPort: 80 - transport: - respondingTimeouts: - readTimeout: 600s - writeTimeout: 0s - websecure: - hostPort: 443 - transport: - respondingTimeouts: - readTimeout: 600s - writeTimeout: 0s - ssh: - port: 2222 - hostPort: 2222 - expose: - default: true - exposedPort: 2222 - protocol: TCP - updateStrategy: - type: RollingUpdate - rollingUpdate: - maxUnavailable: 1 - maxSurge: 0 - additionalArguments: - - --entrypoints.web.http.middlewares=default-error-pages@kubernetescrd - - --entrypoints.websecure.http.middlewares=default-error-pages@kubernetescrd - nodeSelector: - cute.haus/ingress: "true" - tolerations: - - key: CriticalAddonsOnly - operator: Exists - - key: node-role.kubernetes.io/control-plane - operator: Exists - effect: NoSchedule - priorityClassName: system-cluster-critical - providers: - kubernetesIngress: - publishedService: - enabled: true diff --git a/k8s/flux/infra-crds/cert-manager.yaml b/k8s/flux/infra-crds/cert-manager.yaml deleted file mode 100644 index 33ee9251..00000000 --- a/k8s/flux/infra-crds/cert-manager.yaml +++ /dev/null @@ -1,28 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: cert-manager - namespace: flux-system -spec: - interval: 15m - releaseName: cert-manager - targetNamespace: cert-manager - install: - createNamespace: true - remediation: - retries: 3 - upgrade: - remediation: - retries: 3 - chart: - spec: - chart: cert-manager - interval: 15m - sourceRef: - kind: HelmRepository - name: jetstack - namespace: flux-system - version: v1.20.3 - values: - crds: - enabled: true diff --git a/k8s/flux/infra-crds/cnpg.yaml b/k8s/flux/infra-crds/cnpg.yaml deleted file mode 100644 index 8ba121c1..00000000 --- a/k8s/flux/infra-crds/cnpg.yaml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: cnpg - namespace: flux-system -spec: - interval: 15m - releaseName: cnpg - targetNamespace: cnpg-system - install: - createNamespace: true - remediation: - retries: 3 - upgrade: - remediation: - retries: 3 - chart: - spec: - chart: cloudnative-pg - interval: 15m - sourceRef: - kind: HelmRepository - name: cnpg - namespace: flux-system - version: 0.29.0 diff --git a/k8s/flux/infra-crds/kustomization.yaml b/k8s/flux/infra-crds/kustomization.yaml deleted file mode 100644 index 155e1cdb..00000000 --- a/k8s/flux/infra-crds/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - cert-manager.yaml - - cnpg.yaml diff --git a/k8s/flux/platform/kubernetes-alloy.yaml b/k8s/flux/platform/kubernetes-alloy.yaml deleted file mode 100644 index 112cd446..00000000 --- a/k8s/flux/platform/kubernetes-alloy.yaml +++ /dev/null @@ -1,95 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: kubernetes-alloy - namespace: flux-system -spec: - interval: 15m - releaseName: kubernetes-alloy - targetNamespace: monitoring - install: - createNamespace: true - remediation: - retries: 3 - upgrade: - remediation: - retries: 3 - chart: - spec: - chart: alloy - interval: 15m - sourceRef: - kind: HelmRepository - name: grafana - namespace: flux-system - version: 1.10.0 - values: - alloy: - clustering: - enabled: true - resources: - requests: - cpu: 50m - memory: 256Mi - limits: - cpu: 500m - memory: 768Mi - configMap: - content: | - discovery.kubernetes "pods" { - role = "pod" - } - - loki.relabel "pods" { - forward_to = [loki.write.default.receiver] - - rule { - source_labels = ["__meta_kubernetes_namespace"] - target_label = "namespace" - } - - rule { - source_labels = ["__meta_kubernetes_pod_name"] - target_label = "pod" - } - - rule { - source_labels = ["__meta_kubernetes_pod_container_name"] - target_label = "container" - } - - rule { - source_labels = ["__meta_kubernetes_pod_node_name"] - target_label = "node" - } - - rule { - source_labels = ["__meta_kubernetes_pod_label_app_kubernetes_io_name"] - target_label = "app" - } - - rule { - replacement = "kubernetes-pods" - target_label = "job" - } - - rule { - replacement = "cute-haus" - target_label = "cluster" - } - } - - loki.source.kubernetes "pods" { - targets = discovery.kubernetes.pods.targets - forward_to = [loki.relabel.pods.receiver] - - clustering { - enabled = true - } - } - - loki.write "default" { - endpoint { - url = "https://loki.narwhal-snapper.ts.net/loki/api/v1/push" - } - } diff --git a/k8s/flux/platform/kubernetes-prometheus.yaml b/k8s/flux/platform/kubernetes-prometheus.yaml deleted file mode 100644 index 0d3ad428..00000000 --- a/k8s/flux/platform/kubernetes-prometheus.yaml +++ /dev/null @@ -1,57 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: kubernetes-prometheus - namespace: flux-system -spec: - interval: 15m - releaseName: kubernetes-prometheus - targetNamespace: monitoring - install: - createNamespace: true - remediation: - retries: 3 - upgrade: - remediation: - retries: 3 - chart: - spec: - chart: prometheus - interval: 15m - sourceRef: - kind: HelmRepository - name: prometheus-community - namespace: flux-system - version: 29.13.1 - values: - alertmanager: - enabled: false - prometheus-pushgateway: - enabled: false - server: - global: - scrape_interval: 30s - evaluation_interval: 30s - persistentVolume: - storageClass: longhorn - size: 10Gi - retention: 3d - retentionSize: 2GB - service: - type: NodePort - nodePort: 30220 - extraScrapeConfigs: - - job_name: flux-controllers - metrics_path: /metrics - static_configs: - - targets: - - helm-controller.flux-system.svc.cluster.local:8080 - - kustomize-controller.flux-system.svc.cluster.local:8080 - - notification-controller.flux-system.svc.cluster.local:8080 - - source-controller.flux-system.svc.cluster.local:8080 - kube-state-metrics: - prometheusScrape: true - prometheus-node-exporter: - prometheus: - monitor: - enabled: false diff --git a/k8s/flux/platform/kustomization.yaml b/k8s/flux/platform/kustomization.yaml deleted file mode 100644 index fd9b79d3..00000000 --- a/k8s/flux/platform/kustomization.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - kubernetes-alloy.yaml - - kubernetes-prometheus.yaml - - pg-shared.yaml diff --git a/k8s/flux/platform/pg-shared.yaml b/k8s/flux/platform/pg-shared.yaml deleted file mode 100644 index a507405d..00000000 --- a/k8s/flux/platform/pg-shared.yaml +++ /dev/null @@ -1,36 +0,0 @@ -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: pg-shared - namespace: flux-system -spec: - interval: 15m - releaseName: pg-shared - targetNamespace: cnpg-system - install: - remediation: - retries: 3 - upgrade: - remediation: - retries: 3 - chart: - spec: - chart: ./k8s/charts/pg-shared - interval: 15m - reconcileStrategy: Revision - sourceRef: - kind: GitRepository - name: flux-system - namespace: flux-system - valuesFrom: - - kind: ConfigMap - name: cute-haus-global - valuesKey: values.yaml - values: - backup: - enabled: true - roles: - paperless: - database: paperless - nextcloud: - database: nextcloud diff --git a/k8s/flux/secrets/README.md b/k8s/flux/secrets/README.md deleted file mode 100644 index 772be414..00000000 --- a/k8s/flux/secrets/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Flux Secrets - -First-class Kubernetes Secret manifests managed by Flux live here as -SOPS-encrypted `*.sops.yaml` files. The Flux age recipient may decrypt this -directory only; legacy `secrets/*.yaml` remain host/user-only. - -The `flux-system/sops-age` private key Secret is a bootstrap artifact. Do not -store that private key in this repository. - -This directory is reconciled as its own Flux layer before chart layers, so -first-class Secrets exist before HelmReleases that reference them. diff --git a/k8s/flux/secrets/audiobookshelf-rclone.sops.yaml b/k8s/flux/secrets/audiobookshelf-rclone.sops.yaml deleted file mode 100644 index fa419a9f..00000000 --- a/k8s/flux/secrets/audiobookshelf-rclone.sops.yaml +++ /dev/null @@ -1,123 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:5Cc=,iv:NL3ZVPhTMnkkQbT00JUZMHbPIUjeXND1nk7erlwgrSo=,tag:UDmzVL1vUTGK3mDDmWL00g==,type:str] -data: - RCLONE_CONFIG_B2_ACCOUNT: ENC[AES256_GCM,data:9qClao1kLprD11YgYhAJr8Hz/6khtNSewSL+7NoqUFKBiQK6,iv:utm1F0w6VX61njjY9TBirJAhd8gpLj+p5ZFXUQieXmk=,tag:9623zbUba0NHE81qhfKjFg==,type:str] - RCLONE_CONFIG_B2_KEY: ENC[AES256_GCM,data:PFgZ5Fcb1rPm4V5W3+Rn4A1wKxw5AsVd9llns1Yve1m/zuiBZSkrL0nLthM=,iv:zQ5n3bN95cQqMvqvF/xX7swKc8fa8rMtXY9kLz2cn0g=,tag:/GlyV6bWEHKRCwp8NKivvg==,type:str] - RCLONE_CONFIG_B2_TYPE: ENC[AES256_GCM,data:wY/ttg==,iv:/FWhaZRvjh/NERVOk6PzbyhNEn2goMnYRCqy6HUbmqs=,tag:g+tpf1nGjGwUFZSkeN0qpw==,type:str] -kind: ENC[AES256_GCM,data:tO52Wu+Z,iv:TtVXzMZC1Ihf2+heFPqwC6nUXI7TVDwhBZX8UMUe/OM=,tag:q2KzK7RDlo82qKVjCW10Qg==,type:str] -metadata: - name: ENC[AES256_GCM,data:Bjk/w3WQqGyfCLXE2FH8b/5oxTTf,iv:cCai7g81FHf+vxDGS4PGQhgdIxiofHoGC7T4c3c9Kq0=,tag:gYTA3QAJusnW4sx5/g7UoQ==,type:str] - namespace: ENC[AES256_GCM,data:HjVVny6YNA==,iv:lYhsqrHbxvmz5LXxBel8O2Yrj2eINMTcgdRQMIJ+w5k=,tag:va1tHn12V6ibwGviYH39TQ==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2dUR6Mzg2eklma2NPMHBR - VWUyRERJQVZrU1Rsb2RGZWdhNzh2cDN3SHdnCjE4Q0RaNmwwS0gvend5NXJZTmZi - eUFzY29CNWxNV1BkWDRQdEJLSjdLZk0KLS0tIExJZ2t1RjNjNVh1VVZRV2loVy8w - Rjlvck9tNVk5OHFuNDBPRXkxNE1aU1kK0F/40RRkV79qTM/AzDdXLz/IcguUJ4e+ - miXf7WExLGseVSh3v7ZtWDKlISjmyCkaqEQ9RM0RAM7mowPaoXGLYw== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiQk15QS9tOHk1NG5tOGpD - aDJpU09PU1NReS8vdjdxeVBSYWZPMTVIdlYwCmtnYXd4c1BtUUJYdU5mWkNWQVor - dk91emJGaWxoRmdGNGV2QkJJTFRiTFUKLS0tIGIvdGZUVzJtN3lkZ3Y3YW9HcWll - NlE1T2FJVkJvNkpKa3NiSURXYnVkNTQKlZ1JlYYYgyBIDZqrMK0jaQsCL+z/WzEJ - AyK9PPxdFkLo9jIZR4uXpVS1vj6lsgIpFG40AJ9keY3IvQ5EOQeYCw== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTem1NY3J2UFk5dldzSHZU - V2tHRGpjTzJSRnJkNUY3c05zVnhEWGhIdkRrCk1tK3hCVlNodXBJUjJMekNDVzhC - MnlPR1pCTE5iWitLL3hUMlV3Q3F0Nm8KLS0tIEpXRlhycENNNWhweVVJY0V0cWpP - OVN0bTcweXo3YTl2YUtnTkJJc1kwTzQK2MQWH6gDTzCLDS0rVX36Xxsqt2wKoduN - 1dpZRm96QGOhBdqct2YzZgl0qoD4OTr1p+5uqlgrj4prbYqinT8SJQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4UDB3cHlYNEhPL1JwR2pT - SEE5cjlja2FiY2RnOE9PQTc5MzZsYVhxMHdVClFVcDRWdmlXMXJVRmgrdXRBaDgy - T1JqUkRLRXcwa2pPeDRwc2hqcWpBQVUKLS0tIHVuT3VEYTJsWkMrVnJUaE5YY2pp - NnRUemY0MXNzWmwvSHJNR0VqWjBXSmMKVPUw/S+0RfbDxT4pUJpKUjJpK0UrI+pt - Fa3EVk/kB0+hmrJvqo2g4MI/RWcXfzGmFYqT+lmtlximhc6eyNWkXg== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2dDBJaVVJa3hOaTU0YldY - M0RERTduSTN3MjFHenJKODNBRHVOb0IwNWhFClpBVXZGWG5IN0IxWVdiRWxlN1Vx - VUhqb1lvaUlyNnRldkRoU3FYMm82eEEKLS0tIFV2S0c4RmxBcUFmTitUaXp4NjV0 - L3IyUnlTMVRDUkRTSUQxMzQ1UkFmRlUKYEBk3PobQfZY53UzsIKZ9BEcfD2tzMho - Mrs2npMJOKvCo+FSwTNgLTKyafvCjdZh6rNSrnXzhffg1gYPwCcxjg== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlZDFvdWUwZ05hdE92eDVD - R1VVSTA5NGlGdElHODcvZEkySjZ5bFZhSjJZCmtEN1RpZ1luQUt4Zk4xOGxPZGk4 - UkF4UWcvdjE4UzRhRUducjk3ODVQTFUKLS0tIHlVRmQ3MFNxS2RSMlY4ZnIvNk42 - a3FuUWFKbTBZaVc5YXNpc1E4N0VjREkKOPEuV2bTFwB0vXtiIFK+4RtanwpdWjKn - aTzbkjI8J+C9KgX15n/HwW4O6zT1R3YHr2Ak0FPAUY558Nu1ILYaqQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmdHc2K0JTU0lHejcxa3dz - OUVRNldMMVVITGtZMkpDSTRURGYwZkNBZUFvCkRJZmFLM0labisxQ2FmVGxlL2s1 - R0JWYnkxZi85Uk5zRzVCaWp1ZThXbDgKLS0tIEpzb2JFRTJxY00vT0lteHZxY2JJ - RG9kenBTaUlrTHpCcHM3K0trclJTNDgKY3wZ5pul9gh8sO/eYqV7q6uEoHO69/F+ - 20fEyCVAPcqlgpm4A3HtSqN3YoaWjRBWRPfFTelgVcm2yVJcABljiQ== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4TVN3U3o0SWg3VHJtQ0Fn - OUoyQWExTVV4Nnh4ZHQ4Nk80emxkMGZkb1FnCjA4MzBLdmZDQWR5SmtiWkR1amRI - Y2hoYngzV05EMElvVFZFUUo1djRsU0kKLS0tIFN6SFpKWUFLM0RKZmFURmMzRm5a - RjhIV1N6L0JaNUQ2MlVCQ2k2SzB6eWcK7ZfDvsLjuGwzjJX3Hj7xLnTQUCuL+28x - mkewS/unwrjUUhcEZU7YthnFrluferKQ0fX1KI0Szrbp1ViKgqQ4/Q== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpMjhra0tHWVk5ZHZDTjRM - aVJERC93U090bmtCMkNwaFlBakdVUUE2UlE0CmplSkxRcTIxSDhtaTd6Q3dKZDQy - TmRSK3V3cE5MbjE3c29QcUhGNk82V28KLS0tIGh6MkxqbElyblQ3V1hVZm9penpY - ZlREYUNhVnkrRnVzc0ZoTWR4YlZGd1UKoMakSijFFzJb5awMIJGzh1JJ+W+rg5Yx - Q+c2DcbpWeTTY5BYVRQpANDmuL9eqaDoYaM/5q7mBl9UpmVmfadfsA== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByMWVJL3JkSFJDNUk5ZlZw - ZzF1QWJVNmIwUDRWZllsTEE1UUU3OXRJbjFZClRyVmF5eURhc1lacGxNQXdibVk1 - bmJ5SW1WTDZhK0g2dVI5aXRtYWJsbWsKLS0tIGwzTDh3VmdxOHE2aDliMXNtd3pt - RXVKckxlMDRpTTNvRWVPMzFoMnNxalEKgoaI9FyLPTTRSJfHpjEh9LxF1lw/+Una - vrWj+2vh36iuaga70Hs8cJTeX8CJG1kHzzt9bi0DdixItiQGsHfRaw== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3Q0pGTFltcE1NaFErMFZt - NS8rQmI2MlBEbzNoUzdOVHFmYUIxK0JVYUc4CjlBcTNnRlRRQ1pFM2pwOVovWTEr - MTlKK2ZHWFp5eFMzVm4zSVRWWlVMTUkKLS0tIFlXVTF1a2lPdDNJb0pxMFpTTjFv - bEZPbkxMNGV2elI0RWpiOEFsUjBxZzgK6gyuR9dP5A19qlcezJFkCfQ/E7ZdeKcp - SmR6xV+/7hX506U00rNmdIuhCLdOv2XVh9QUszhqm7uP2kJ8m0jV9A== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBja2d1Skc3RkVzU1dNL1k4 - VmhZT1JUMVQ1ZkpramZQSEpRTkhqaEwxQUVRCmJtZ3d2TnBIVHk0Znd4bHVaeXZy - Z0RyS0l3NVRKMExkekdIeTJNcFI3SmcKLS0tIElaWVVuc0FTUmczZjdmZDlSbWly - YUhlWlIycEZvM1VJNjVyd05OejU1em8KVszwDs54LchZdoxnWDw0VUYvPecfib5p - jg8Sib9azTvLFwwu5gixxeyrbwne6hhaoGtpvEN3RH1Xb2tSbv32gA== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-07-01T19:42:05Z" - mac: ENC[AES256_GCM,data:zfbhijoaEtYagO2vthhbFZnh/BsTXEYxEZOppee/CTC/zp2WyFBH+P57nOuQLRTQVHCcKuKFBtmb2aTkLR+jeJ08aoWxwdSyMupA9V8AF7wPRJHzt6otQgATEn9qkMQCqMGK1xPNKmqlbL7/Dev+NpBzonddErF4QfW0Nxhwhx4=,iv:8FREpVr1BmrCQ67+76edPa0gWpAxtQ2Gh4dY0kzZuSo=,tag:viYIGa9/i5NsuCG29a7TkA==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.1 diff --git a/k8s/flux/secrets/cloudflare-api-token.sops.yaml b/k8s/flux/secrets/cloudflare-api-token.sops.yaml deleted file mode 100644 index 1951c92e..00000000 --- a/k8s/flux/secrets/cloudflare-api-token.sops.yaml +++ /dev/null @@ -1,121 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:GaY=,iv:2sJ4+zFe0Z0gB0NRCvv89je2n6rr5SCW7L43sQViV7Y=,tag:4EMNASmZ5cUq49ei/DDLvA==,type:str] -data: - api-token: ENC[AES256_GCM,data:JQ6Zs8q6wddJB7yUrXBqCKMjM66YP6SP9OMUhI3g1pyrNV1CNGP+QW1LOV4SWsSfyTMa09Evgm0lN4X8MEHv3fvMcoLMOakq,iv:OMtyeOt043Bl6IuOJlVFsR7l9IUyuFQkWiL8OamMC90=,tag:EFkja/Q7ww4CigIOzx5Bmw==,type:str] -kind: ENC[AES256_GCM,data:aFZ6gNhw,iv:BbBVKPpnpGu4XWdB3RQ/4rOPnNHAyCp9iPZJC0NvjDU=,tag:x4XBwZryR+JSWyAwgLpDRg==,type:str] -metadata: - name: ENC[AES256_GCM,data:dWpTZRAUmWYrc6YBFsESwWJBzsQ=,iv:ij2e3HXy2Ra7s48HocOZ7J7NZwmProZdO+nGYMWNq5s=,tag:K3i3ap0SlFykRCNEy9lHMg==,type:str] - namespace: ENC[AES256_GCM,data:DpTEoqd6eJ5+MAjZ,iv:Eld0oAp/NJ+dLMEi+lLW2r0QG4FZqyBoePB6BgmMcYs=,tag:v7OZBmGRI6N94rbmfC1P4A==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1NWlEWWw4UmJOOTIrelRj - L1RvSkVtV3IrbkEyM0hINHBKNjJlQStydDBBCmlsdVpmek9oT0pEaEZrbWMwUHBD - aDNFKzRrblAzbnpuSjRuT2xCVms3S1kKLS0tIGV0WkpjckliTlcvQURNQmpzZ09x - Yis3c0pCWU52b2tXSCtzTlQ0aWorLzgKbo9jBuA8PXOAmt3sOm9vit+LJ+hfYPRV - 4n2/1uhW+2kBN3Ti5qmPokRSdcKjKzEwztU21VToed/CCWuCre1YkQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzbFE5d0JLWVBDcWVUMi9C - Z0FmeXlUWjR6R0ZPR0xWUUdVOEQ5ZUF5S2w4CnJ1QmVJbDBkN0k3ZW0zcHB4NnM0 - MEc5RnFQUi8wdUw5bVFrUTRQekZKS0EKLS0tIFFTOVJsa2ZlaUUxUzJndzVpZEZ3 - ZTBsakUvTkM0VDlwUitTNWxSMmowd3cKKWneUo9n1c1PyS16q8uDc0hW/uhJvVv8 - p1TpGGZZPSZIftg3NkcxBOGcLFZYlv0HRgZPs3wCwTYARH2fnZ/3pw== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnemRoQmdiSDZBYWJxZXh5 - c251cnZrV2JJSVltQ0RNWFZMMUhnOG1JZmtjCjdqZmRmTHNXUG8vaEtjNWg0VCt0 - cHMxRFNZc0hMMnhrSDJZYndpWjRwd0kKLS0tIFliUEhNS3F5Z05kSUJVcEdmdFNZ - QkdiV2RwOGt3bDNxdGowQytuRTluVmMKXZtTZJNDqPyH7PcQIM1MgSU53DvTpyTk - saMKC+j3v2izbkCiKJA95Vr6/WL8rAjzyjyY6mToWLGvm1gRQm473w== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrZ0k2a3dQMWRMMEExaVZj - SjRVWWR4b25oMkhhOWJLYzRaRlp2ZXJFQWhVCk5sYmkrWURoZU5tWTU4SjEweUM5 - aDVEMmR3UGlDc09GMFpZZnFZTHlKWWcKLS0tIDJWYlBBb1hhTk1TNVZPampsTk1G - a3J1aUpSaW4vb2Vnckc1ZmRrV3dSMkEKrXu67jpy4d3o/C146P3HrK8JMD5N0kzM - waHgP/Y/Zt4obScyHZH0ZEiHHVF/D0M8MHuNbCC+9u6CHScn0MF8yQ== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhWkZ2dGxPODZreXUvVERT - VTBBMkZXNmVZWDF3UzdoMzdNY3dBcVlxbUdBCmpIUmhRay83U0R1c3Z5ZGRrZTBI - N09lTytYTFBHQW55OURGKzM0Y2g5QWMKLS0tIEFuNlZ2Ky83cHU0U2dvOXFVS2Vn - K3IrWHdNNXh2dmdDNVBDVDJJU1hZeVEKNLK0El23vP6QJud/jCKgpWDXPOpwaIP0 - 436lygQ7c9Wh6HghPEHUhwNAyH6r1aQRS3iKqK2/hoeQUYNFenF5ow== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaNWpyMlhXU3ExVGV0WEZt - UUlJQ3NMc2tmbS85QnZBSmphVGh6THhacDFzCktlTkdNMDBOa0VVbUQ4dUlkejRz - Q2lFL3BjYWM5VGhGU3NqLzRBQVBFV2MKLS0tIEppTXUxUWhydXpTNDNtV2FaOXh6 - bXRlZTBSL1dnNXppL0NFVVFMZ3NIUUUKy1cswMChLunI7AneVhAOsxpSS0NkISel - lZItdkjv/upRXyxgfracASLfxjEdWhGFkT/7m+wFaBR0MHxhuS2wJw== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwNUp2TlQyM0ZOcHRvMDhD - YndoZzVobjZjOThmQURhcXBEWTVlVjRJV2tjCkwwZXRGcG5XcXlRcGhCN0NUTllB - QVpPK3FORjU5dzFUYVl4ZGRiSVJOZWcKLS0tIEpkQVZCbFVlZHZ2d21kRWdBTndR - Ri9KTUw2OFJIYis4Y0kyZ2E2bmNIdTAK/t5RsM8HRKcp/Vvv69jq6j9tLHQc923/ - N+uAFWwmTZTK3UqHn8RQuNq8DppK92HKOlUWL9RcB09aDBJrHunw5Q== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBib0ZGa0VmNVV1TVQ4WHN5 - L21iaXhYMUhVV2ZnSzZMZEdUODZTOFhSeXdJCm1TZEk0bTZKQzJLYzBmbG1Ca0lW - QUJVeFh3SHpBVlhHZVRFemRjTlQwdGMKLS0tIGVMc252dHN0ZTE3TGtuTGU5N1Nu - ZHhYOHhRaVBJU3pob3lDTTUzNGVpNzAKeuAD9+HIcKH5Od/+pBg8zYQWtmIPf+Cw - oRRpR82TzP4n7/T/xvWGt3JliIoJKznwZcvkaTuiwFih3x/WDfVZ2g== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnc2lMbWhpZE9ETmhHcWNL - ZGs5Y3VHb09jZmQrSkJhYVpOU293RjZiMUdFClNPSTJGREJMejVXdVQyL2RVYmRV - N2ZlUkg1NHVxYnVoYldmTmNWZWdpckEKLS0tIGpNMHlTVXRjajJJa2lhaGN4by9w - Q1BXVkpLWUJvVGkzem1nVmczMW5NYncKMKJj0+qniEmw5czSmX1rchK8MpVgzrnJ - 2TXVkMN4GBc9Vfs9xwdiNHsYShBSi5BCy5hYJ4/6mnR/QW32Tk4g1g== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEbXNxaE56VWhnTFFWL1l6 - U3JTOUdjamQvNGxiMTJZTW5CMUJCVDdESHp3Cm5PNFJsSFJ3dE9EUWk3SFlMQlBM - NDF3OWhWczhUNEVWTGk2U0VCbTBORzQKLS0tIFp1MUlXQmc3RDN6Z0o5aytCZlRz - K1ZMZ3AwN3YrdFVDOGVwU2d5Y3kyencKAoR2QWiVgndVOPopQ/jOxS/9jVefLHRB - PhNNgFSGSNHpiur603kB5ADBaLjCWVX1wYUsHrxbmdhQQ6TUX+6gMw== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwVlV6WTNZN2lCU1FLcEMy - UmNPZU81eTlsTUJOblZWZi9Wc0JJQWRrYVJFCm5CbE9vVEJOb0Fabm5QWkpzYWVQ - M093c1laQW9pdnArTU9LVkZud2RwejAKLS0tIHpLUkVua2dzMVJaMjNUTWNyZHhB - U3hveGVqSUpFSmh4RUlFbHpHWTIrTDQKk3R6/bw+W18Jlynb0PZahXbQhvewo57u - C7NDMtc+JeONQak1GZSWIk6kWWg0IhEDtfUejg4Zx0ryQjIN1GRZTg== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3VElNOFJROXY2N001UCtj - VmpuK20xR0xzd3RkNjZseUduOXloS1dwZDFBCjBCd2hXNUd3WGhTKzFrYU9pL3Ev - SVEzV1pEMGFHTWNzdmloN0xUbis3L1UKLS0tIDE2NVRWUUJzaXBnYjJYT29MUzlP - VnpxOGZSRjBaaDJxRWltVE91aVE1TDAKnZzHNPiBuQUmPdj6hAJ4ubJwzXnwdJz6 - 7c+1WD3GnGxJlxuaksiMowbEsWOrmbiFDz1pW2GrIFKRTCR69Nz7pA== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-07-01T19:24:47Z" - mac: ENC[AES256_GCM,data:h7oBPRXh7kolfgs7nV588bPLbW1IDvEWObglBTT6yDydxnJVKr210jNMPCLvcS2FNvMDSSU1uZRUB8r7Pb2D9C0JZYpS/FBR2A+oDsuY+/lVsgS8WrK+MB4IX0Fof+RUN4FjWkMsyz8YpJrN4HBYybCbTKh4IDEx6ZeG9E5TP44=,iv:GhFdtpXFQlJ7qBXpK08mctXOH8UENuTwwLjimWJSIz0=,tag:NUm1R1Jti7iE8C60la1byg==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.1 diff --git a/k8s/flux/secrets/forgejo-env.sops.yaml b/k8s/flux/secrets/forgejo-env.sops.yaml deleted file mode 100644 index cc3a363d..00000000 --- a/k8s/flux/secrets/forgejo-env.sops.yaml +++ /dev/null @@ -1,121 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:64Y=,iv:F1ot354emJ9WLJpPzuwsBjTz8UNnuV8+edD5dNoRkdk=,tag:MH8ztKXyuCELaKeqTGxs3A==,type:str] -data: - FORGEJO__database__PASSWD: ENC[AES256_GCM,data:e53NflxulBOpBb+yORtTwCnchIY4v1iNqqjmm6KSsvQc3byWxlwlprjcZrc=,iv:jpxyRxqmqfuV5P1bueetnEYZdzNiaXVoHRomZMnvpHU=,tag:slN/a4nMA9gVt2U2ZVC14Q==,type:str] -kind: ENC[AES256_GCM,data:tHmVMDCU,iv:Lh84BCNh3bcHZ32PculHN0ebqQ344Q9RzfuMIiCJooI=,tag:BQE4waPKPWBLnYfGAVtkwg==,type:str] -metadata: - name: ENC[AES256_GCM,data:zh4FrdUdIErLkG4=,iv:vtJNSUYAYHaabGL13gSfQ3C1Jqf5XtuhGeuOtJwhXys=,tag:GjtKHKsYTDZJ7wIYqn/kHw==,type:str] - namespace: ENC[AES256_GCM,data:J1CIWk/5uA==,iv:Xcj4MZbbQ4rN/PqNx6+K6l7N5j9ic6eIZ3LqGlROJwE=,tag:e2MIZu71WxyeMonPoucyBg==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsc3kzZ1JnYlFnanhQNzRu - TGFOazJvamIzczhhUzNRNHBEY1BGejArOEhVCnhXNWMrVHpyR0d4L25PdlVwWTlj - ZkwwMnFtd1lUZFhTQmpHVExhZkd3VVkKLS0tIFNaeVhIRmJFUVNSL2hEdHBJMThj - RDdRTlJDL1ZlNjFLWjBKY1VibXYyODAKY9OWkfOLquE7Mt3lFISumfsHnLA88FH0 - d6eVaJTNWaQQQ6qKVqem543IKCMIRUIHbOb6pBZT94zjjyoXzXzzBg== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqUHVRL1p6N3VvT1R2TWsw - ZGF0VXJMWUtjengrazMyNXNpY2grR0pWakZNCjBrOTFYbUN1Ti9WaWxtTnBsSTJp - NENwNDM4ODJCUzBYa3p6N1czOGd2VUEKLS0tIFJBNkpNQ0NCUnpoZkdjdWlHNWlj - LzMzYTBvZElyVTlaRmVHWW1INzByYVEKtaTz5i+ikbsH+TnlSh5ik8OiOYlnoZX8 - eLgi2zvg5Qsgm9wQvL069NmD8niOAtRZ4q/tuHyDy2By3KeceWhbwg== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBeTFDaU1EcHlRWFdyR2Jv - ODJBQXBkRXZMUElMV09zWk5OMmJDSWVKd1NJCmJ0SWVuNDkyOFZkVkZaS2kvVHQv - TlFpKzRQbktTQ01aOVFyTVpSZkd3RzAKLS0tIEk2SVVFWnFvVmVpOWpxOFRhYVFv - UFd0YUQ2WTU1NDhKbDNRelhUTkNJTDQKfwNLm5xKbBrigmVumG092ZjDZcWDw/XE - ONoJsICHJrHvJmj/O80WkdIVL/y5imVI5B8A/GPG2hgnaxdtMFQQaA== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5bzBvQ0lMYjlVMlVFK3lu - Y3R1eUZoK0F4YzdzaTBsK1BPQ0RKQTNMODBzCmFlcFJvY3doMTZBQVZsbWZ2dEZl - cERKdGRhWHVYbUd1QlFUY3hvVy9QQzQKLS0tIHI2MXowc0lIWkNab0Y4WkN2L2No - VWJueXlXK0xLZGduSWg3Wml4VjdkSTAKfIUQv2o6981WUgtFLIkPbKb6sNkiPnLa - dDlwNWEajEpymyetagwg805vg1KUzJGlKIvCQQKad/oXrCDbmZ6Uzw== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqRHBISVpVVzNQbWE1OFI3 - YVpSaG9yOTRNUHFINGxJT0ZlelM5bTRROW5NCkNuYW1QWVlkcXg4azdldFg3dnhW - RDhHNmhqeTlrOE1LYTd4VzhJTE5RdWMKLS0tIEUrOUF2N0pGOGJPT2hqeHZlUEhw - a3g5eE1KNEIyY2s5WW5jdHZOQTFTdWcKcY90nDbbRB2Y0gju8Mx5QeVW1Z6nrYmY - RGA0BKVGwaGLF1FElOl8XQx8Ctla1Hgg9OZTwNkZHL98JZXMa2EOkQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSSE5IbEs5VklYc2RaMDhm - Y3V4UCtWZU8rRGVDK1VzMzlMT3VBMUtDOXlvCkZZditKOHlmY1RBWXppOUNFM0tN - NjY3bjlzUUg4VnBUWWxRajBKZGY2dUEKLS0tIG03em1LazVEWE5TT01XWVZaUEhi - ZS9HaThNK21VQUN4TmlIeEk0UVY4aEUKsGhRGcetfDNcxgsXAO6xPuttzIG6HSxm - x7kHas6adM3WuBBANEHw+A9h8RnPTID9x5x9FAr5qmfct472lUcqqg== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsQmIvSHVYUmdBRldNMkdn - VUh4VFVRTjJnTGQwWklCQldwR0xnN3QvQzEwCnN3aFJMVVZPQmo5RXJuS0IwNm90 - WkRSMXBWVDBNL05SdWhqbHRGcDlJdjAKLS0tIEp6SGJ0aWRmM1pIcW03WXVHck9P - emhoUXo1cUk5N3k0YXcrRGw1TUhwRTAKez6fBFpiv68Qqo00FiRHoGVIbBs1reTv - hiS3WKuXEyduSQSIBZYs2rYVKZNFwRuE+XR70Q0HQn8q02eCqoXWdA== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiYkJWaEZuNUR3OFl2bmJh - dHVyaEJYVjkxNnQzdUdUOHcyejFEUThOdnpVClVjTVdlRXc3TExPMThWOEVET1Fl - M3JKczR6OXNFV3p0ZnFaWlVlSDVPYXMKLS0tIGR4WVFwNFlUVEtGemIwRHhVRVdj - V3crNVVkMW5hUGFxRzBNUmdvYTlYWGMKAdo897Z2rTG2nEg4dUGc7X6GMR4KZCDm - UjGnh6gmI/hmkweOw0z0sP6G4FfnrWspkdQRSLjs8jAPJzAPZ5kx7Q== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhRHBLODkzelU5OEtTZ3FZ - TFRnNXIxSTF6eFF3RzRZUGs3ZElqb3ZSVlVJClJPMlR6aTFCNFd0Q1l4bnI4eG9I - b1VlTWZzTXJObTQvTEg0RDAzTmtDSmMKLS0tIE1tVlh1M1ZJbCtXWCt5ZXhzMERH - M0dSaGgzSG9kRUp6clZMK2pBVnJNTUkK0vWyzjIcZxseMMdWC9yO0ZuHsF73+KFR - kO4F+jQcOg/Dzhzq6hs9eM+CnMT/2rVi1TqZiFVcFOPV3aacTewBtQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhc05uU2hpcGU2SEtHMlVp - cEppcWpBWlhqUHRoV3N6S05hZTBKSmRFdGhFClRPZlp5TEU4RlFBLzZPN2dhZ3c0 - ak4wVkxsZUdqRkVibzU4NXBwK1g0SWcKLS0tIGlOam1nZS9XSFI0WFNJb250Tk5z - MENORmE5cjhESDRzdjQvZjNYWExnSmMKVKKUbfrVg5wgWj99jYe8jctG10lgEvN1 - 98QABU2FG+ZrbCx3yYVwqiFkmyHkraHszkX+xMf5RLN1068XJS70rQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHK0RvcWVMN3k5eHpJT3Vv - bmdFUTRvR201alRHVVNRUS9kend3aU8rRjM0ClNiaVRESllkWjhiRi93K1NWYU1a - UHg5TGprZzlaZGJGYWt4emI0RlZVY2MKLS0tIEovcWdJOWJUa1VXYU4zQThqTTdG - bGY5YjFJMkNUejd5bUVPU2RUYVk3dHcKgYQr3i9aF7cg5jbzPiSx1nJ7j4dmhJ67 - qk9M9PqdI6UH0w+fax6pnK7IZw/Mnf6al0GNkhJ7sHU7FQ3q3imImg== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyWldSYnF0RjYzczYwNks1 - cDdlSTByTWxSRmVGQm8yM3NnV3Z6Y1hzdW1rCmx2emd2ZG4zUGVZcmFkbktzakhM - aDVBUDFnbmw4WlZ6cWZsZXl1UmtCTE0KLS0tIFV2d0h5OUk0b2RLTDcza05seEtn - RFlkKzZESDFPNU0rSUF2SHFNQmFDU2sKx0qdofJ+3x297m3ZrzPl4NjV/bleTJJL - J99ZuAXEFD0aa/dnuQ8/dB/LLjjQZnTCVl3mTc+rE/MHYb3Xy4ji6g== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-07-01T19:42:05Z" - mac: ENC[AES256_GCM,data:s51cZG+74+W6EyuF3w+SeyDFr8Ui49lusTC7grzNjJ5U7vaJ61a1zwzRuudd+nUPfo46xA7DZ8ifUFTxEy+wl8DrX3h6COJU+PtlrMsHjDts5wQ8Pa9TkJtCSguD2OBPYWdxZcBdYuxkvvtgOHTn0gdVJ40Lw8vZBJbiC3f3NbE=,iv:Pakzlcd23lZDLGAQV/O/9PysUs0i1xBk4BGp7ZF3kvI=,tag:1UreMQG5+VTRm6Tv1PrPdA==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.1 diff --git a/k8s/flux/secrets/forgejo-pg-creds.sops.yaml b/k8s/flux/secrets/forgejo-pg-creds.sops.yaml deleted file mode 100644 index e6a735ba..00000000 --- a/k8s/flux/secrets/forgejo-pg-creds.sops.yaml +++ /dev/null @@ -1,123 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:JxE=,iv:rqRXjXE4S0T4X+wQ4UUVFwSMfuMSYyWTHLmiapoefIw=,tag:TFoCM8T7RURfWm1/72dNvA==,type:str] -data: - password: ENC[AES256_GCM,data:Px22utUQEHwBrolHug6PwY5z4SkNk/bh/n9X+cayAln3zmIFAVEpfkGyfEE=,iv:tbyoDTeDli5OIjjx+DRq8wzk0mJMuIUflPylklbBfkQ=,tag:P+w5s1i1WgL8tomttk0k8A==,type:str] - username: ENC[AES256_GCM,data:4jtw0NZ3KMo6ednP,iv:Mjheb/3jedQejhlJOilbNZgi11P/Mtsa2nr9VHXP/ww=,tag:cgP75qW7GfNJcvwxUKYOIA==,type:str] -kind: ENC[AES256_GCM,data:jH8YsWyD,iv:+lIa7X2dywhnBGBbUr8ti5h/LXka5X2M0BRL6gWUrGE=,tag:JNnnsPt35CGz5tJINRaNjQ==,type:str] -metadata: - name: ENC[AES256_GCM,data:4K7tfJSLVAMcwOCIU4flEA==,iv:t4ntn26+lAnJ0qCWRPihWaNgyLEP3qEHEo3gwrkvKAc=,tag:f5OwghHtKKkAP6z2qdx4Gw==,type:str] - namespace: ENC[AES256_GCM,data:Rd+Q453qBNBurHY=,iv:pU7RcUEUF+sFVY21ek3P/mgernir1Lmjkf8AclirefI=,tag:1GR71+WQPawMfVXRoypBWw==,type:str] -type: ENC[AES256_GCM,data:Yanckl8APFjE/FHldhP8quDDC6sF60IB,iv:13I/TCCVnxtJv2nnlG/09oO05XLjq78gF2ZFqxqg1RQ=,tag:opwr5UR0y3o+FfOiDnvYmg==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwSnkzU3BVbFA2Mmg3Nld1 - L0IzaDdkOFJPQmQxK3lGY0JOVUNsNk9RNVV3CnZFWEthVCtXV3dVaHNWYWx1TEtT - ZnNpR0hmQ2YvdVBXNXVRYkxaSEVRT2MKLS0tIER1YW5nSFl2NHVYdHBNdURzd2pR - d2JZZlprUjhzL2x3akpQODVEZ2thMjQKduijMFWvnGw6hzi7OEq257/u1K9OY3vC - j6gpZmCGaBkRd2KWaCUIFIdKjJ02X5x7qnegmYiO5iTu9Nr6PpnvfA== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2YUx4dzFtK1hxOGxhN0My - QjlhNGtOV0hPd0pJR2FBUFpLVTVvdWdVS2xnCllrQmRUNisvVE10OW45Vy9Cc1F4 - WjQ3bEhBSUVEalA4RU82MlZHcTlicFUKLS0tIENpRk53U1FIR2FpdFlXSUtWWTM0 - NWpQT2NTdWtqbk94WmxqWmRyRUpBYjgK6wiqteEfvmWUv6zSP9rb3VyESzOIM2sM - geJJ4t4Bl7m0MvT4tFqkJKx2Z6llYlvg0TiZelXcSiswoK0C5+VNmA== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtK211QzNOTHRkcDZyYWl6 - OVVsQ3Q3WmUyUTEwYkhxbU9jQzVFczcxc0JBCkhNWUVqZlRpTUdZYlhzN1pIZ09h - aVg0Q1ZudkRWUkgwaU1ScUlwNGNTQXMKLS0tIE5nMktQT3hGUmVLUnFYczZtc1A0 - VzlhQU4zd1JhK3F1L1pFeEIwNEFJZXMKuToAcAm6zXgyAMTNpyV19tSBB5nTkU4U - NX5KfhGsin6yt2NEpHYt9MXwPNnmw3XX78+fpL2wgMQLHdIm7h6VcA== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDTjFtQ0ZTb05ETEVHakVD - c3lReW5oSzd4WnZJcXpScUhES2pEelNmaEFrCk9jdzJhQVRNYVUrMUdLcTN3WGRK - ZnhlVERKbGp2aUFrSGVzSU10ZzlnNFkKLS0tIDNuQ2tMUENZR3NuVlBsbjZkeHls - ajBRY2ZUazBVbm9uN0EwRFp4SDcrUzAKmu3iU5ZC2Mw+t0xOejYGl24kC9Zt9tSX - /6V4fO7UrjQbfCkrJlcsOExZ+5eKQEQ9WVPh+onVW3NRqGJzJ/kRwg== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQS0x5UHY0SURqdFhNdGNt - YWc0cnFIMXFPb1lIcC95L2gzdUo5OEtHVFhNClRtYnVmdmhUV0dkMGdsVVk0RXRP - U3JxVmkrb09LMEVhMi9pS2MzQ0NlSzAKLS0tIGV4dFZVeVhMVnZZKzJVTHVmSWta - czJ2TkZRc2orQXo4cCs1YmN6S1ZwQzQKLOt39tBY6dlENM0Io2AA3WkiCzjbcRcb - 6gqpuAjOLbvoYZrBL17j6ddl1xTnghk7KDO2RvDCi3IW61d2StaUKQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5bVdFbERPRkxHZmRHU2w4 - Z3BMZzRPcXpnNzJKdE85dE1CZC8vclZPdkNjCmVIVFhiK2M1N0lCV2o1MUZqRS84 - TGxEaEZZMTZDSDEyODNuenhnbVJnc3cKLS0tIDJyS3Z4Q1NYMU4rNEd5UHRHR0Zp - dHd0T3dQRGMzSFdCbTczaWNQV2Yrd2MKepJfAofCAu5mQl0sCbpp63D72cRmAJG5 - Wp0FKH87yvG7OZgFggRgGuaasr04RkCn7MALkwmtiPbUDCdx4dS+tQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVU3Fab0ZpZWhCM05RaTNl - a3hxRXF2a09NRXdzTXNvWFhMMkRQRjdhcUg0CkxUdmp2SzRoTVFTRHR0QnZGZ0dB - V1NDYmZVRlRaclcrZXM4dmp6VjcvWkkKLS0tIExCa2VmSlY1a2FqazlsUHNqcXJy - Y3Iza0FtOGIrL0FIT1NRd3BnakwwVUkKy4Yr5janXQga8HbspjiwwX+S1XQF6A5C - aNLnehHR1WgS1SkSfMai1yBfKww6ye5gmOT/LogSFlCMby/V3/FWYw== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPRDRSWVdtNHBVYzhaYjhR - c2EvKzczbWVibHpDQ0ZxdW1iYXZLZDdIaDFvCk10WHBlSVkxVHV1K3I5SGt2S0Nj - MUZWRXNNTmJIMytoSkhiWVpZQjdTSU0KLS0tIEVUbnptTFlrUVhObGpTVmxCQzRE - TWlBcjFMWFkrUGthY0h1ZTNLTU4vY2cKIY8iv2i4qV+S0G3BvJ7Jcn8co4GhxUju - UQAKHwWiZ5Eoe0XQZz30EL1lmLjHgzv2rDkf0mEZCcKD0Nq2hgUZUA== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBySTVocEZ3NW10V3BUWVlD - RURDQndhTzUvY1RWbHZZbEJ0WXFjc0lHaUVBCktWYndZT2U4MzRaKzlzWnlwbG9i - WHZzM0ljYld2R1NuSytkZkg5OGZ6cVkKLS0tIFJFYVlJWVlOZGFPOW96OWxCMXEx - d2Y4WkU5ZnNseHkvOXNKUkk2dXNQS3cKxz/j50UzWUVPnOzgJiBvE4jP214Uq0VX - egwPkRNkIO6FRXMcvSBCgbBTzckTnuLWmxQKNIEOHBW2kFTiRpGeGw== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVeTBkV05KZVlqTk1NUm1G - dzE5VzBId29mQThaUm5aZjMvRFZ3VkFRVURjCm1MYmpDcWs2NE5DSU5CaFhxMmU4 - ZDhxMER2UkpYV0pNeDdZTTRDVkVJTDgKLS0tIDZFYjhBY3oyMU8wcHlsNVNHSUIx - UnNlZ0JUVzJvUm4yMWpLYXphYUIxaEUKNlrnqZZAQ9G8HH8xDX8kqH6+ntGkpWzc - l5qWCHoZIlB+SJJaTqUVzzGa6DKYGq6jpcAKTz0IkVMmBnjFPaooDQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0TDBPZ1JqSHRsWTgyZGdQ - bVNzYURXZ0hsLzJkakxtc1NHaDE5akpMeEFBCkNZTHliY0pXSFJES1pja1BJUkls - dGVIWHVKSEd0R2tOeHBWakR6ZHJvQ00KLS0tIExOTXFZTk4vTzIvRTk0bW94OTVY - VUlYZnZlMkl6TnlRSTMvb3pHb24zcmMKJHYasYFBYHlkPgIuYVHuh9Lx77w0KY1A - fidqQ4GFHOR4ooQaP0/tQHF91Q0Fqm+NoQMuHWaiKdygAyiJXjqcUg== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUVWxRNzhzTmpLbC9USlJt - NW9WbHhaM1AyVzdoMUJ1MGM5T3RLWHE5TzBjCnVGZjNMMURtQlJtSjFtditxc1lz - VElIYk90dTlTQkhuVE1lMEpTdmo0NE0KLS0tIHVaYkNBcmNQN3BCQi9SUkRmeGg5 - dGMrNE54cDRvN3B1Myt2SllxZFVnNEEKN0f4s7gDxSvC2Bbbz4LbtsenH2XOGM4Y - tU6i28U/lm/FB+04fu0MQKKTeb3jObqnBUBG0mMHoTm6fCt92YG34g== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-07-01T19:32:43Z" - mac: ENC[AES256_GCM,data:OEFdMmyeffs/CxyPVSRttsjikzqCYyoUsWDkZ53oaa6OAzJCxeJ62PpvOnQdoIbLvoVOwdefuO5fHkXxReme5BW1ASOxhccmpgjzbs+tHPD+4JFP4V2dKPS0bLEtZ+f/+/orrf47zrnI4Di9eCqb9qlEECLbCIY+J/RICHTNrNo=,iv:V24IODTWXhDp+mB5lZbUeusayoG17n8dDUMiBKHtqz4=,tag:mHDyaQH7KyHFDNt3AtOC+g==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.1 diff --git a/k8s/flux/secrets/forward-auth-navidrome-env.sops.yaml b/k8s/flux/secrets/forward-auth-navidrome-env.sops.yaml deleted file mode 100644 index b7c3c6e3..00000000 --- a/k8s/flux/secrets/forward-auth-navidrome-env.sops.yaml +++ /dev/null @@ -1,121 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:KW0=,iv:tnC+8ygylgwi3O2xR89TTgCWyP++OrodK2kOepAg0Tc=,tag:eAg9xIObS/d+hZAaJ18ffw==,type:str] -data: - SECRET: ENC[AES256_GCM,data:UMPaQI6eW5PVn5JNkxHXrFULGCjDS1J1JdsB9VOQpJWec5a5BZrDW0C4XCHz/lJUE5Z6mFyxzKYKbnut,iv:oPctTh7IxI3tXQj+Vi+6Zkrn4IKgMfkdfQPHIvAMQ+g=,tag:Lou938X692H4ji/K6VstUg==,type:str] -kind: ENC[AES256_GCM,data:EANfDqqH,iv:V9Sipa6L2vnnoCi+kxHb9RrN6b7eB4mbp3RXhPznmqc=,tag:hdid30Jy+k6LEUG87U7ajA==,type:str] -metadata: - name: ENC[AES256_GCM,data:uOwJNjlXkYgbxr3E+0Pm+diFURLblyNjCTo=,iv:q7Ey4CZ7e2FXFq3ogesTIG2NdOwGz/0QOX+c0XF6p8Y=,tag:Ulan54qF/Msj8+gKSfYD3g==,type:str] - namespace: ENC[AES256_GCM,data:0v1l+xFObYY=,iv:VsQ7usEjAveTSY3YWhQYgCMmUJvKnXdNHVuszkb6vjU=,tag:kHa0bFNTnzYlXB1jrKT76g==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTWkRhaGp4a1o0dU5YZnpH - dDhnY0xyLzhBUTZuQU9SSm9SYVRCbmh4L0MwCkN3WGpuNUNSSDRxWE1RRVBlOHdT - MFIycUtHSlJSQjVpQ21XLzNIc3FOSFUKLS0tIHB1YU0rdERDRG1mZXIyYXc1b0po - d1R0eEpud0cwckRIUTNpSzJ5UmhQNVkKwomt9C5RDr8mWSCGnAiDuvPFAseqEsh9 - jHHJMiF+rlDXgFnaOjWhQ+zwh52nBkRnyxQp9IzAOvN+El0Hk4vHvg== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNamVMcWtEd2lyb3hUNUhT - UVFHdWFXV0I2dk1RWnBja3J6cmRWSkRCSEdNCm91bmV5VHFHWUMxUDdaUTBGZUZw - Nlk5U0NtYVQwZkRoNFZqM24xSDJaNVEKLS0tIHJWcTZSYnJwTlFGSUFMY3pJWWFD - WlVhbmEzNkF5cFNNdjhRcThDZEdpcWMKG0dkXqzrcD/S1dCitxF5nns+UjzdIdoH - m0Ic8c85mShaO6hX90Fq1HRfGxflRRZ4+VWgjPvPsD9mz8hCvBpsSA== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTcUtuRld2TGwvb1RHR0g0 - cjB3NDNIdUpscVJzV0hKVFZ1QW9lS1Y0TVM4CkFQU0ErUWpEdlU2cUVGeXFWa1Er - R3gweEdid0ZiL2V0STgvTkVaY1FsSnMKLS0tIDh2SEFZR1Q2eXNnN1BtbjJzVDV5 - ZFlFZ1RIaDhXNm13c1dpcUtyMmNzbVkKgCTyAxToX/lC29zAaIYOuqTBaYN8tekg - knT0wpm4q7a4IZl+TuqKsbbOjS+OIvZ3Mlhqw1a9Kru9BTZQiMavuA== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqVEVvT0FHTkhMRVhtNnZm - bzJ1TURhVE5kaUVjK0hFaG85c2hJVTNiMzJVCjBhV3Q0U1M0ZHdVcEJ6RWJReFNX - TUI3WjVwdERQckJ6bUgvUEJ6Uit2YkUKLS0tIEJTOWxsNXVSdDFPVHMvTXRTRmpC - eVd1ZDR0cFRxTGMwS2dyQTI0S2loSk0KFf2HS8quPxsFGlpDqUueTvOab+/EZ59l - e6286i7JYvCwhJG3lzU64tRMRjHolD5twPgFwEHvUryWj/nGL9TgcQ== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkcEFiV0dVZElqNUVPODF6 - ODhDWmQyTmdvbkJoMDJYa2JNQncrbFl6R1hjCk5DWGlzanJ0R05QK1JOcXc5eVZz - dnBTeXFnUXNKWGNTdWhmNDM4OGtoWW8KLS0tIElLdlQrakpjLyt1d3J3VHNTWDJI - cnh4cWgxUnhOakNDejhWZWxOemttUFEKUkR3qU5YojwNonUzh0DBzZ9pvtBBGfC0 - e2zoz6nbl+CSr0zkUr1kporXwBHxxqu3PpjXMwzQAQYdyRs4ayPm8A== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzSlhSWS9vbldtUDZmMGNm - NWk4aGd2aUYzek5FcS9kNXova1IzdVNKZENVCjczeWFXemNqMUh3QWp3QldrNXI5 - OHEwNkp2clNnUCtpWm1NR1lRL25mR0EKLS0tIHJMdlhobDU4UnVJL0Yxek9TTUJJ - TkxPYW1nVGwyMDlqSjA0am1JUmxCZ2cKSN+yjiheaC2mRrS/e+XiVHDNJUoV9fCc - eS/zhm99S231W87ymQvzHdae/cZNMCC06kx4jCeK1uEwSjHXIWVZcQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2K3pKTFZGRTB2MmU5alli - dlE1eWhJQlhjOVZSdWF5MFhHNkMza09vOEZZCityNE9oU2dzdEU4Q0Y1RE8yOHhs - clpEN3h3T25GL1VCaVBZNjBhZXljMGcKLS0tIG5aNi9XVTBGVnNnNlVsQnlaR2FO - cHVmVGlLVDBRKzhoYkRqcHNOeEl4M0kK96oYe5QiEKQMeja3L7Ji5bN6E6IIuZkC - IWCJb3WrwZfc8i6Ad+b9S8nS0quLZkEpwcyKOcS44EU2rNaPXj6/bg== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMVGpCMXpIb0FXMWlsYzNY - RUtJMkxDUWNNVW9UOHpldm9GMGo3R3NIbDBJCjRqbGhNMU82V3hiWDNKay9EK0tm - TWx5TnZpSXZlL1lmNW5mMWRPRktsMDQKLS0tIEFnQ2NYSFppQUx3ZW03MThiUm9i - RVMybGVZbGJzcGs5ZEUvQm51STh6RjAKgf+usmRIYgCVGm0boTnGUMHiTtDmDR81 - +cGwCqbd9eNWh3/BftCwMGKFHp/12LF4sQHIWQgwYoLm3VmAveIUKA== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOd0RibXdjdVMvUWFUTmFm - M3dJWVJsZlFjcDcwVjM1Uy9UNXVBbk9GdnpBCkdiam9XMlVFV1o4SzJDMTYyYkZm - emJ0QnZFdTd5bElJcE85eTVZMThoR0kKLS0tIHczMXpCSi93TTJMYitqdlBwWVZR - MGJQclV3U3kvVFM4dHhwSFRqTnhlTHcKlBAp/vCAXTxxxXsOCahKuP1jAlpHn/N7 - SvkX7i2LOMxCAlcQxx88DLgCvUaZNXq6OOlfaoqEVfUXAx3k0D3zDA== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjUFNPc2FFZGdnZm9xQWlw - RHVUZHNuWjEwZGlJQjM1V3l0STl6RHc1dGpVClNubElrU29pK3ZqN0hLWHgwajUz - K0RielVMam8vdGlmYWVad1dzOEZwYUkKLS0tIG5DZFhDc2NhbjEvYVBBRURWK05Y - Y3M1eXN1OXVTNU1VbERIeEtObkNOcEUKF85/UZTT7J3CFXI+W12GkB8ccZXTuZe4 - PSNE4K7QFlBxqJSAnR8On7URfVb9F3rAFqUD9pACWdjZ+40yvA1E9w== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHRXh5bFREdFpqZlA2NTVV - WGFFRUlISW0xdW5WZSt5VTBDaUJ5NWttZ1R3ClBqdmxBRkJDcXY3K1ZQRWRWZXcy - TmRLRDMrMWlseDF5MGpxWm9ncW4wd2cKLS0tIGZCaUtjWXBSdzI4eldSTFBoN2ZW - RHNDVi9KVTUyWW91OUlwdFg1NzBCQmsKVTx91GLk/hfgLqA2OevYG+t3Bpe+XrX7 - JVynD7Qgi0K5Zo3OMLN5eGW/b4qj4+XyvnvId2Ct0Ek1BUlgFImjhg== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhdHhDajRxaUJkVGIvQ2ln - QVhsZjloU0M1OHBtMitzcEphVDA0MlQzTFY0Cm1xMTBOS3NwT0ZPMGF6aHo1REFC - M0dCUHRVR0lVUmVGMVlOQms0enZvNm8KLS0tIFF4MkdSR0ZJRFROTUtjWG9wYzJo - dXJmczhhRVVkZHg2MWpTOURvdUwwdFEKhfwFGXKKeJLW9lZTsKFbk7n3n6HhZfWE - SbiRXn/csOtM5F31BU6YjW3FHv/vTy36pY1qoJYtEOFJnOx5IF3bdw== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-08-06T03:07:04Z" - mac: ENC[AES256_GCM,data:Qmxo/ooz8Mk5eU8YAmDGiuGujU0SH8fGHDTCWbEG6z/e5Jb3oPUF3PX/EP6shYREQOTYozGlAI3OwFUD55KEBoNprCT4V6G5UMKEb/BcLcQTChE8TvCkLGvksN4UU9F29e96FvRUenfiYaL3zAFflyU7tMrT4+k+5FC4YYxj3q4=,iv:dDhT0/+Ud0dBLMGNv4jwvDMCE5GOfU8lZfUa1YftqXQ=,tag:os1IPe9Yn0wVR+N2NQOHOQ==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.1 diff --git a/k8s/flux/secrets/immich-config.sops.yaml b/k8s/flux/secrets/immich-config.sops.yaml deleted file mode 100644 index 99b85acc..00000000 --- a/k8s/flux/secrets/immich-config.sops.yaml +++ /dev/null @@ -1,121 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:J+Q=,iv:gkEJHMWhcc0dLGw92UGNqK7sPGxhw4oZ3i8NV9Iuqo0=,tag:Z/bS3dPXu5EvqxLLP8KV7w==,type:str] -data: - config.json: ENC[AES256_GCM,data:G/jDDPfaqbEKeupdiwmO33EEKUiVDTGyxNVjsWxvN6zj1GPd2ozRkqdEAdg1HUZGEPLG13VTrL8PU++i9zQsBLeU26VtbcIFYP9nyVBTX4/HUC4P3qRZwr+bBDPeDPBZafZmooSwKi1zPotRwJ1ZAhv3AsYMfgBce5ATC+lmVFGJEfILvrBglunf50bDWWGz3UKR7MMkD+m2dT2/xIFsltR/toAQd/7Vb6TiDRj9KIrYDnsrooa/KSn0CSNsdsv672CoSSFcRQl7DN8uS5KD9gOcbdv8rVHma8Y5YmSFtNQpGOt9wIqkbBwQ+ihUvDALuOjOT6Ku7HG2S7JPD29xr7XQE6NQbVdcIF+P0ZWLSK7g202JCFIHKvblSn0bWeOvHA/VCLI/6QiBrWAI+VE+2DsojFBTSI5JwuRJ9M0iDHZxxk2+N+cvTucRUaUWF05v8i5xPSLG3Mu4d45z71qnagzciM2H3ciuLIjTrwgEEjwwpTlwH6QsDLCSTjFapX5euD48lA+qVVnrapLfweP9A3qGNaL3j/aupxIStO6FoOtv84r2bg0L6o8yhpv7598U3hjzXU/tc8YMo00BlCU2qH8stTBvkyhGC7eoWYuPhCLy4BPlN4LWCrm0r6KtoybYuwfg7UX3/wMkl+BJsONlMmoY7crOt6p7yYndDHIgvNnQ8Bac38PWCVOQNRhH5e+ZfEpzMmZlFGrS1dCeJosh+E/PTLCjZz2LliCfuV50U54ZtpK5mmFAjsVgV9DfVLJDhFr82NEAp80=,iv:cxKktnuivvSS1gkfNZVpSPBt8M3+GvC3GWKXY78219Y=,tag:5FkP7/imIft3J6a7nh8pgQ==,type:str] -kind: ENC[AES256_GCM,data:iZb3CZuj,iv:ovxFGjnaJ5xrYmYJvjay9aDVvygNc7oMOhf38s2RIQA=,tag:cLxqhYTUKoGyk8immbhCZg==,type:str] -metadata: - name: ENC[AES256_GCM,data:2e3LHtrxqC78ejaptg==,iv:agUsMEFqXFvqzfvhS0/CSxFaD47fQnnM6OG4d77merU=,tag:LVb18TQxgY7lEoFh6Niz2g==,type:str] - namespace: ENC[AES256_GCM,data:RubxD2r6vg==,iv:4c6ZlOomHo1D5/ZiHWO1uF/ko7s1WHU1GGjD6aGXvVQ=,tag:5hDZX36fv88GnkelGvZDxA==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlZ0JyWDdOMDdyUGtQOHlp - cS9XeUxsOTFGci9CQjRnTXRyUzYxSG5oUVd3CkJQRnpqcStITEl5STYvcHJQYUhs - ZzZFRm5FanI5dFlOSjR1aE1tTnc0TmsKLS0tIHkrYk02WVhmTGxhVStycTF3UXZM - TzJvcXhaSG11Z1dLNUZoV0hqVHBFOU0KS18HZNtQt7ihRLcOd5g+GIz4Py2nHRaZ - JmZrf9xfB6TFW6nxMZAp39TxtGxcQ1BYvoIKstjmb0K7B9NuGxgQWQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByWW1mdjdKcno2NURUcHhG - U011L2c5QmhBRWVKbDFXaUFQS0F3RUorRWpJCjYyUVJjRGtKMVJFdHMrV0JzM2ps - cm82YWMzNUVmZlR4M2RKYTVoZm9jcncKLS0tIEp6QXg5WVAwNkhzd1dwKzQxcGxR - cEVHQTFjVDFCM3hMaVRGM080dmc2OVEKNi5CiKrgBaPQdLRMiIbyKbdHE01H4fp4 - 6EtmKCwmWWvJ25wTMFOB16ThdyCSa/Nh6+QI5wK2rKBcgS04wE8FzQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaUk43WVRxQzkycTJBWE10 - bW1FOEQ2dXRGTllML1ZoSDhWU1plb3FjdlJrCmxqS1gwejB6OWZlK0xQS2hzRXB2 - cE8zU2Z0NnROUlFXbjF1b3pHL004SmMKLS0tIHoydmJaa2orTUVIS1ovNWhTbGNW - Y1pqS2xNbGxRbFpFMUpYZWs0MS8vVmcKsrTdvvdi1RrJOuXSmBTwoPbWvNtoy7qF - Gd2AdHzPkcZ8n8y8b/9IxP/ebqCz6dbXyaoFjaJnCmXsfjettYId3g== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRRHBLdjFTUStHanVkQ3JC - NkoyalpaZUxzcHB6MjNQT0VBdGcrZDVIcFhNClR3V2NmT3o1ZExmRE1DQVZjQjVk - OVZiWkx4ajNuakw0SzhCVVljVkVrYU0KLS0tIEFPRmMzOTdmOFhIVnRVT1lPVytQ - cTAwQ0JLdVdKSTFHSHM0b1g4Y2FqNEkKX39oEp68JQjoU2phR+DxJC56+i21rOQT - NPyOZt1I44iuVx1JcQMYIMHYXC6Skt81BaF3R/wLvUeqGkd20mZAkQ== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhQk40aFFTWHpFMVZhSm1E - OTMxdjRSWkl1QlRPdFJvLzBkaDRyMFJGL3o4CmJVSW45L3B6UGl1disvMUFBSTl5 - RnJuM1FubVpmSGlDSHU3d0FRNUozNzQKLS0tIHAvWFBMcW54ZGtTSHN5bC94dkRV - R3N0TTJpTktJK1ArazdSUjNnZTd1MGsKDN/fwW0ENXl79jo0wUME49yxEr1puJiC - 1deuL8HylY+2QnesCuj6V1msz9rOgySKWbKg2VVK54vkONQPGKxrIQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2ajgyeW9EWmJlMzQvOGhV - aHlQTk1uM3hocWgxSTZoem5wMWxWdFVKSjBBCnIwaEw5dlZkYW9PekExQkF3WFcx - Z1V6WElEemtjVmZ1U1JkMlpUVHU0S2cKLS0tIDJUdzZFelBsdnNKZ2RtemxpTFAx - c1dvRktmdStRdHMrVnBENW5rVWF0aHMK8bIvt+Xt4J4nLsxpzcRLEj1t4R1bn+j+ - b6UCuTDnTvc8Wv8hrDg03b8reckkMkM0OUxnaZmiJ0lOD5mxlMZfMw== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIaEp3WmhVRWMxVGpEZnkw - UTg1bGlHMk0yMTN4cWJDUVNvRlY0WG1mMURFCktTZ3pERXZIVFhlVVFpdysrd1BW - amhTbDhKS280dFFYbHFkOGlrWDQzd3MKLS0tIEhBS0oycFI2eWY1SkFrem9NV04x - MXFiT1pTdFF0UTdObmt1bGJvWVlOWDQKin6NVNWYifIqi2zgDsmHUrZCRiHMxZK7 - TEkbmwECyh3UGn9nu0bQnEKbK9e5hpxhKrVbnFE+kiZvtV4m5DTfEw== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqRStWVGY3azdmeVYycTM2 - SlYxTEs2RDQ3dnVGWE5OYmp3UFFFa014U1cwCm4vUThQSWtoZDcyQWRzaFNtRzA4 - SE9mTnFLZWlKbzBvTEx1VmdSTFhVZncKLS0tIDZrTXBFR0R6cHR0d0pzTkxtQThN - U2wrWVE3S2p3VHJGaGE4bzlPd1p3UmsKGj8GUoFA5eWrWRX+t0TxKkqaA2m30t4g - st4FSaS8r/xoc/6ZzFJJzMEFD5BWktXoOC4z4QmyFCfBzEd7K1+i4A== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3Y05WeDQzZUdvYlp2VERQ - MnRCWGlJb005MDc1dHdsY3UrSmx2MDRYd0JnCllDV213ZEZZZmV4SzJVUDJRRVZL - bklMZXl2TmVZWnNKNzNrRk1RUFRiMWMKLS0tIFVtOEVwSVRzUkxYWldpVktLN1dl - T2VON1Z0KzVOVkZueFZrY1dySGlFa1EKDLVL97//SK1OP6MFJlfPpfUk/BrI/gL7 - 3/BadCAj2R3ucfXELN8SZAXTzSkX3MRK1ebIdfrWJZQJrjuKsvXvNQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqMFc5M3VPeXVNUktKaUNw - cEdEcnpseEJVMENxdDViN1VCdy95YWxoZldBCkM0SDV6SHRtWFpxUnZNaEhiTGIz - NTdhbGhpREYvK0RiWjhJV3lPUEI1SGsKLS0tIHNOdVVadjJ6NjNaUitGNVMrVVpq - ZGVHYTU5dGxoNGFEb0JmU1RFcmROWEkKD7xtzlYbiFLAT8lubBl3SY93ZVKE0ugQ - ESaBDrQ2lYrDfXjQ9pKYr4uabjhGYoUpTy43IGfSebtvX26ilTS1dw== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3RldkS0xQVzVKa1g1QlBZ - UXNXczlsbkx6Y3VWYnNxZkdnVEhkRFFPQ2hrClJ5c1REdHVDRVR0cmw4aUMwVE1u - Sk15MU9Eb0lxSitOTjloWTBoQ3ozL3MKLS0tIHh1ZWxabmw1bUphTWhpRC9YSXpo - S0hnMjEvSmdvczFkcy9PWGdIZE9zNGMKDF9fCBJBEzTMriCM/E0vmjxDG9QBtB/m - DkJHaeUyqc95VD2NzrwARW+A5j38ONEEqyxuVbQ/yvG7GL+vppCkHg== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYN3JDdnVNeGRaK3BjWEVC - RUtVcDVobU1YUGxWSVdJdDgxUzM3UXJ3SkhzCjVHOFRlWWR6bGRMeFNGVmFCa3FI - Ly9xa2NWZGswUitWS2Y1dllTclh1dTQKLS0tIFF5dFpydm1zWE8zeWFMZXRLc2xL - YjBwSTdMZWt1bm4yaCt1NGdjcWtoV0EKKQKEly+FLLE3XEbUIKOHzPUhbeFRyW/c - m3TJS9JnxjCnMD3BqgjXKNp1MwjE1bDnNVVWQ9OjBLN4sxtFr6j/ig== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-07-01T19:42:05Z" - mac: ENC[AES256_GCM,data:pkeZ2OHtPdiLweDUBNaF4TZbVlhL7iAZE3glPtmWETzNVplwq25NmcMMaOdJWGRwgngtT//yytarHoM61NGo+NNSFighbVc6V/0L+w0OaQ8et/Ofz/PMn/D3vj1YdqlCmlUALz8p9AuV2XXdeTvfIptYk1CV8DRnSK7pd8ZhKiM=,iv:1mafJgnr6Rkp+H3cuFp5vmCagXxcCdS48RYXD1dFfjM=,tag:H4S/YYKJVFMqmiXNQhIfzQ==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.1 diff --git a/k8s/flux/secrets/immich-env.sops.yaml b/k8s/flux/secrets/immich-env.sops.yaml deleted file mode 100644 index ec6af494..00000000 --- a/k8s/flux/secrets/immich-env.sops.yaml +++ /dev/null @@ -1,121 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:fJc=,iv:Rak2d4XE/2pMCuyGEJca6uxLqv36vM3R8DoU4dVe8hA=,tag:GtH4sJ7a2/KPTuT1gnVuoA==,type:str] -data: - DB_PASSWORD: ENC[AES256_GCM,data:NYFMIs3KGqa+FSmTNxocB/VgVLcuACpbLlS78WzOZqSsQ4r20I0CPHGFJxhwviImssKoclioH1lhRpv4,iv:HYHD5RFTuKLBNQaRJfj9oW98dtkcvJaG2wjFtB9s3ZY=,tag:Z5ufMj1sOHqr6yfIqAaKyw==,type:str] -kind: ENC[AES256_GCM,data:QtnZu0ef,iv:aaSwJzWzP+UFjMkfnfenzNe9fKhFCG2sWX9hL+IPMm4=,tag:NjyP2ZS2aBjPypAiSKBHfw==,type:str] -metadata: - name: ENC[AES256_GCM,data:3HLdyxDHGcVQsA==,iv:Py1TbdYVO+T4CyercMLwTWYgY+BBrlKCzEcJUIt1gsU=,tag:I0yH1TXFLqiTBBb1poxCWA==,type:str] - namespace: ENC[AES256_GCM,data:ZpYevDpwcw==,iv:VfMwf/5bLtjaxczl5yH5pqKjbtrd0LuWSFVX3n5eRP4=,tag:v4H5yP5AtWh8by/EK9DMDA==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwZDkwalJWSTd5RzNRdkJJ - QlFha3JVVkpDbVpHd0RUMkVicmxmaW1FWUJRClZRcWlxWi91WEZ3TlFwcWVXS1Bl - STdFQlgrcG9HVnlrVmFNQkRmNCtoUFkKLS0tIFJTUk1aUVlyRzJJV0xvc1ZUanJF - OVF6N1V6UTJjc0U5WVJCdVNnQWNvamMK1EGwnVJMM4B7nET+VkQQw5tVbNRFEDGH - b6Y971Bz+ORvDZmm8MUhfiHPTWHwwQsiWr16OtImn94ApyvLu0ljZQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyVlNMa2paV0dTaFZVS2hD - T2swN1VxVnpQSURtNVZDM3dyeHVsQU1WSER3CmpYVzY1UGNPL3JQcU1GR2cyNTNU - TnVQdlYvMmVEdEVHc05aTldSbTNkUDAKLS0tIEhQY1p6M3dQZmxJd0tNZjZsNml5 - Z1RWby8rZVFLaEc1VS9oYmE1YlRlM1UK4Pl/QmpPf+KZCVxjbe1jUfjpOeZDQVuv - VAhzykmc34xl8lIFWhgWHbNEMnGb6ZB4CQbwxFl7JeWPdBTCRF0UnQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrUWMzSG1IYnFTTUhOVWJl - bVRrNnN0dVA2bERaRzZDbTNxQ0x6TEJoZVI0CnZNSm05MFFPQkgvUTVPS2gvVUVm - VGYweXZnUFlDQ21RR1hML0h2NFg5cU0KLS0tIEhFNktTeFlyZWF1VDNzZHdyeE9p - dFhFK2huSkJhMk56ekNsUmxGUEVkQWsKTLgp/XWWHWcZ4ubjEpv3ZF+Nn7J7heua - xgqA7avvFY7bJHw0H2PcsweCnVb7dxd5TJbIZNXjC8I8fZR+NyYJpA== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlckhMN0ZKMEM1SHFCQ1Zx - dTF5Nm1DbFZsK3o1Z1NUSFBYZ3pkNjQ1amw0CkY3K2ZLM2pPczkrclhTOUhtUFdB - Q0VKOEFyWjI5Z0M0ZFUxZHJzTW94WlkKLS0tIDdvM3V0UUE5SEt2SEo0VG80anMz - SERjeitHK1NmOE5yQnFoVDkwTldHeFkKziffn8K/GAmMYHKLSI2ge6Jdstg0PBd/ - mpMItdjcHKMQVtN+2SiPKDIay8W0dwXb5IaanMARf1rE5hphXkcESg== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxWFdhUlQ2YUtrOUtVVXUv - bGR6WXA2NFNDWVViSHJJRGRFSW5mMHVvZEc0ClNQK0xDZC9KVnVGWG5DYnhiR08z - THlSbllWbGdsWnJqMm41T2t2ZGx4MkUKLS0tIGF5YUdXV3E0S1B6ZkRzay9hVzVv - cjM3aDk0elpJaGFlenZ1WUdhdmtRT1kK461gKpS6rZ5mWJs4tGF4zIVutgFoR408 - ykqJXlBzIQZumxouHxooUqf2MaWzQPXoEBH7Gg8//Zb4YSI+4vkZZQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBicFBHUnNuaUg4TEZtOXhn - dldoViswcUxkR2hCNklTZzg0MkNoelVOODNVCnFKWXRUaGY0UVh0SnlRZmVQR2Zu - WUN3SmxVOEswMzNYeDc3bXNyQ0R2bTAKLS0tIG93MGNOSkhnVWF2RWRyNW9GVVA1 - K0oxdnRBa3plREMwTFRBVEROODZrTkkKx2AbW+OiQ0seWQom9h41d1bOMuFNEDt0 - YU6C1a0La1HhekotYFQhakLn/07xPIEWE7Exd4A/wcMzn1I4mFCvQw== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJaXlQR2wveStnempsaXJD - dkZCT0krV1o3VGhmaHNEdzB6WTZkY2RndXlFCjdrbmJhNUFCSU9WNEY0TTAxMXVF - a0ErcWtKMWIra0FMSzlic1kvYlVNZ2sKLS0tIGdoTis5Vnd6a21wS1lhSjIwM0sv - ZmM0RFhrSmJFT1BQK1RRYnRMT1NSOVEKxUkzza7F4V/YLlcNjJkAcjVfUc74NI1Y - SiSpxIlzKABTdhWH+T1duswa2m2tOJ/c9S9SRmWm98e1KRU/3ZMAEw== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxT1diUmJrcXF6SkNxNVNq - ZUZYU2tRV05hQVhndEw5WGczMUJkeEh5NVZRClFaZDZ1Mkluc2NUTVNJQkxIUzNZ - ME94ZFAxZUgzaWE0elJ3b2pzQ2ExQ1kKLS0tIEF3NGlnVE14a0ZxSUJhWGUxc25i - SDJENWxpbU93VXBvdjJKMTduRUtwNTQK/GyR0HzopF+91XwICLAoYWcS+xb2flpv - Esb3AzqnRgB9OJDLAn4ewVuuhTZ9MZvs/uTGU/OiANZAtkaHt10lEA== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLd09FQk82cjBtWkR3T1pF - UWhmc3dFRWdSV3dtVDBxSlZtenlaVGpsQUg4Ck5oSTNWeDBIdmxYQTZFMEFyT0lB - WEtnSjVoWHJ0dHJRVXQ4NXMvOFdZQjQKLS0tIFRFWnB3Wlh0YW5rUmhQQkR5ZGp3 - d21ZYVhvYXB4bjZ3aEROYzZBSXVKTkEKJhLO4oUQs5V/C3sHlT46tr6uhVZIiFAR - tnkGPnQGpM2D/CsTol+OZyh43MgCj/H/M5vxJMTWWzBad68qPy0EJA== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMa3VLOEJiTFlaNGxCVmNW - Wi85TTcyOTVZNUFxMDVkdXdZc293dWJJQkF3ClVwWjBMdjRHTUxENml4R1oxWmVn - ajJhVWRUNm1SWTVrZXZZd1Z3U1l3cGMKLS0tIGlLNG8rU05uZTJDQWNhenNLRkNi - eEs5NjlHL3pUNnlTVGVsSUxsQ21tRzAK3UzpeWtwau1D9aocEDblsm3UvC4u5zfu - k0gu9/fNO7T6fz40C11VYa3IYMPMKhOA8Rkl0FETYgbcxPQGJ+rs/A== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvTUJsajBGdnJUbzVvSkFm - RnczeVdSdGlYMFR2ZHhrcmNoV0FiM1VpUVFVCk1MMHN1OCtxMU1HMXEyYlMva0NW - aWkvTmUydk5zeXNYbi9Cc0E0UmRkNlkKLS0tIDdlUDFHOWxHem5oZVc3WDgxcWYz - MUREQy96dEZyeHZlMGRZUzhxaFVlQU0KwbBKr0exnHqONU2C+oIU+ptSqrn5STRz - Vh8mOdqVZxCijtBtQWAHitT0Es5oQ0mtAoC8IXYeGBzBzZfQhnA6aw== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6ZStXT3FLK29QdGUrSE53 - U09aODhFSVpxTHdxZDhPTDhQTGJrQTloNVFnCjA5QnI0VXQyQTNKcUVmOHpzSFRG - WFA3a1plYUdTRDBwajVMazJsdVRHTUEKLS0tIDFsZ3pzQ2QwbGQzVFBJbUZmbmZ4 - LzRtVjNteFZWV1hBa0p5am1IanNNdEUKbS1yYGoN9iMjDnwVIs1hDHTseOaa/Zkf - XNS8p4iwsfsei2eqVuZTpPLrZDJCJruUAJCUTEbGd6DCVZIHmfsNIQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-07-01T19:42:05Z" - mac: ENC[AES256_GCM,data:WyCYhi5pKkPbBT3BDVIHnYC1e1L1d1El2YRU9R5bU8Po8rEKevKaJI4rCtfYv4azDqf+f5VfwvGqf0LsW0+ZcXP4U9yM9/DdnzVLyVUZ3BG5PuHOI/9LYBlV8LMb2ieZO1af2zaeV22ZuJxSDzd+WvCv2qShT+BFMv8SQxpOQ9U=,iv:GuWeUDyqp6klJWiKlc6HUsaSanHnB1vNgZA3aIiWZng=,tag:TuxMQPSHjCsw4zz9fsY/nw==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.1 diff --git a/k8s/flux/secrets/kustomization.yaml b/k8s/flux/secrets/kustomization.yaml deleted file mode 100644 index 7fdd0f75..00000000 --- a/k8s/flux/secrets/kustomization.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - namespaces.yaml - - cloudflare-api-token.sops.yaml - - forward-auth-navidrome-env.sops.yaml - - immich-config.sops.yaml - - immich-env.sops.yaml - - longhorn-b2.sops.yaml - - navidrome-env.sops.yaml - - nextcloud-env.sops.yaml - - nextcloud-garage-env.sops.yaml - - nextcloud-pg-creds.sops.yaml - - paperless-env.sops.yaml - - paperless-pg-creds.sops.yaml - - pg-shared-b2.sops.yaml - - tailscale-operator-values.sops.yaml diff --git a/k8s/flux/secrets/longhorn-b2.sops.yaml b/k8s/flux/secrets/longhorn-b2.sops.yaml deleted file mode 100644 index f598b554..00000000 --- a/k8s/flux/secrets/longhorn-b2.sops.yaml +++ /dev/null @@ -1,124 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:ngg=,iv:41HQ/aGWe4NBy0TtC8CYWxYMXhUpgcZMUxtAT/zdm8A=,tag:JOOuuXmRFjblHT0xMbhbHg==,type:str] -data: - AWS_ACCESS_KEY_ID: ENC[AES256_GCM,data:Adr0Zs+OfvQ7ZWzXY7LQH97xbcDJA0mqAWHobYqz2Cq+K3xf,iv:7qXo7UqaFXlTxCjC5YBiIPwT0GfkSVTmnh4VQyXT8Do=,tag:6igLl20tuu5WFFro9OTqFw==,type:str] - AWS_ENDPOINTS: ENC[AES256_GCM,data:VeaIGzhNCha0XI1X3wDJ4t783+n5uRRO3UdXbbd4mhEMflDtGzOpL6q5iEj/AU32AFEa+A==,iv:JFS0OTztGRYTOWVwuf9qKohkx+pdsh0mneNBM/pf95o=,tag:xvqjQ0F+Qe49WiAy7eiXxQ==,type:str] - AWS_SECRET_ACCESS_KEY: ENC[AES256_GCM,data:LvOa38nl2V9mZdgDMP2g9VrL7QgMozgRTAe8nknFgnBHCf4yc7XCw3LsoVs=,iv:SB9PESa5djwOPTq0A6LSo4YNMImCImILuJueCoX5xv4=,tag:6Qbg9qIA//4wd6Mqmd2oXA==,type:str] - VIRTUAL_HOSTED_STYLE: ENC[AES256_GCM,data:0gn3WQi0Puk=,iv:fMI5rF9+oVCglWl5ZARfyO8CTSFp1+0hu0jmDct0qIE=,tag:lIQYR4ZsMG3h0IJN7iVyKg==,type:str] -kind: ENC[AES256_GCM,data:HqqvIdOU,iv:NVVSyGMjv8LLqfMGoC/lCZUtZfVrjWrgiBLsxb23AXw=,tag:4LvFY4medr5pP1R4sexBFA==,type:str] -metadata: - name: ENC[AES256_GCM,data:CjlOCKTmpjzDl8I=,iv:ikFXlMzpN5qFaKXmpB85i90GQkLPQMqwAzTWK56Ehv0=,tag:R2pmsvOI4TndZlWewNqSVw==,type:str] - namespace: ENC[AES256_GCM,data:G3sanb10cQvObO1tPqEp,iv:qPyCZMVOeN3wteBXi7MLx5VHxyLfULgnpnastaowJw8=,tag:JlSXChdYMIYyRfbi35pucw==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoc0Jscng3T0RCU01ETHhH - NXg2d2YvWklaNmVVZ08vYmFSbU0zc2I2VFRrCi9RL1hPcjZzVjM3SUxueDlXLzF0 - cU1yalV6ZkVmbFVqUjUrNWs3Y3Zkd1UKLS0tIEdETUEra0J3UUF3cC9COVlxRm1P - Sk5MTm12ZjBnSFdleGF6djZmd0JIa28KzEfGEKeyFGtdLjx2rWaywc9CKKbSSVpm - JmsmdvCHjnE4SwrHwV6Muga9MyDSrOxDLAX2fD14vSbxX8ZSOxBvPw== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqRVphU3BFT3pobTJpMFJQ - elBsaEkxTDZLbnFRdUNNQWo2SHNyK2Nkd1JVCnZnVXlURHhnTTQxb2VVNm5sY2Rm - R3N3ckNVTGZQVXZibVVNbnFFc3FpRWMKLS0tIGtUZnpLNVhoZlM1RUpaZkhVYjJ2 - UXFzT1lrS1NzRTB0aDhVNjZsQjd5RlUK2MtbAPY19CearakfPihc8fbuzAmnj7nV - rYUaGEU1tE2yAZTP1nEhq3LGcWBu76cdH2t+r7Utt/ScYCxoXYe/aw== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEUC82Z0dIcVd1VFc0eElv - eWsrNHpWY1YzYWtiMnBldUEwRWVvbExUaDM4Ck5FcWVPN2xxSEVudnU3eC9oUDhk - ODRnd0I2MTJqdDVuTk1RRXZFK1BRZ00KLS0tIFpYTDJ3VmIyOXQxdk5UQnpqWXlQ - bVVGZ1RleTF3WlN1WEZlNVZaN01UcG8KOySoC9mHRMyq46/hMfB2VCtXZ5EGuVil - tZQsIoP5FcFx6Ec0P2awW0OQAkQQfuewdq7zAbxbegpG3sIwk8Ym0Q== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMUjlUVUdDaTlKandxOEJJ - MXVLNHVHdnhjc3VwdjJGZExIS1UzeDltMUZFCkk1TzZqQWdjdlY5QTJ4bzZ3enFL - QThtbWgwUUFwS01qYjNvczBNcUpCK2MKLS0tIG56Q2hoSXpqMlBrNVJPZnZKTllz - Z2VJRFppbitkcnREeWZTNGV2NmM3eW8KtFTL0UNhXy6nPVGyZESfh54JAO3muBgh - nJOiB1uB5BipAjhh4z6p7DmuXsFJpkMi/7zIxV5bYWiOlusXeMP+tQ== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWeEpJN3BlUFFBTXM0cHkz - ZGg2TTN3ZFg5K3BmOUdNSE1MMDJUM0xUK2lvCjgrZDFNcVRndWlKQ1BiZXF5Nkxn - ck01YkxnRzBZVnl5aVNsbWQ5eVplZDQKLS0tIFNheElwbGJGbEptSGpHbm14cStr - SjJZWFNhc0hTRUZzemxFWGtDbDUxNGcKa5uuOX3xJxR2dxwdtA5BmgXKlcEBNWBx - z7YNde90CS+nB0QiU4lVTj9w4k7IcsvKlhZhd4BlmuKeLcmqhNCKpw== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBORURIR1BwS2p5R0FrN1Jy - UmNaOUNJcVVvbXAxcFBSNmFSL2R1eS83QVM0CnQxeWxxcHNzSzFwakQwVUhxczB4 - Zzc5bE9TTENTWW5wcmJQNHEvVDQvMzAKLS0tIGpNNUxjT3lKV25pNjEydmhkQUVK - REdlYTBKdENNNTZNVWlGOTAvT1Z4NFkKMnwh1vYYEsm4CGCt6N4aVRINYUfHetCZ - 6Mmal0TwGnevKYoZEPDkBa2ijUQpRpiQQCXNOUfSt0XpiGcxAlLmWg== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBISWwrTjlFTlpQZU13Y0tx - M3pqZzc5R0lqSFVJS0VXeVoyM0FqUldyV2lNCllDUHpqSHB0MXUvNnBpVnZxMHFF - UzQ2YnEzWjJHVnF2dHNZOEFtNk9adlUKLS0tIG9SV28zeFpqeXhZWjdURWpJcjlq - dkpVcG5kN1Y2a25kMTN5SUZHN1YrTFEKFbcG5zdEfMHEfwSjgEG5fAku+w20fxxT - /H/JRNVZYyozffycjr+PlkRjL/C6OMzPEkLU0+2Dm7bkyzsPK6SJFQ== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3aHhyNFVPZ3hVSVVWSWt2 - N3RKTnBmZFhnRG9IMGNUUGo0d0FXTWwxTFFnClJSQ3pERTZ2NE9kQ0RpaGdxNnZU - K1pGWTZoR0h1dmpnSDE2QkhtMzY0YkkKLS0tIGRLNWlPQlYzeDlBUGtnM2lsSkpN - QVFpSU8vS2t6R1dvbCtuTTBSb01MWXMKM9GvTkkYPOXCs56BvMLdkxm51PU8v9CB - 2jFICpa1uPXTX7nqzvvHYhxTZkn70dtTElMzJAe40DUtQOw2+csWFQ== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrbzU3N3BKVTJ0ZFNWOTZ6 - cDN5VVgvQ3M1THY1MDgwZ1FaZkE1RWQ0ZmlnCkt2YmFuN1BPZzdpdC8rOGFSazZh - dDM5NlVEd2g4eW95T1Y4L083TGNVS3cKLS0tIC90YUNMRVVrcnRUT3hDRER3YVJH - MWhqb09YSTZmdUpSVGdxMzIwVUVkS0UKxbKOKurlPyQFN8NHKQzf2T3vtvxr6XUm - LZ80mXR7jeQaACKVP4ujBD8nvmeCwy66xPyBHqPIR+b6/TMuxwT7nw== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5OEhHSWFaa0xiYUtoOFJX - VXdYKzczSmk0SVVMaUE5aFRYMVpaWjZpcGdzCnM5MFVXU3ppM3l1S2tCOW9MKzZZ - bzlycGZibUEwcy91Zjc0aWRSdUZvYUEKLS0tIEZXMkcvTUVTbk9tMnhoMHE5TTlM - Q2wwY0N4UjMzdEk1Y1A2QWhTcms5RzQKflNIgBaPC0nxuB8WFgbaffsbQ8eL8mlP - vOTzKvkIEo2DwyY+rznFcp5ROEmViJso5HpjzDSIb7MVu6lAAjmo+Q== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvWXhkR1gxWHpFTWUrd2xF - Nk9zSWZocDZvYzBUOStZTUN4dERoZUd6OVFvClFSVzVRbHhhQ1VWSVB3U2VGVzQr - Qno0c1grc2E4QzdPUENQUVFGQ3JzTk0KLS0tIGphYVBaS0RCcDJQSGxPcXZJWUQ3 - LzlhSUxXU3I0Y3ZjallSTlF0MEk3MTAKdlfJRpz6Naq6QjVxd6Og6v/saGu+0T1D - A06J42uhoVVK+aUEqA9YHuCiTGsEZ3IWbAmeSSfqlK3k9Jdyadd+YQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3dHdOdDBQUDV6M011UUNp - OUlYdkl2WkFkd3NUWHBtY1B3djRQMkk2UkdnCjMwdWpuSExxc1dPZkNjQ3Bwei9Z - THhIK0J0bm9wU1JuMzJHK3VnM1JQZkkKLS0tIGNoSlloaitrNytuZGZsWXVJWDVl - N0ZxZldndEU1RUx0QkpnKzZmK1dOMlUKguy5XOEL48crQLZ4SvmRI2XP/ksx8Ipm - 00qxjXgWOHiVlA7872rCzVdPHIiTrtO+PtEIykmpjc7LZr8+YjvCLA== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-07-01T19:24:47Z" - mac: ENC[AES256_GCM,data:LqvQIhp8t7tR9TJsGeN8USEkpWELPOcgTJyn4hltB8nbUQmal9SCaVCOFOJeaHJHEDYZ7Jwb00dTmAvTzRyaERWroSQXc4r7zncp6OqVwsdtWvgOs/ue8KgLW+rFTwLIDW9dUKGuxaLrqooplJcj+B0uXVIXEWLv0t1b7c6XQfs=,iv:E3alANpPKiTga+j+mAIHh0Qa9v/sYFKK1yXXkeX0a1U=,tag:zFzWIHMfiWrbgUdyj6AyZQ==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.1 diff --git a/k8s/flux/secrets/namespaces.yaml b/k8s/flux/secrets/namespaces.yaml deleted file mode 100644 index 331afe84..00000000 --- a/k8s/flux/secrets/namespaces.yaml +++ /dev/null @@ -1,44 +0,0 @@ -apiVersion: v1 -kind: Namespace -metadata: - name: cnpg-system ---- -apiVersion: v1 -kind: Namespace -metadata: - name: cert-manager ---- -apiVersion: v1 -kind: Namespace -metadata: - name: longhorn-system ---- -apiVersion: v1 -kind: Namespace -metadata: - name: tailscale ---- -apiVersion: v1 -kind: Namespace -metadata: - name: nextcloud ---- -apiVersion: v1 -kind: Namespace -metadata: - name: websites ---- -apiVersion: v1 -kind: Namespace -metadata: - name: microcosm ---- -apiVersion: v1 -kind: Namespace -metadata: - name: identity ---- -apiVersion: v1 -kind: Namespace -metadata: - name: platform diff --git a/k8s/flux/secrets/navidrome-env.sops.yaml b/k8s/flux/secrets/navidrome-env.sops.yaml deleted file mode 100644 index 85b4c421..00000000 --- a/k8s/flux/secrets/navidrome-env.sops.yaml +++ /dev/null @@ -1,121 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:ZW4=,iv:hrx1SdH7M2ymdG8iRp7k8MyuHd20BbKCjzj3a8QNlSo=,tag:tE1bkWtNSliQm2Nhx2pd2A==,type:str] -data: - navidrome.env: ENC[AES256_GCM,data:b9oxjwCPQ1p2DTZuUBFfegj7Nuyo4w+WdmN6oJrdtPect3RmLgI+25ACNQ8v1dGPcl028ZHWaDR9kEMDoQvP7xyp+0S4yhgCWb0Ellm5TB4z8YRu972tzvpLLr+u3gHSd/oRVWcZCAVkezgkDc3QYjEQ67R9qOhX+RCTthbV4jMzzPqZ8JnQgjC07d44n6zECcBRbeyL/h+RFutY+0FTgg3tMExlxhuQK9vUNgiwn01gl8D5VkCk0KidKTTpE1WU8mRo0vUan0So8FEpAUeuMOh8fbXAG2hFf2+YGaQk7NiZTsDwFvnYWd3Yyp///si8pREvPSjIAIn7CmXq+oDqhfC3bjY5na5gL4AIZgCg6TUP30xgteDBdcx5KC6MRAsULziOUxuX0lcI9h1BDwzUlg==,iv:FVqVQ/1LZ9YMk36ajg2aST7qkrPT8ghuYG10XtvHNrY=,tag:njVugcPT3/KHN+jA9y4Nfw==,type:str] -kind: ENC[AES256_GCM,data:zLjrGF4J,iv:BkD1BosHSCsWTSBmXDJccugCO3aRHiEd3PETX2KZf7A=,tag:2o57CsOZBKG7zRxi1oupkQ==,type:str] -metadata: - name: ENC[AES256_GCM,data:3Q4DGsOWB965bU8syQ==,iv:ItHJUogV5NyeZEBg6yZt7pY6zeOCC2J+iNPd2XI+dXA=,tag:ih9c6sixAIlZ9/Rey7f9Jg==,type:str] - namespace: ENC[AES256_GCM,data:kU5VXw/4ZQ==,iv:tr0vsYZ9ZmPS48eLKSjt4/HC/uYF5B0qfMCRrOymDSQ=,tag:O3fJY4fHQjVg7ghWHYSoiQ==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNbzh2SW5naEV3djE0dmhN - cm9PN2l0clRkeHcrRTZXbWhwM0NhNk13RjBvCmRiWk1ZQk5McE1oZUhjOXI5Y3pN - aTViaEtCWnNxaU1VMzV0Tklic0c5a28KLS0tIHV1dVN4ZUdLaGI1QTczeVFlV1RL - bzEya24zZ3AraE1mR3NWK3ZyVHBmZWsK8qUsg8EW1tHJQa47wv7y++n569TrYoE1 - RcEIrmF8AE2qIU6CC5qGXYbot31SdxxntIoodLJY0F5PvcG7vCMpJQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1eGliQkpHajNRS2dIa0Iy - SmpmSThMOUZtZm9TNlVhc2FneDBya0tXZHhjCm4wWTkvVXpydnQwQmlic1hSNUJ4 - ekRzYzh4QXVZWko0Uy9wVG5WL2wvSTAKLS0tIE1sc2VNQVBWUlRJUGdHeDBmWWtw - RVZMMkc0NEdJbGNBYi81elMyMFl6VTgKhMXFI1USvzWVfIKyPXuoL9EFUSyOJAZP - 0y68p6omVwflAGggy1nEljNt4Q41KRxkQQqZGvXn7md0KPt/lxlOUw== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrd3ZYUzQ1dXpkSnl4dFI1 - Zy9UVllpU1k0cG0wWkw4Tk8xRVJMMzE1Z0JnCnE2bFR0TWZkak1nQStvUlB0RGtj - Y3I5VG5HekZvc05VakZmaHJmaGlWNkkKLS0tIE41Qm5EejArUngzUXJtdE9lZEl0 - anI0dGpFazhSNVZPbGdyNE1uTXg0U1kKZvFDpomwql7ArDBEPRA6ccPBIgnXJ4m6 - Pd908IANGsC9D9ROBdX3kIC3JN99lkMLq8r6I1CDudvjufcLhEdRJg== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzaDBzY1RnVmU5dlVxTGo2 - RUxzdW5VaVM4SlovZUtWSHJhREYvZ0Z0Q1VFCnExOFluQkp4NDVkekVXTlZQVTRh - c0ZFUlNsalFUUGk2dmY3T0xldUFocGsKLS0tIENPQmRFQnY1VFZNU3NrVHoydlVt - TEdPY0YzV3N2OWthcWQwRnFmYU1iTkkKJKzZxvMDGqFhxImlaxNkw9NgxvCASf2J - T0vVEIy671PHzpJwuf0PoQay46ZLRcj9Vlbaj63NAVOTmTS053rLBw== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsekZDTk0vZTBBTGgwVjUr - ZDJhQmdEN1BlV280UTlQZ0lBZWJpNFRTbFVZCndGSzE2NFNkMFFhOExUWFE3NXRh - eUxSQ3paRWYrMEplV0I5R3BkM0lvcTQKLS0tIEE0c254cHZFSXNRd1RtdXFPdTlK - L3NkVjc2endITVF1QzY1Rkc5M0RsN2MKOyPqJUCoz0spsfjeIe+p5uJr15J13qsC - 78CCplO5S+ggzisxtt9/KQCUvlgn6zN5hBuPLal4Y7Yr6jkRvYM6JA== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSckx0K0QzSG4zWGRDSmVN - R1gzTWdzazJLSnRCQXFubTlGbGF5NGJZMVdVCkZhZHQ5ZzA0aFN6c25sVkplRHp0 - cmMwV1F3K2VRYUlyb3ZaWUNtcmlnR0kKLS0tIHpLbnZSd3R3c2pyNXpBNTRrYmdt - K0RCWGw5dzhuR2k4SEg4TXRTWHF1bDQKEcBO/Qu//0TgBoTL2ee/TNcmlLc56dFR - dV1VoLJBRk1AZ7zDJwrS5n+i2MThahIQNUbiXfza2TIOvtKOre6W0Q== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkUHZWVlg2ZVRpTmZmeVBN - NnZDM3U1bjRFQ3dSaU5GVnFRYjhTclRTbHpzCkZrbmIwWEZiUGRDVFBubFlRVFN1 - RTRwU0cwamUxWWRUOThZeCtlSmRJRHcKLS0tICt3Wk5LblZPZWo5ZUJtNjhwS1Qw - NDdpZ1Z4bm9PRFRNaXdRSElwL2J0SFEK5ae28lLySkFkaJSr6KJWhRtugaek2olU - /q6N04n9JqHhTDUMZesKGpahZqfPyyVLnsupUsmv/D6MELb2Orb7Hg== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvNlg5aXhEY3lJQlFTU3NW - alRxVDhrbEZsOW5ucHJhbTdVZ21Wd3JJYmxJCkNmR1BOQTExb1EvK3owczRJT2pj - R1hjWlkrOEFmckx2bjdXU0llaWUwS3cKLS0tIDdKMVQ5TEI3NEhZdExzUW9heWI1 - NExMb2dBbkpHdm5IZzMzdUZxVjhpY0UKIoWyvOvHG5ar4itxvi3pbzNPqK4D/3kg - zl1kByeMXcxB0nayHEYJhoMpzH8KFJFiMO769jyG0qpAE0EUenWyeg== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhUHZNQ0djUW1ac0czOGd1 - anNPSTMxdXhmNnVjYUY1VE56NjRyWUpSekFrCmhHeDRkcjVKNnl3bHFmeXNIazYv - TERMN1pSMHVISllOZzlWOVdTS2xFNWMKLS0tIGxnVWhSSHVmTWpKdVJvdlRpaWEv - MTJJVlpJQXY5OUYxWXJRTk04cWN6ak0KRV/5YZowzl22U2Yb2H15bcq3g6/2U3aO - esMqQma2EglF30h6MG+hZy0UXS7Jj5bmIqYy41UtyHl0yfrVPZp6Yg== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxMldZTmRGVUlvb0VVbUt4 - UDQrU0crUnJyVzZ5TWZnNDQ1M1ZQWjFrSmo4CmZkRjdGSFRLZDlWWEs4ZlBkMVN5 - YkFKQ20xVTlnY3FnWjVQS2FvTW5MSmcKLS0tIC9wN0NCd0ZJY1hoOEx0NS9CUUVX - UHpnNmM0UG94dStiVzAxdXhCZDUyN0kK5FoCUlJF/243Aw58udPl2EHP7eo9TEN9 - Gmkyg0taFD1q4xFfT30tWPlXic0n5GFA9PQ/3jJdIH+eBq2ie5PxiA== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoM1djdVJPZ0NlbWs3UVJN - WmNIcEdFK2JDRGRLUGZ6Smx4QlU0U2xXYVJjCkJCbWNNWGNTaDVGWXZqb2JtZGRz - N1J0dzR6NGhsb0xvb0tSQzZlY1dLalkKLS0tIDIwWDA5b2d5eVlCQlY0SmVZK01C - bVFVVzJLZ0JZR0FFR0pOdUVaSHB5c3cKeIS7AubCTHBjaRNbT3UlegAvFKgU1RSI - uEsnsoKPjQkHSDZobGJhBgg70PR4tquxkFOhJAETF3y5DzIPGKdE/Q== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsenFXWC9IOU5pWDZoQzdH - aXBQYWJJNnl3aW1RU3VQWnMrcEMvWHpiYXpzCjByeW12MFppdk1GZ0pnRS9va1o3 - QTgvaHZOWC93dit4U1BFVS8wSW9HaXcKLS0tIFNhZGtEeVNIdWZ6VzJFWEQ3SGph - Z1ZiWGFXeERGSFFlaGViNExtdWp5aG8KSoam3mWuH/jffm+8X/wY6D1cPqomocQh - c7Rs+fRkhtuvl7Yh3goH8sxejlHT7/y3YaxP8jz3/GVnXS7mXxrkfA== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-07-01T19:42:05Z" - mac: ENC[AES256_GCM,data:sv1Erw6bjpHJc8jbUYMjaOzTfwJ2aNJMfagxra7ag2lxfi3ngYoJGwbHapKQknkqn6sjMSA5SNqpdM6if0XHDapGjSFMPFloFoGifabo1h87NpESqbqPX2mgjuQJ4LNDY/D1RTMDaOkh+p++lVNsrtEI5RJAGWSWjLoa+BUq6mg=,iv:sLlS6vauB6IunBlojwSItvSDARjkYePzKpPHA8SO7os=,tag:yHtt1YyyKQwecU+YP00Fyw==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.1 diff --git a/k8s/flux/secrets/nextcloud-env.sops.yaml b/k8s/flux/secrets/nextcloud-env.sops.yaml deleted file mode 100644 index 6b6845a6..00000000 --- a/k8s/flux/secrets/nextcloud-env.sops.yaml +++ /dev/null @@ -1,123 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:t3s=,iv:h/i7yKXXhiVRmCSD/UopqnIcEHVm0mWZuw7ngf9nXHA=,tag:cmnV2eBzPomYdW3WCOA64A==,type:str] -data: - NEXTCLOUD_ADMIN_PASSWORD: ENC[AES256_GCM,data:vqEfboo5x/Q2DHJhag91ZiSK1atkPuEmxjngaM1a5v8YAAKxGcXDj3JTuH2r+iOgz3cM9TVocQ9uA6AVVChGMA==,iv:uyaTyQWsCMTrI2PDduTyYfXWS7U6YJ+oY0KdxN/VOeY=,tag:QOynD1IEa2x6Y15YN+SI4Q==,type:str] - POSTGRES_PASSWORD: ENC[AES256_GCM,data:N4GdEDGhzLkUhfyosthFq2RoWeOhCd0mzdmXXuMd1Xqdh6jq1ccZYO1C2fCU36Fi7MumkeyzmNbnJ9JweTKUXIzCi2a8B/RC6UTIiaXmYUZ0aRKfJIJyTQ==,iv:j8r9Cp/cvfFs27zNLkB3HG1hnhwvi40gwfxt0KsB5BY=,tag:XWyNUsUykhyh0IaxCQ9bvA==,type:str] - SMTP_PASSWORD: ENC[AES256_GCM,data:iUBie6pwdHfNmjJpYT0ENZ8OG5yRfyRLgKiCK0cjVqxoh+KXCuLg+8Q6Axkj8sCV,iv:dIEg0c2eFQUxdyaDPO64Kfnh33AnE7MGS4BQqxHEwUs=,tag:dFNKatRVmjckhbi7dM8rKQ==,type:str] -kind: ENC[AES256_GCM,data:uSHbNk6Y,iv:F4CwlA8zsLAtYo0P3UP1jvUQSyI1PR/GSTV9oyzeznY=,tag:iTlCglEf/gY+kKArXvlLgQ==,type:str] -metadata: - name: ENC[AES256_GCM,data:xNqmQ5PzKQYtQ/pjoA==,iv:lVvKi568ny0F3yqca26mDHCOekKOLI+e9dzFEK2CYho=,tag:2AbNNAx+dW3Wh6cMCte6Tw==,type:str] - namespace: ENC[AES256_GCM,data:2vqvsmF9lUzC,iv:uCU9YeZGdAsoP1wzPJZ4ixHYDruO3e2m8HtP4Hk+qBk=,tag:Yi6m7YRciHxdSZG7yzIy0g==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsd3JRR3N3T3JtWm96WHpi - NlR4SjlHaXRHbHFkSHJ5QkdLSGhIUHBnMWxrClBvaGwwN1MwVjBzTWF2TWMrM3Fw - NUJqeHVBbDNMSm9QWDA3Ymt2ckRBeHMKLS0tIHdpR0dSclFzMVVsVlRKbW9KRzd2 - R290d1Y0eUZGZVUwYUN0a0VxbkJkbmsKsKT6YxcGK5RGtIE7HwbSwEa3Jdosd7V9 - MJ8TysoLVNQFD/OiLukNY1/jSgcSx+Kie9o7WObh+GHnrhR4/PqUVA== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJeGNEQjh3UjdCYVFVeUk5 - UFNEd3FKSjhlRU9WSlpXTlExVDQ1MHVaRUVrCnB0RCt5bUF3WC82dlRTZUhKOVdp - cWdCT2RsTlFOWTVqcEg1VHRZb1FJaDgKLS0tIGdQTnZad1FCTTd6L0FDVHhjaTNM - MFpNbE5jc20weWFMVDJiN0MwMlFOZVkKvZEJnqSibuNfyE/4tn5vbPFINtfy1dxU - TyWbyuVKfrIMXLyR1yay27B/eQOvMWwYrDMzOjva6BDQQwZ/pPS0nQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUUFRndzFodlRucEFyZjd0 - ODBsQ1Mwd0VTejltWlE5U284cm1jRk9zUlhRClJUM2l5TmJUbTg0OGdzOUxXRkw0 - d2piUTIxbk53RUJINmU0eTYwKzBQOEEKLS0tICtrVm9VUm9WZFhJZGNENlI2cm8z - bUQrc1U5NFRqanlHckhxL01hblQwd1UKsyZsjlprl/QRNbHRiI0ye/9XYjNhQ3v1 - cC6+BjrMXccerT8T+qroKZY0NbxEZDJPePk3Ju85Fj55pGbbVq2trQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHdDkwSkhCVno4d2JhbXlp - bTdqK1lyT0JCbzFCZEE3anF1bjVQZEdiSDNFCm1ySEJUMW9NOXBnTjY5TkhZanJB - NWhmVThoczg5cjhKbnpvL2IwMDg0amsKLS0tIFhqY1h6Q1ZaNDF2VlZxZlprcTBO - VExDWmlwb2lpSVpYUkJKRlUrbjJoZUUKcUzAixIVmjP+VklfoLJ2VbUKyThc9AD0 - HXKYSSCZsGw+PfUFDn6qyI7+6hC928Q0iJozJKNF/c7v7zTWkVayxg== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBMk9pS0RxVWVBK0ZMTVVK - bzRTTTZGeTRqUzJycXVjSllpeVRpOWdFc1hNCnJ0ZjhDQjZTOWJFR3AvUlF4NGNx - WURNOWFjeEhSbFhFQWNackhDZ2oxd3MKLS0tIHQ5Q2tTOWt2WHhwWjV4SDdlbkNy - N1FPRkhMWmxWNFZtWVhjQlQzWS85VUEK3QEgk86kirUfXXfjrANx9ngPD1qC5Egq - 6shIF07Ubj2+iOf2XQwVnLRmfwlmMK/LVR/blf0bDY1d0J7eGSxrKg== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUTW9id1c1WE5ySjlYVktn - ZXJnWnBqMkFCcFYzVjVlNFFiMW9tTDVtZEhRClVsanlJdldXQkplejl2aWFEeXdZ - VVN4d2wyTU52MHRuSndJWGFaQlRCWkkKLS0tIFZ3QWcvWU1RZFFWTGlXK1BNNk0r - Nk9wSFZqTWwzS2E0NWJoM3dzVDNSWDQKkLN9QB/DB0dn7uQqG942QHfrrDWzuRxs - hJgT42QL56tU761EOrkMzfoVJqGBGRBOGPw4V7Ip/YSlAf5+rbeXEA== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjNi8vdmlLOC90YkNEcHN2 - SE1oLzdCemF1OFNtdGdFbEs5M0RURHhSMFhFClhhdUdLOGQyWllubnBNWE91ZnVz - UXE0eDdKS1U5enMwUTRxTXpJM1B0M3MKLS0tIDkzNy9VSjBaUm8vamt5QnExT215 - bHFYZXFGRWNqVWRJd1lVYlBNZEJSM0UKmhYrgZEowbP9wjGGyFe3fIOIZeDhSZqh - hQL3/+0OP8xhQwhrA1y/BM2JP3332Kf032gtgArP/FjQ+hr5fM6YHA== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByRTFRbFh0ZHFvQjNCT2V3 - NGdFM1kxNTBIOUlISzJqZDdseFlLNzJLK1VNCllTT0xpVjFGN0hrRk00RnptTkpQ - ekxiODNFWDUxdUp3Sm9RdDdHLzFFdTAKLS0tIGdxMjQ2RG94RTdrMThGdEppOXlI - SVhXY0RSd1lGV2RRZmhhM0psWnR0M1EK/rh15lwk77aJTI6ej63V8Twf0ggnPspe - aK4vXSIhGExaKgmS58EKF6Xsq5ugWv3NAoTMZf0Bf9QT+d85/6aQvQ== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJZE52TEYwR3QvbGk4RjY4 - bFRqdFpjcktQVVVnaVlTcm1xYWRvUjd2eERzCnZ5ejF5a05wbWlzWUtuUGp1ZEdY - alJsMVVQVFJIT05IdUxJVm8ra0haelEKLS0tIEYvK3BGRTJyeHhZcjczb3JFQ2h0 - WDUzYythUkNzb0NQb1ZGYlpVRmhZVVkKczjgYc4zdVnEobpPqGwORtxR6R/tFMIX - By07XVnlQkihGiiN9DPDskGLkAznNqejcsF7/mp52qEUFu+Bwgakxg== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvV2pUR0hQTmo5QTBHQ3lu - VlBicC83ay80Z1hrNmFjN3hWS1I1L2p0U1ZvCkNRc1ZSN3VFTUhsclUycTVmUHZZ - TStOZmRDZkFUYzlvSmZxNzZIeEE2ME0KLS0tIExSMVVHR3ErU2dPcU9TNE5wWWtS - cDVXZFNuUDV5cUlPSTRuUGdTd0xEdVEKlfUm2aRRbhrvFrb7CdLyV2rrPZ2yulJT - bYcewQflIMc29y8ooDKdGzskYdB8ozDnqxarv2K/I5YVjLgiX2VVOA== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEUTVINCtxdXVmeXZsamVQ - aHNzOWxHYTJ6SHR0OWw5OTZpUlRWWXd5MlVBCnRpNWhZa0sxSmhLelVrK0xCRUNS - SGR0RGJoMmJiQ0lsMk5VM25tY1IxcGcKLS0tIGNVQU1PR042OGtqVkJXeUVNd0hu - akk2QmMwc2l4di9zTnpub0t1a20vOU0Kj9BKZgH03Vif4cduUQEqBO8qwP7aLuro - B6RCLGuXlAYFxC6eAS1JJ4SWkSiTsTbbcfp06Ua59v6sXihFaJ8T0w== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwWGlHRVFtRlplRmVURk5r - OU9KbjdBaHFoWjVFdFFWQWNIVmdTQXBudUZjCkJDSkVhV0VPbTBRYUQ0dGRuMjhV - cDRyQWV6MXYwREJvVzluT2c4QmxvamMKLS0tIHZCY1VNNU5BcXp6R250N2tacW1o - YUswbENibVVIMTJOVWoraEZpSGNWazAKXWirM43zI+eL32+Wr8nw1Bdgd7e36igq - cO3ZefmLl4yZ/Go+qC2ldtfRUE/0hrswh5OthdTsGDX5MYNIstIq2g== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-08-04T17:38:48Z" - mac: ENC[AES256_GCM,data:Vtq0cZ4EDK1rJqRUptEK5SoDmWWForMKTG67O8tX59rspGm+Xw4P7D7hp1JO1GEnXtMTfVqiAZ1GI1+cTsbo493AcP+sXeJ/XY30UhCmKuc1S2phn/ATNXEYF7HhYlwJCiYvPqFW9DWEbQI3n1ROSw9+OsySfRWKcWXu1FdLpN0=,iv:5m0p8so12JtVQb86n8c9VReJwstkvcYoJeNtq8aum3k=,tag:VublqPwa4cicFcgK7tuTLw==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.3 diff --git a/k8s/flux/secrets/nextcloud-garage-env.sops.yaml b/k8s/flux/secrets/nextcloud-garage-env.sops.yaml deleted file mode 100644 index ac85d0ad..00000000 --- a/k8s/flux/secrets/nextcloud-garage-env.sops.yaml +++ /dev/null @@ -1,123 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:DRg=,iv:E3KfR63hsZ7Ps3V8BiCLPww+UVGARykeB/OikuEkWiA=,tag:mMnI8lfRHzGi/vX0tMa0aQ==,type:str] -kind: ENC[AES256_GCM,data:UeY+WU2f,iv:eRUpY4ID6VBrLEcCYsOYkswoOVB4LGXuyyiyo6XxCIc=,tag:jh1FG1Pror3BFAswIASw/w==,type:str] -metadata: - name: ENC[AES256_GCM,data:0YFSrDLLXu/xUToQKyRG0KFp5Vk=,iv:9CT0iCLjducy0FeDyPPCO0r3+3Vc4CAUeRfINNe0+lI=,tag:O8rwwnJX1NkAzs7aSkVLEQ==,type:str] - namespace: ENC[AES256_GCM,data:DyB8hii8m8Uk,iv:H542zPCodvHyv4uCBMDPZE7oJ4ND0lpow7hwo6smits=,tag:IEQOlWbxkMDNjmp5f5HaJw==,type:str] -type: ENC[AES256_GCM,data:6v+3Xzkm,iv:tM6UMhf49aJFbQUg645VaVqag/nkrInd/WIAugIUhPU=,tag:XnKXXSEBshcapYs4eCSqGA==,type:str] -stringData: - OBJECTSTORE_S3_KEY: ENC[AES256_GCM,data:Q6ZeXMKza9CC7/hNlO/ArWAT2nG0D6VPnq/dJ7iqQKhdkg==,iv:hXAh4SAsgw8gQBpoK2xYsp6sSA8GUEZ/Ldl5A5Hn328=,tag:NuqTKtwIVGcoYEHRy6pQhw==,type:str] - OBJECTSTORE_S3_SECRET: ENC[AES256_GCM,data:rl9IoUDAEM7Udi2HfYoRLuMlD0Vw0XA1qu1Br6kf8A/57znchGm+pT0b/N8+YyRk/VK8nd+V0b7hKL5oR8JiyA==,iv:OFVuehlHqwhMu/GM7Hnps3G7LkJyIjSvqyDSuxaBfxs=,tag:gVYgRWKHNe0V8RG2iZnZNw==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQMHFmSjBPcGRVSi83RjZV - OEIxazFJTmdoMExxb1VkTTVNc1pNYVpPRkNRCmV2RkEvRmhmOG9rSXBLWnVxd2Jj - WG1rMlhVUlZkTmlPNWZ1TGZWZDJwcVUKLS0tIEVhYmdOaGtNQjJMYmhWQk5weXpk - aFExWFdmdktVa3gyNmlvNEJJcWlhNVUKJYtRHF3oxnxm3Y1aIoqldiRKcQf2YDw6 - 34sWQ17jEvAT4RtxqHzg/mVV9qnNgmaNypkabq2rB0zFGuwCICUClQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjSHJlSlYyZjBab0dhMWtZ - WlpnWUd3Zk9iRHpFUUlndXJBai81aVJVSEFrCjJ2bHFWbHVTRS9waDFESE5aQk45 - NU1vZ2tqYTVoUmQ5MTl6Q1VUR1dURHMKLS0tIGNHcDU3WUMrQnU2VEgxSnBPcmVx - K1RlS2FoTTJrcTVVQzBMSHExbmd4MzAKjzLnb04UO9ARAjEesdeBaCVSQIOy3XWZ - nKVgBkfWg9yM3GVKMmu1252sejIEsesZgaj1uyugC1Y+jPJTbW9yOQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5ZVRzRWFYSXAwSVRGSTNp - eHRlWmVyaXQxNUZSQ0VNdGszVFM1c0xDOHpNCnRmbU5udG1sSURZQ1ZJT08xYTdX - Mi9QcWdTKy9qT2V0cWo5MjRPRkRiWTgKLS0tIElvOGJQV29Wc2MxckxIT0t2d3Vx - K2JRb2NORnR6ZmJqYk8xY0JxeTdtRlEK56BAMgvQ5lFIDA8PIQ79s9krcNS6j5PC - TCeU54CjKGRgROioqtktwNHmN60luq9UvbsFuIMeiPnzoybEhyeU2w== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBTnVhTTdVOW9weE5GVmlF - enlueU04MVZWbnNFemJrdnp2eWoxektySGhFClpFVkNqQmZTOHJ1dTgvVENkcnBi - Q3dlckpOTVBYa28zMmxVT0hWeVN6TW8KLS0tIERYdnpJMWVaRThNQUxzUXNMRjcz - VFM5d3JqenlwR0RpK2EwVE12SkdlRUkK1jnexFW3CIBFMtfePwAXNh2OBbp9ACio - FZT1x1X8sv2B8umeQvVwHFWHDuIciI9GhYDv59GSy9iWkzLmX6iK2Q== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkYkpMcEtDTUZ1YU5mYlFO - VS9DZlVpQy9QRGJvSHcyVWVGaWYzMFl5Tm1NCmoyTjNPVHpvbXk2L1dxb3Blc0Rz - NUNxWXh5bVp2V3hTS2NxSENTQnVOdTQKLS0tIGp6eFdVSGJqWFlZcnc4VlRQcytK - UUs3blNCdmRFdFlSeVJ0U0RZajFSVXMKfmM0EcIN2zyjsT4VPLCTsSYMbmyQ5pNH - Lh5yz51ahQzRcORfo7dopIzOZppOCqPHlzkp8YANxxIY52VePsO1ug== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2bURkRVJxbGNLYnpERThi - VTQzZmVRT1JrdnNsNXc3cmpKWVNTRFlTdVE4ClRkL2I3RjdkRCsvLzBxU2tyajRl - ZjJGc3hRZnZ1eldxKy9WRzRmRFFnMFkKLS0tIG9iZ1RlYk1yMlAvT3Rscmk0WUY5 - V0dFWlJnTm9Rb0tETko1OVd5dUlDWmMKlfNIp9O2+Sbd1g5BfuT5HzOLgFq8JM5s - Sx5FAxIOn+vJI4s+XE1wYxJEjFD0apIJCPOi6Lph0Eu3aKOT1OmiIg== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMUkVybVZBeTJWSU1TUkQ0 - aVlKL0Q2NitXTURzYTkrdG5yRmVrOEErQldFCk8xeGFUanl5Q1NMelJaUlNDT3dz - ZXprUlVLeUdZek1kaE9DMTg1bGVkWGcKLS0tIG1WeWZaYnRIM0M0TDFGMHNVcjRj - QmxjUG5yY3BFS2ZTN0wyZ2t4Wkl0NU0Kmm5zzLBQRkNXgi4zZRzIL9q8dzuEwIs1 - FJC5BHbXr9rCYX3Eue42Gk3WGNE/We3G6WuUdSDkR35XoEqOf/hxlQ== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVUExxNW05WExVRzdpVUh5 - cS9NRnpaZzRjRDd4Q1dSYW8zM1hEcERUMUhNClFST0M0c0FzUElLZjZKK0pKNmNw - Mi8xYk1ZemFBMk5rbExxQitJT29uamcKLS0tIFlzVURFWlhtb2FCMDRpWDM0T1Ro - M3FjZ2t0MGJLYmhPT2lpT3RJcDh3Y0kKGzTpcisttqHoEnMCQxZiAGX8di4/7yL0 - pDLEDg5eFAqIXGulupml+Wyy37aA/fb10jMC1SCrPY2GiBk5c0KWIA== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxeVpHUFFtREovQU5Rd0E1 - WG1nSnVaY05JclQwMmxzSjJnajhQWi93dVZjClZTdkhjVTFDaHkzdkxvSHVSZHVX - dGl4NHlyWXN1MmVIdjhRTCtOeWRLZ00KLS0tIE5tYkxhYXFIMWkvdytxeEdCSG5H - OU1UNVU0TklQaDN5MXhZK0RlajhVcTQKT39/cH6kuTSySUq2cvVgaW6S+BIjCpLg - IuvPK5bQZ9aa1d76etLOaXpbrKyWSr+RLPapJhIbNM9p3GA5LC/XZw== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXaTRnTkVGMGpqMkE0bFdV - YkRMWm4wOERXaXIyRDY4dnd6ZTVJRmkvNXo4CnpOM3pmandZbC94UGlycWRSMWR2 - NmphVUJRanZuamxyWE5JbG9pV1o1c0UKLS0tIFY5WjlMQTdYVnV6bnlBVWt2OVQx - WU1taTFoS1FtT1dlZmhPRjVuZHMxaTQKNGWAo+LckjL2uDf/UFeceC1KdaA5WwfZ - fJ+3/USoe8OERRiG/KpSfySXvY5S3LhS5G0NxTG9JyiJYSnGCiznHg== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrSHJsbC9MU1kyN0dlVDZl - eGQvS01Way9UdjVhRHZkVXZzaGFDZkw2QmlzCmJzRUU0cmZvZTNHU1k3VWJRcjRE - U0dPOEcvY2krSDcwMUZLbTlvN0dBdmsKLS0tIHlJNFVVMUhIcjl3TEdpd1duQ0tT - TzN6QmhLdVBVWWRxQkV2eGhZaFVOeVEKZkG06zeoTCYDU2v3L0eSBPWQf7+3yxy7 - SguYZrKk1LFQWWUGqpRNzy+sAZx3rDgB+OGvKh1Zx0na7ZB1h4wayA== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjbTdrTHhYV0hXbnhjaXk4 - b01WUmhNMS9RNXVpTmRuYlNLYlJXKzNXM3o4CkVtWkplcHNONE1uMk54N1hJTWxj - VC9SZ3BzWTlSTkpTQ053b2ErTjZqVE0KLS0tIEo0UnNtUjREUXdPdTE5eURTbG40 - WFRIQU1xeU5kSkNvbncrdlBTZHlBcVUKHZSGTUfRrJPqaATqftgjsPJxKT1Ga3ng - j/Aqf4ZLd/V1aMJ1HrqaYu+4mJNQFESeoxCQ68eEo19oKSjgNYSt7Q== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-08-04T17:27:50Z" - mac: ENC[AES256_GCM,data:QqQZo6CvOnUoJI6XQrHzxghMrzInCOYdwVf0eAtY/4JBg3JGLibJJ4w59M2oqfXqGVSaCiBy90+gqVOhR3pEbXMax6VJzpdXqrbc8uiF4Vfeda1u4WTKLRv4T6naad9aQ0TKyGY1P6284J86K5H88BzuouCjmMA2qAnTQ1ZLO34=,iv:OBx8RYZPbChI5jWCFczHOwnLcI8DYNcLwjYZXqZqfcg=,tag:AXLgbBuid79RhQrar3lf2w==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.3 diff --git a/k8s/flux/secrets/nextcloud-pg-creds.sops.yaml b/k8s/flux/secrets/nextcloud-pg-creds.sops.yaml deleted file mode 100644 index 2dbab4b8..00000000 --- a/k8s/flux/secrets/nextcloud-pg-creds.sops.yaml +++ /dev/null @@ -1,123 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:SeU=,iv:+xLfctHa6LmnQcS+s4mixZI5YEcYkSXkaAyNToBj58c=,tag:WqWTlfJmTtflcSRDy5AIQA==,type:str] -data: - password: ENC[AES256_GCM,data:sB6J8TxSGtEPSxHA6SEk7nKS8BI/Vvm5t8xMR2Krp+MnLw7grEAScg4oT2M46fRmaZ6ZPnQ+ZB8IgqpgrybRzcVE0Ih5YKc4C7y5A3PyQiJpcKcqL1/Yjg==,iv:Hike3bPiEmR7irOzkJ1ly6WRJM7LyG5B2tKXtEOfGJk=,tag:6aijS0muzYA1mIv4jd0EwA==,type:str] - username: ENC[AES256_GCM,data:oJ3wHPu4yE5sqtOI,iv:WeonWVJVgc5hcRo+2KXODFvON89x2PJ3pdhhFdXlBd4=,tag:nKouoRMNJ/JioUKJBhKmhg==,type:str] -kind: ENC[AES256_GCM,data:h3nsqKGI,iv:A3YvD6d8sjHPKH44wXdd8sMgVD96WCpnTHbmATmHvpk=,tag:7bFvcAssxU52x9iTLsX4AQ==,type:str] -metadata: - name: ENC[AES256_GCM,data:rM9GmAJuGDPMpzLkUmPe10y2,iv:jwZDxAyyTzaNG0F/KlKzNIbI4HnoH1a9djrICrv9HEw=,tag:HSFTz4qp9FVzZlU0Kr2KoA==,type:str] - namespace: ENC[AES256_GCM,data:OUOohNnrvrw/3+E=,iv:IVNXHzWllAMPtL5k7RzHW7Yxp5MasYx/CUQNKL4lWk0=,tag:56OGsYoQo8TNtlMbQLdXHA==,type:str] -type: ENC[AES256_GCM,data:rIJdWiEFlXakce7/mauOOvrMETLX32Gg,iv:kLesRy08Je/Az8x7lg1q6J+x3Ur0R9ze2bxaIKtRgnM=,tag:898hhLvBssFNetQicLe56g==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIOE1DanlubXlINjNqRzZo - T3kyb0JzNGp0NnhDWDduRlAxbVdJUzVlVW1jCkFMWC9FRmlNWk1lQllQTzQ3b3Rz - Z1RUeFZpZURyUTZ5Rk1RcUdxNEJQWXMKLS0tIEduaGZqenpBTGQwZ2x3NmI4bkpQ - b1NPVVNabEpmUjJPSGp2MUFNKzZRdm8KfKwJ7dB5w12q+46M/mHFEAFC0Y73wXOB - VxLpwkWhLoPDZsbcNUI4kldrUHwiLhMG1S50fedfGu+FSFp6p+z8dg== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIVTVheW5OWnZObDNraFI2 - YisyajhURDVIdzRzcXBUZ3ZVSGIxbTQvWDNFCjJCYStKOEJrMmRUZkJXMGE4S21K - WDBZSEt0M2lqQ3hkdktEWGo4eTFqRmcKLS0tIEVWSmFLWlkwYi83TFlzUXIzeGYr - STJFSGY5STVDR3hVZncrb2NQRmlva0EKB2F/HDu2wyMSYeVCSGgtLS53fmUIvMrz - sTPYClgVo8lcr2r4U0jKFa6V+dg1zJrS2JwaiJ/7WhBURkRysyT+GA== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFaVZ4S0Y3MWp1bDRCenQ0 - UEplOXZRWHVVVzl4SXd0NTZlYThBMmlBcEJNCklneWRmanZkaGw0dFZET3Y2a1B2 - ODdWbXBwMWxoUExPUVQ2Snl3Z2xCSE0KLS0tIHdsVHVValp2OHNONFNyRnBTazFu - a3RpTXg3T0R2Q2czbGFnU0F1MURpdGcK91sA9n31cFwnSlws38AowxKj5fKh4FZI - q54W6JZzAVNWIiMPZ/gbRuV7N6jj2Zw5nD/1F0TUq+JooABHptn1Rw== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiajB2K2hXaTcxZ1BjTDcr - U1VZQ3Y1NEY1NUh0WHZRa2hNQWhvd0JRQ1g0CllXYVIvY3BQaFREeVFmcEFLMENu - Nlhyd2ZnMlQ2QmJSR2xPbFpFb1VEVUkKLS0tIERUNS94c08xR1VyVDZOaytzcVdr - ak5hYmhtc04rc0JZTHNRdG5lZHdmb3MKjLHklmb9SAdip1ZHFJZ32qPQbfg2a7B+ - 5y5LLJeDQWYPlUmdjaGCi4Yi8t1cfflFwTsssM9FhZTO2CLC4XfADA== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpcStNREZPUjc5MUd2b3la - ZlQzNDdZZ1paY281VzJtZzZYWW9mT29SRVIwCkUwQUdTbFF1K01pU1Z1akM0V29J - MlpJL25LaFp2RmkrSWdOTE1HOXR0ZGsKLS0tIEFEWnpOUEVNMnhmREI2QkUycmVy - aGtqdmJBQnRUN3NTaDZVWG83UHF6bTgKJTYdjbd+MoqO/MrPTsLD25MaVIuyRPN9 - chJLE2y0wYNbge+R7oGgRk3PG2onqY4jkcQfd7cyxSzsFDHgezJlBA== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaWG4xMmxwdldMb2lqQkps - MHIzQ28rbkhnU0xma0w5aWNLZEtuWFNOd0VRCkU0N3F6aDE1K1ZhMUVuWmR3akx1 - d3FnN0ptaXNnb0RLb21DQkdMUXpkT3cKLS0tIHo0SU1mNyszU2hRdWRwVWhXYkky - MnFCWUlNbHRjcFl0Nlh2alg1d3Bvd00K8ASk59tnawqPCFdI4frTAKNL5kg+ghy8 - aUI/r/ageivsDfGwi8Xs4CSirVaH53XJtKAMkgw50ZOF/xDy9nfk+w== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOUUlwRE9kTC83U2swMG1L - dUxEdXpuYkZjekE5cEhwRFBROVpCUHFnNFFBCklwNUZDUVY4M0ZRa3BXcXpKVHdw - enE3ckxhUXdmMkhOVEFFcFZNYkxnTGMKLS0tIEJXbzhSMEhpZ1dteTlPNzZlOTYz - WEdqU0RGVEpxRGtQR1psNHdDQTErdmcKr5uwL0gtkGHMWeq06MtH6wSI67EhPjwa - 0vAtiGGhNmeo/Byl1iVJyfUB47x5qQlzT4HR202vibMnju9PY4oh+g== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtekpYRjJGdHgyRXNpT1Bz - L0YxZVJieGZRZTVCMG5aWkJ5QU9FdThpK2hBClFiK2V6dWJPTTYwWENjS2ZhUGJ3 - Q3dzYXp2WHJzUGdOK0NESEJWditnVTQKLS0tIGpSOThYNUx3bUpKSktpRDY4dVN1 - cG5uM0RvQ0pJM3dZWXQzOHl5MGNqTWMKhJAlrV2402xEI4wH6YELdIXtwQ+021y2 - eikIyJOdaHHo1oKcevWodYkrVVVGp53G36AUdtyI3ZTusklrA8MF5g== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4YXlrSGR1VDhrWkw4WFZk - MjQvTm0rU3ZNVFRLMzhtc0lMNlYwMG80VUZZCk5KbnRHeE92WUU1bk5zVDZSMzU4 - K2lPa3VOUUl1NHhtWjMyYzF3MGRpZFEKLS0tIEh4LzdPQWRLMXhZTitDWWpKNWZ3 - MW5tN0MrYWRzYUk0TFlFdkx5cjhtSU0KYmf6h4QI1xMq0br2Er3GVU3TmO35eQf9 - 2pA44xu4ZrBPAseIbz20r9xYA8rwUUP4h674n42hwtxtpEQZd5BVFw== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKVnJoZDNoWmFvU2Rkdndj - QzJFOHFFQmM4bFpIc3RzNmNTZlBRZkRKM2hZClc4eUJ0U1gwUSs4K3oxanduTnRU - bW9BK2xSZUtMUExWM0hFbTNzczJSclEKLS0tIFFBRTQycHozakNOYkNvOHZwL1hO - aDNVeXAzU1RKeCtDMDQ5NFltN2FvNkUK7+mo6n7McbFJ1jlbQCnpKfn6XVVUfjre - USTLf1l6soiewdGUr2haligIRjqNW3fWLxVOrWcQZtzVMx8lrdISsA== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGMk1GSTFVKzBYK3NyNEt6 - ZlBUU0ZEL3U2N0ZCTVo1YzlDbmFWbHk1MjJnCi95K1ZIc0RGRCtZV0Q1bm1NZFI4 - M21TbklvQndwTk5VMmp6aEVCdUFpLzAKLS0tIEtpTFZqaXV0anlIL0NMSDB4SEhl - ZSt0ZUYwNzMzdU9hUDkzWkZBVzl6OWsKa/40ojpux9qbYzmOjAIRezckJlbFuEB0 - xwMXdEWqlRQk0GjOkLOaqViqaNNr/qFsA2JbTQMosSQ7vmatLw89gw== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNZGJwK3ZMVmo2dmRZTkR3 - QTBJVkR5TlF3czJaeGtlY1ZZTDdMQVRKajN3CmtINkdjZExkNmlvZTA1blIyUTNN - SUtET0hua2k0K2lxcncxRFR6NVhJaEkKLS0tIExzcHhCQlpub2gwd0d3cXl2VUdo - RlBwVXdPbklMSzF6RGs2Q1ZSMDBBY28K5+0w4hiWjOtgiZtrrKNH973tVS5mv1qy - AV5+ty+5jga9pAb/6fJxKmgDk1zR/bh/nyjujEfvvt0JlD36l+3FuQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-07-01T19:32:43Z" - mac: ENC[AES256_GCM,data:3rZJT0rIIjVKe6q7EoYkzW9u8Z+zQynEOLo+eqpos7gL/YNZ+ixGJXDCT64ZHHlppeWUAQIizxdDs8hY7FaCXK2QQwa5d7Q7q/ut/OGpL5LaAQngvRsBSHmQfZ10MkyTGQJW8kGNMFj0KWbNm3NWzvMMERYkbWzrkcriHIDJzFk=,iv:tnvMEiNd2vSQg5sBFC6Pri1zaKzOheOxK5pHCbWOy64=,tag:TTnAXaAvIaB51ON3ozdbpA==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.1 diff --git a/k8s/flux/secrets/paperless-env.sops.yaml b/k8s/flux/secrets/paperless-env.sops.yaml deleted file mode 100644 index ce237e7d..00000000 --- a/k8s/flux/secrets/paperless-env.sops.yaml +++ /dev/null @@ -1,123 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:p2M=,iv:yV/4O3g44Rghn6rTuzjF+uOS6gzCd9aBAP27Mea1Tvg=,tag:w1/mjpNDG9jpDDG4JnQcEQ==,type:str] -data: - PAPERLESS_ADMIN_PASSWORD: ENC[AES256_GCM,data:7fU6RXwNYIuFoNmQKlaWVpdvWBD+ezuQGVyTfggoWtfqarxHouqecoNtCb4=,iv:SbY5Se0nRKbzbGQEZVJp7slwWaTB9DzIRWUG5n+sXvI=,tag:PU+zP5IwFi4lDauuf4eT/Q==,type:str] - PAPERLESS_DBPASS: ENC[AES256_GCM,data:QLF0Su6GnQyrBkhXt7UiZrL4+hUqwJ0NuNFTszMon178W6X8x6b9jqZoyTNAkaaSItJMV4Z232taB8GJ5jO0OZCPJV3MK7bqE2oRhBrKuClkJSLNCSPxMw==,iv:wQ7oWEoD/CP5BJPmN1oT78S7YsNH7eMPpEoGj/m/8PU=,tag:JI4CnkcSofeh/Yx1v61/kg==,type:str] - PAPERLESS_SECRET_KEY: ENC[AES256_GCM,data:114HMlGKrcP9WOswcv7S7tOBpstpNcXV1vwMxFsHNv0r5N4EpMLd4ZVrrQ6PZhPBxySd+a+bMalcDbnpuBA86StH63cmHxlMC8HpFb+X6FT+XhYpMA6xpg==,iv:kUrUOJ8is4WhSwPnQZLZGaWWVa1YqaU4BZvwxTpgz8M=,tag:O3ziMnInAiHVvCkgiqn00A==,type:str] -kind: ENC[AES256_GCM,data:lOm02YEk,iv:FWu+4JQ9zwgFdiHK+3fgVEArs7+57jcvfRNUsMVzxFA=,tag:Ix5bgpkG00UvNAYBO7RklQ==,type:str] -metadata: - name: ENC[AES256_GCM,data:SErDAnPOLBXENXt7Zg==,iv:M7liOnqUPgfXJT2dCD14Smjucwtx+UHIr3m2OFaS/RI=,tag:ck8O+6QHIyJHN22nLwCMcg==,type:str] - namespace: ENC[AES256_GCM,data:v4SrjrzdaQ==,iv:m8ehQq9EjXtWsr2y6Mgs8Di92GJcxMlyFNmkGISwKBE=,tag:JFUwUAhgnrjxt7rM8XokqQ==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCRlVSaFNtUkFRa3k5em9H - RGx1Qm82Y0VjSE1MZktNS0pFTGVjMFY0K0RNCnBFcGtFa3YxRGNyaHlJdCtmZmFK - aWFoS1JkUW0venVoTzhMc1h2UnZqQzQKLS0tIG4vMGFWbHRBM1lqc1p2MUt1YWkx - WWdBajNiMzdscldnVkNTUFRlZUtjY0UKfC9DW/7dC1vboxdvTfVYViWFxmGRYy+o - Kavj8s3XbVJkdxEq03kNNpxPyNnJ9blf9eaSDtQDM3FxEbACvXouVg== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHNnEzUTN6bEVTUkZtYTF0 - V3UrbWlLM3ovVFJPTGtCSE5jb1BBcDE5V1RrCjYzWHBqRSszQ2dnWU42QWFRN2dR - WmhpR2VsdmZxbzBsdmJ1bHpwc2lQM0UKLS0tIHc5cklYQmZ4ZWZsRXdRaVI3Y0cw - UFAzV05pUGE3TEdpRGtNTk1BOVE3TkEKeey33+GtCSmY+p/whM6mBnXHuQi6RccZ - ZRAn6vfjgwdQNDiV2nS54hXUZhxnYwEimKk5GYf6ZDM/iFgcil3NGg== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByaDFkWmNhUVdwN0YyTWdh - MGthc3JnRjhiTmp0VDlHYnRGMXN3akFiSWxvCjRSaTNJVzZNeE9zYkIvREJ3akRl - OVZVL2ZoNy9yaDIvQ0IzNERQOVJZNmcKLS0tIGdjUXljOVpRNkhGQnowUG9mQldj - Mi91QzhhRVNaK05sTGc3ckFZV0o5cU0KwjuV0ZcQIEhZJe1WaPRGUdi+tjnbbnQS - ghLMMnAwuoAmT+Fz1AyrPkPVR4mJOLl2rlm8J/u1zy7oO3Sa0qBzPw== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3aWUyN2dwS0tOdU9YKzVY - alVKT1dYdithUzA5aXdLcFZFUUpZWHdSQlZRClljdjdrMVZZaTV2dlI5cDMveDVI - Q21HMXYyQUh4ZWt3aEdDQzNDWFo5dk0KLS0tIENkUmNtNjJ1bzlRd1hRa2Y4LzlW - b29OYkM0VnAvT0J1U3kvdG41TnZ6U0kKVZmOzqVK+bplnDpVSv2HDndItnpvBQPj - l0sEfPEUb9nJYkYHhZS6hNVUxq8175FvlisKDTTlPbz7Kk+MSr5O1Q== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuQU1zMEpTU0dCMmhrYmFE - QkkrejZ1dVM0VnVNYm5sbHE5d2gwN2djTWlzClpiZmFLMk1OSUcrZ1o1Q0xjYy9u - Y25BRDdUbkRCN3ZKNnA3YVBPQzh3VmsKLS0tIExYc0ZFV1UrNVVPOWtQRFlJWG5G - R2V1V3BLdHJaMnNpUEZ4Vk90bXhxcDQKZQi2xIojPh0kuaLHlUa8PThgpa3m0EJH - 47zcRU9PXRgWA+YMUny4o0YDPaX7YC6EEoW9T8+oRrhft4gpRTbENg== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNaXd6VGtZdzVaSDlMejZv - WnU3UzJYZXdMcDNGLzdwVUE2N3p2S0NjeEE4ClNpdXhqVDhxejdqdkt4M0svTmk5 - MlIwTVhIMXJvalI2R2g3ckRkSndKVEEKLS0tIFEzTUxPR2hUMHZnYTBaNi9sdmZy - a0w4U1BicVB2SERzOVo5dWpOaEhveFUKjZsJXODj7hyiDX6SyS9U0ZqfS3NBC7pM - lqVF9tKtObsY8B2YFiS9hcN3Qrxpjbkb2ow49SwX46FvZEWAkXnYgQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXNHR5c0EwYndkRlBvTFZx - ekRnRGFtc0kyQXVYTGQ4dk1wL0JFM0ZrNHp3CmhjQk5jZ3ZrK1gvK2tPTks4VEds - MmN4RzBUNytrOGxhUlNhRkMrblZxdHMKLS0tIGFOWGtySVF6dW9WMmlHUWhvdjBN - WlJrWFQ0YzEvZVNMVU5nNWZmM3Z3ZTAKeA5xL3ULObtxEq0WM8r6Zdgny+H8sLgL - /muGZVKJKyzZ8+Y8rcm1leq3XETJCS/rp545hC04KuAY3ZMC9oULTA== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiYlNyQ2dSbUlKTDRsRlFp - ZGdVQzNEZlQ4Y2JJV3hDQU95Q2FrVGFOSXdZCndHN2ROakRlMlN0bTRNRVd3bnRl - a2Fvck1rcUN3UEx5MWJPR2FLMXU3ZXcKLS0tIDFMNzhWSlZ6NkVIaC9hdnVkMkI1 - bS9MRU1HckVJM3JZdDdNY28zRlRwRUUKjmiYuotwLLm8qs3AnmBil7sUs3WGEYu3 - bSStafjcUjkO7AcQ5qR4o3J6NpV3Yzd7SSk5LXkNdnFmHajBRjQd2g== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAySUdYV3d3M0dJOEc3emov - SzU0WmhFSW45cEJoNk1ZUjhYUGxIYjRRZTI4CjZndFY0eEZUTnNoSGJYcmF5RmZV - K2Z3Qk02a2NuZ1lvbU5VL3V5Y0F0ME0KLS0tIHpYUE91em1WVE1nMWJ5ZkVBTjhH - N2srVEN1OFh3a2Z4UncxV3BVSUd1STgK6NH1hRZH9gS3w5Y4Qp0b4fB4cYKvZPLG - sQgJoKr9QAmPzsb1Ah6zfa7nw3xosE7HWI5Cn/qwQUJUz43VdQlbsQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjM0srZ01KQTBubFdBOHM0 - V1ljTjdUNFN4NkthY1VKanNWRmtzU3NEWGl3Clo4NlY0dCtpMjFCVUxPVjVSRVpy - YzN0VVFSa3pOc2kxMnB1QTRJRjUvdWsKLS0tIHVKN2FOeHpXUVNxK0p2Njd4QVE5 - NHVrNGRZMWdrdGdyWTdSZ096bTRVbHcK2tqMQsf6ULHsb70cAf/+kiS8xDn9PsCJ - k5oUUWgAt3JSKrx6xR3t3+Hqgb+2oiLzisaWtDt0i1L4dVX1d2XYsw== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIMGw5UVVWZzdtY1dSMkRo - c1lpd21oN0dJT1VWbFJEaWEybEp4MjZLcFdVCkxmR2p1QnZjOUFja3ZFU0ZhQ3Q1 - aVhSUzBHenM5RVhOcDZxNTlkV3Z3MU0KLS0tIHpObkN3eFFVMHp1ek1ocFNESEky - cDBnc01yTUNmVWlxREtEaTBZN3ZNSkEKUh5/vLAxANSCc0P6P66Pf/Q8y7urswBi - HiHz8l5xMCf+po0XPTRguPadYV/KM4hj1al6n8HTMu97kH2lhLZHfw== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiR3NwU2dFWFBZeWJIdFF3 - a2laZUdzQXYxVnNMZ1oxM2hqazRqeU4rcUJrCllNY05UajExZXh6U1c2d2pKRUxF - c1duUWVJNUF1UmIvdng0UXNuV2o0RUUKLS0tIDJGSXhMWUd4cG4xOTNjM1hlYXdB - YlJwQ3JpMXdmaFQ1VkU0KzJOVHNXbE0K2c6dimZN6yNAG/DtWJp6Lix8FsC5QZTQ - QC5embAlunVC63i1OwE4t5VWJ5ufSDfO96KejP+vhUuAiyh2obzs/A== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-07-01T19:42:05Z" - mac: ENC[AES256_GCM,data:nFVEWUTj3PqbEpTmeF5kU8kL5+Y2BxwIXzH4IopHgFwl6kMt+0WIRzNwuJ3ronmQUhJyyZOpcmet6MdDI3ybtjFcqQp2KUB8FaInbt94SLR45CgeG/Wen/CQbis8YOFQNpzBEZMHkoCWxM260cHD47XNaAJDJlQPX5gbVcUIFsU=,iv:ei+NNap//JljamcvU+jT7H7vjbzh68QF+v8iJDQLJyU=,tag:NL2GLN1Yzl8rvX6k5Itulw==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.1 diff --git a/k8s/flux/secrets/paperless-pg-creds.sops.yaml b/k8s/flux/secrets/paperless-pg-creds.sops.yaml deleted file mode 100644 index c241bfa6..00000000 --- a/k8s/flux/secrets/paperless-pg-creds.sops.yaml +++ /dev/null @@ -1,123 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:fsk=,iv:JnKRWmDlPwn5+9ByCMKDLd+ZzShJ7nl1vWFVaRhzaNY=,tag:NrAVKbCio4QftnIlLasUgg==,type:str] -data: - password: ENC[AES256_GCM,data:rKuf13AF1YrWUIxXRJDXZLVVxSTLq9ZOmVM5azgGhEmNAb2TnokEK6mGw65a/4ltHRbkXnx/4MboOQObyF1MprrosH5gpPVW1AQMsotGlWonT451AOTZEw==,iv:9/4uAGN+LED0i8QH1mkmrpJiFnXdq0G+tqAxKWwMThU=,tag:H2U1bzBDnMuGym4Yq0uqTg==,type:str] - username: ENC[AES256_GCM,data:yAV0kTChLe1DkR7j,iv:X+jHgP7tj3/uQI4yo+aEd0D2+j3CmjFXJOKHc0nA7Cs=,tag:uJP1Sf3H5MmwoVQOHV3lJA==,type:str] -kind: ENC[AES256_GCM,data:QkCdO4kM,iv:8bLZai/Mi0Sc1mMOFKTh/vJvVJzLjtesQ8X6EX9ZUm4=,tag:sx8Ri5Axh1pF8QDjufjljw==,type:str] -metadata: - name: ENC[AES256_GCM,data:cDWwgwnDiGC6AgtNYsj3n29x,iv:77EacuyMTJAjxuvrVyir4nqGQ/k0Kglvg2kWnYEyJAI=,tag:xYK9msMxatzoLk2I+UHUMQ==,type:str] - namespace: ENC[AES256_GCM,data:hS+pO6CMLO2YT/E=,iv:MZ8sprf1aTNohEX10/zZsxPnBwxZH9jP3AohzFax2o4=,tag:ie1wVuLvNYnpe+5PdRfw4A==,type:str] -type: ENC[AES256_GCM,data:+krNHBW5VLIxEg6av+YCSk3F7hLspR+D,iv:Zjzm1wCy3UeeZcTWK3ytvEOpQTDeujnW5X+JZiRAR3s=,tag:1D2kZ7bvDy/3sSXgfzDDeg==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0U2tCZjNqdWR1Z3Rzdklu - Q3I3V1RDRHhwOHZYSWJSUjEyajM3M2k1ZmdFCjFHaWo1dEl4T2N3TDBZWmFKR09s - aW5mUkY1bTczanRpYnhEMDdyRktJR28KLS0tIHdpbXNLeW0vY3ZvVVVYZ1NXY2xt - Nkh2ci9sbG51WEI3ZjlQemdUbTVZNjAKiPjdCI6uQVLRS9Yuzqw48SvH8rQXdL61 - pUpNHpnmfie1X5IE3/LZEv0PYVahJcSEhuVoS/JpLL6QxR9/QrRC5g== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5MXNieHNNaitVdzl4dzVs - TE1WTzRKcllkSDBWUnVMY0dMMFlCcXp6RGpFCjJoc295d3FJVTJ0d0lJVWVPRFJa - MDdXWllCNllaK2hoOFk0eVJkRmFhWTgKLS0tIG1IamNoU1FuWVVpOHhiM3FlZmZO - YkRBSWpIL05RMmxTT0hGdFVJbnl1YnMK+Ag/lg8HkFjmlWvlsZCSNDXLeLR2MjcK - VUIixHBr4DgXqsIb2JmspqWOrezHTan4z2i5cvxC55k15HL5ZQ5Vkw== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYdFc0S2JlU3NwM0l6MU1p - MjdPOStGWUF1WVVTZnhKVnY4SVowNGRocEdNCmROemxja1RuZzRHMkhTNHJxMUV3 - REZOZG5XOXhsRTBzVE1MTkhXU0w2dlkKLS0tIEh4aDZHOUFOQnFZTzF3MjZXdzVK - VSs2ajBuOHc5dlhOM0pNMmxUc0FETUkKUwhCj0k6Pu2sFZgl8vrBb0TY6MHtI7fz - lrSgMgXDAxefd5uUOFbjVNsQCzIHZxeER4l7Y6QiupkwbUTlUTXksA== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQUENyRDVsTDQvd2R1N0Y2 - ZEFaa3plcElrblcySTVYeHRRZXJ3d2gyUENZCjMzZm5xbnVPTmVUbFI0eTF4SFRS - a2JUaUJHWVBYMUxqVEtTSmNuMjB2R2MKLS0tIEI3bW1nWEtuc3ZNRUlRZ0daZFRP - U3lHYlcrNngwZWFEMy9LTXh5RDRxNjgKDmK/keieIsJmduy+e8B0Q3D/bBzFYmy2 - +yMptE48Wzi7h1rZPPH3LFIlxs32GmOVAfBk1c6E7zeJLUn4+BzD4g== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrVHAxWnMvNFc0cE5ldG9S - dGdVSTFSRUt4enF6dnZQL2FHeTdZdEh3Q0drCkYxanROWVUxdEZYOExGbEdsb3JC - TFozbGx6OU5KZVRzZC91aHNXeVVERGMKLS0tIE1pN2UvTjFxM1pkU2JuVDAwcVpH - WmhOZFNqWUhZa0ZkREgyQkZFdWFVNGsKk55B8jMTR7JSrqYXLU5sD3vztpRhm4iP - vHXN2m3EwARCuWzxpVRpscM1BEUzZvF4ZSzsFOl0OGsNlRV+Z4ibAg== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCUTNmVHpMRXVvR00yTnEv - cUJhQmtpWGZqcFh6TGFWQlFUc0o4T1QxWlcwClZPc084MjFheUpyOUJ1WTNHVURV - UWxmTlZMaXJKMmtpZGlFSnI5ckZ0OWsKLS0tIEFoWWFVN2dqc1laTFBSR3FrWjV0 - SlBaOEFRTlc3b0F2cjNOZHltZEp5M0kKApRuDuqyWJm2GAotvmr8w7iBxu/3qA1y - yVl9ISaWRnMs+sa/GKV8dJiqThs41qUmiXm3hJQetAoFlUIzJGNS1w== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3QkRONFFMeENEUTZRTXk3 - b1VkRXVlVW5kWXMzMUhPcEdua3FDVE1IdUhZCi9BSkRnZE14U2lFT0tDc3hFZzFx - aGpGZ21HY1FZbklHRlF2aFhKME0vTE0KLS0tIHl2WUdTUThUSlhIbE1uQzlUVzB4 - QzA4WTY5aGorSlhoVnU5VUlNc2hSaFEKI3ZEyVdldHT2tzg/ZTxIIIeQt2ik7ik/ - GpOTDRt6np8ZFnuqHd6YajWMteuxx1JCe1XMdNVGDonxt7ca9fdbCQ== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvN0ZoNUlFTjIzeG4zYytY - Z1FIb3l0ZVUwZVR1V2ROS0FiandvK1YvTkJnCkYzak9MQS9USEQxd0REdE1idzk5 - Z0Rwa0h6ZzEvb1JSdmtLSklnVDVNa0kKLS0tIGJGMmxzR1k0cmZWYjdWTlJiNjhw - cnZqeHZBZnBVNXAyRXFqbEJvZkpBNTAKtdyaLYCISYEFCmRcwKINY6mJmgVDwE3t - hP1MRMX90Uc0fZkX66Y3CZDoOwJDtJLKgpy6wbkFmpjEqqnB+zazwQ== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRd0pyMkN0Ky9JV2lNcGZU - WWlqM0ZSb3RvZDl6RkwrU1ZqRVNZMXE3VFFNClN2czhyQmNQaVhucnphSzZUUms2 - SktGMTM1d1IxeUFlUHhxN0ZQZHF1VDQKLS0tIGtqUzZhdks5a0hNK01qMnBTenJ5 - Zk9GU3FDQXp3QmdHVkQrNk01eDlPeTQKPY9/g0Wp+RFDHYeekSfDjZtvHagPm22W - Wxv8RDI6piJpdMiuUu/ZJinWjeXZrAnxh6tzNyLnD+9+tgHIOQ0lhw== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0M1hROHlaM3NNS3lFUlZa - bWlRak9pWmRLdFJTdFJuS3ltdW1ZSmJPb3hvCjlQWEliVllNdktPcDBITktDdG1w - cUZVdFN3c2ZUTlRRaU9veGtDZFE0c3MKLS0tIEMzclNZTElNRU02RXlUdlBnR1d0 - TnRxVDQwdk5XcitKUEJNQ2ZJRjhGQ3MKDp1sNwAd9FKgkdu+C5GA93ZQx6NGvXbs - AU7mjQBdoGzuwhQE+wesa0n3fl9CjeVec3JXHh/7sC+UUotf63Rm1A== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5VGN5RDVSTW5NOWxWOVFF - bHBYbkJWM0N2ODJEVlNTYmo2THR5bWZ5MWdNCllVMEF3VUQrNWp1bEVkV2hiTDZh - b0JYdzdHRHd6eEpNV05rWWlmTEtoV1kKLS0tIElGZUNMNHp4aGpvMGIwMmpBU3By - NHJ4Q3ZaWkhCVzZyNXh4WTBZQjkxRDgKuxNfSTQUG28i937yEhpVEzppUZGMm2H7 - hBzAw8TkB7l3IC5o763+fXU8mEzSoloK+0X6xi4LHBkvXB/mYqDTPQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3a056b1F6RndrdVk3eEly - cTIwZDBjNHlxUGYwa0ZpREFOVUg5bE0yM1FrCnBzbU9UZzJKcEMvSk5wMUJPbnJJ - dGQwS3pvdE5JK0hmVUJwanh5Mm1VZU0KLS0tIFUrWHRIMXdONWtTNWxPL3JWR1Zo - bFZ4R0JYU2svenJCMlRHRks3WlZLRU0KSrtvWiXAhzUjXE4AWbhy54Fdh+Q+xWYb - As3OkVocd/UT2PGb0HFyF1vPQXOMdqZe3NXAfL7srgDVjYgTXSL9Ow== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-07-01T19:32:43Z" - mac: ENC[AES256_GCM,data:oHRVVG7+6mbB9pT4SCoC4d4IVjWZBTt70jLzHUf0YCtLAZEUtrb1g0b+3Q6zqJxnMShY8+y7S2AnRxQGxrO5VPhtVz+JzLqTNd4GQ2uVHaIgHk9bbcz92u2WKLna63NBT5RX3Z0FTHWxVYegugGjsIhnVwF7QmrapJfl/sOcwHA=,iv:f3AQQGlwZFyKk49QQfON3TCs1NznnjEtW+n6cAoG2gg=,tag:n+2Vc4p9jMkgt4f+r7DmQw==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.1 diff --git a/k8s/flux/secrets/pg-shared-b2.sops.yaml b/k8s/flux/secrets/pg-shared-b2.sops.yaml deleted file mode 100644 index 9ac422d6..00000000 --- a/k8s/flux/secrets/pg-shared-b2.sops.yaml +++ /dev/null @@ -1,122 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:WPc=,iv:+3r6yoTKu5NgTjNjh5NwvANPNKSW+afRalPeHID0hNw=,tag:/utGyOcsfBb1lHt4rnWYNw==,type:str] -data: - APP_KEY: ENC[AES256_GCM,data:F/o50FB9CcyJiupvOphNb22ET4GqJ/02osbdWihTzm+kz43k5hKdEnw8j3U=,iv:1kJj2X3nWKlV0DS0opIO7nOzznbs0kDs+DOIl2a8zV4=,tag:vdZuWTs0q7YGfosyuz/AjQ==,type:str] - KEY_ID: ENC[AES256_GCM,data:WMSUBoOvRGSvqPFLreMNtSp2SA4xJqLlO8lNQx7PLtLLpy/o,iv:PHKg4uZNAgXhAWHwVFzkhu5rCml99qC67ovdiat8Ec8=,tag:y8qpoNiGCYdaHPE648iSlg==,type:str] -kind: ENC[AES256_GCM,data:E6+rZ6OW,iv:iz/lbji0sgpRfRnrhk7R3mSofGNkyVFU7iW/AYuAQeI=,tag:71jugbWiUQNKshm3OR4AyQ==,type:str] -metadata: - name: ENC[AES256_GCM,data:kHsqBvDTDg8kslGx,iv:fNpL+8p7wpjn4hErS/KAk+LGWdu9Y9RU3WRNANwZl5o=,tag:BlifoEh+iTL3BJFvny+I6A==,type:str] - namespace: ENC[AES256_GCM,data:arxxVNYYCdgW4Cs=,iv:VpGKLQgXYxZZXgPyfY0MQBR8MuBBn+XiVNvXWjJ6X00=,tag:+DCQP1muiTKifSVvUpAZXw==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvaEFHTktQM3BoS0Rnd2FB - NHNkcldZYXdxN3pRMDhPZUVIZVE2WEo3ZUdzClcvakZOdW8vZ2FIWXlXVzVwdnBn - anFMaVhhbk54UUF6SWJaeUo0a01keTQKLS0tIENVcnBONEs4M28xMnM4MDBBNGVW - VnBuRnZtdk0ycENIUWZpeWY5N0NndVUKwXhIfZH1L+s1rs9I/w38mSE6RCo2JGdQ - PkOWqjEElgj43c5Li2XwEe8wr+b6jLyP6XCv+vVQjlzXJ4Izm/e2+w== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBETFR4a2ZqbTh3M1crYzdJ - YWxQSXNTU0M3cG9XWXBmYzMxbzVXN2F6dUZVCnc5OGdkSU5LaVFjYVN2SnJPcXFq - UnpvWjdhbVNEOE1WekI1Rnl3dXlyQmMKLS0tIHJmM2ZWNEVwbEpubGFjM3NMaHFy - R2V3RnNpNUgzUGN2WE5zNW1aYmJXc3cK9vLKKKsRcvVQuHgABEtZejjQFxiZOL0u - CBBQ76dP6kvWOXYNjNdpIaFTqnX7JxLKCrxFD2WKjuuIA3m/QA82vw== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvUGsvclRydHFlL2w1TDJ6 - aFVqYXltR1lXVlVhRTVGOWdxcWRhYjZvU1drCkVyUzJuSGlzVjhCdXVKcTJtcFZR - dVNmeUNzcGluMUF6NmxEWGcvdkpBWkUKLS0tIFJxVmF1Y214R3NWWnhtNUpBSkU4 - L1FydEQzbG9BdVBpUkw4Z1BQdk4rZWcKTHGPRiQf7v9jcIDwh3HUHLFgBPz4bMPu - XxKidvOkhLHTZVWMLLzXSpPkYHJfdvjZBpcbG4zX4gGt0xo1G+qReQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2T1VsbThhK2picWQ5OHVz - V0tjQXJra2ZSSWc0S2NNS216aWlhNGUrdjBNCjZEQ0JadGdMUGlZU2JQSHdDbWVs - VVpYWkJyeDB6TVRiM1Z3SXpVeEFXWEkKLS0tIFowVVZXMHBDYWJlQzg5eHNqajRR - aVpoYlVjNXkvVzM5K1VnNVl1T3I1OW8KdXw/XGU7jJqzIJGbYCA5fyyAi7+T8xaE - LxjVbLDqQLRX3w6zi21Q1PFPTmhkkTkSUp3DrnPWBL/X881HOcJ6BQ== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0SEhSNVNyRVE3Yk9HdW1B - eDlIMklaeVZGR05idW10NVZWY3BXaGhDMUZnCkYxMDJXSER0dGtqRm5KNUV2eWdo - aXlLOG94U2dRVkxFZnUxelNuc0xRM1kKLS0tIGVJb0JFUG5qQ0NUTURvQ01mYjJ2 - aDZFWUFOaGZ3eHRjMG1XbTlFRG1reEUK2Rn6hCy3eBC/4sE4DU0TxqXZ4eNokYlj - ASNuJpOgK5JfQMppcEmrg0AFVpbF7ZEs8dgaFsApdVMff5q5i6UVfg== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBU1BtYVhUNVExWk55RjBO - OFkrTWl0WW9ueVh4OGY2ZndyWGY4RG1GQUQ0Cmhnb3BIaEJDWGZkUkNTSTY3am0y - aHpnYlpwQTZtVHk5eGxJOUF0VEZPbmsKLS0tIEUzbENyQUx2eVVaMmFFeVZLbVg1 - aS96eFFSdXJrSTlhTzVjTFd6d09IWGcKTLVsZMMjDxe/JEwLyTgGxCUcJudYRr2P - Oq8nT//vFvroBB8/iiaC2e689DNA5Srmy4XUw3h9F928R9gsd5ox5A== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDWFhrKzhrckwvaDZHWU5u - clp4ajZDZXlhUG41WXlRZDZraVhvdUxENmlNClN3OWF4aERSNURHaWNnKzNPV1NI - cmVyLyt2a0ZoSlpIWGh1ZGU4aVp5R0kKLS0tIE1mSjdHVzdFVE5hNzI1dVozQ1Bj - cVRUTEcySVdqWnV1QitDSFc3MTc3T2sKmhSWiVYycLVUt66J2CpekZYG3rDUugNR - jOAIf7UlNmc/M8L7hWyFhYQK3dp86F2a9leyPFqlKQgwkNqcorzIRQ== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkbmhwcmxoZVUzbzdGK3ph - QlJ6a0NBNEJ3QTQ3VENIQkJTL3FiVWRTekVNCkFLU2VJSFMwd2dGVE9BbDZadU9k - WnJXdzdnWDlpMVFPd2tlTzRaRVE4REEKLS0tIEJQWndZRmt5bUdSWGNHVnAxOWk1 - RW4xNTExa1cxRXEvRThwQ1JkK1pISWMKkAfuro+7HP0QcNcKsH61Q4qv3Te+9beO - wx55SNwA5TMliyw78S+xH9bbD9Fex77aGwB35lgqipM0OiD0ZChEvA== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZTkYyaTU5VDI5a01HK3BJ - TXFtN2JvMWR2N3ZESHliUWQ0VmhMNjErcmtVCm1tZzZhZzNMMG9sSnpYRUcyaGlT - N2xENnZYRTUzK0I4K2pzendEOGlXME0KLS0tIFJqWnR6bVp0UGtGOW9zZUY0SDYv - Rm90bGRXaWNPUTdHbEJ4Rm9LdzlWZFEKXdbfXxTzdqkUQ9v7RF9aFLwkWhlI0t5O - Rrc6dE5s1YO8/MdqVWgTOtjS7xctIAEM0+uZCTurQUvCn4uA8Ivlgw== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzN3Rob24vblUrOUxoS25z - VnJpTzNPalNJRjdEaXlOcWhNckNxZTArWEJVCjFPOGQ1MTd6UzRBcU96QVROR0g1 - K2pIL0oybWd2Mm9PeGlJWjYzWWRqZmMKLS0tIHMxb0t6NlB5SGJZcVkxLzdnTlEy - ajlqRDFUOEVwZDlGMjMzeUFZM3Y5dE0KhnSA2uGY2TGuBPM8+0XkFp6w/MT7YEba - fC56E/CoFwa+7jfA3ClGpVrJMk8hZs5lnvmS6CVuyiCNtW53tJLDuw== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPYUUwcU15eVA3MnFyUHdF - MHVlQnZyamtqUXNHK2kxZXFWZWZBOFkwODBJCmEwcy9nbWdhOU03c1k1NkcvZWlV - UUN1MDg5VlZWQSszS2ZPNVp4TVVOSE0KLS0tIFk0UloxOGNSRGxSdzY3cGM5N0Fv - MEM2endOQUdzZzM0WUF2TVdYeUY1YUUKL+tu8OUPWdNv2GtVudxFqevDCMZyy3uG - 5VtlTRyyVBY75c4P4X6IX3D0Z1UoIOP/rCouXrUJJ4paYoRSzVEUcA== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZd1lZMXNGbVdYZm5zcmRq - RlVacUxaTjQ5ZVZ2WTBvVW41Z3A1NXRFVnhnCnpOamZROUo1YzJvaFFzSEM2ZkFw - RzlZNHppbFh3dkRqaEhqd2JJU2FNSHMKLS0tIEMrRVFuYlpFbkZQc1BBc0UrRnpI - bjhLVkwxQlhNTVFJTDNTSjNsMFVZdEUKSXt5JKOq0R61yIlehIrofCvgDzDgnMLV - NwoVeWM6ODt6gmKM8NYCnt6+5I5zZlneJG3kG1WOsHesc0aVDNr5uA== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-07-01T19:32:43Z" - mac: ENC[AES256_GCM,data:dOVHq0khrvot3rHlmmduKWN3wnMAmZEeU14c9Vz7Cds3hDrlNIrS7XJiA8H90wtH9bm1GsXV94kaHcnko1xFFBjWyzT7582si70Gg7r0ZCQjVI4q/mem2F7X/c2JJUGgZRpZI2vhFcD+fG6h0cJF0MN2zGmQX2z5Xypxcb50Yrw=,iv:CeuFP8uYZa90bRqMBaeOJaO8n3PpCva/lDoF3X6avrU=,tag:qRFjBxBEHXMSxytFGe3btg==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.1 diff --git a/k8s/flux/secrets/tailscale-operator-values.sops.yaml b/k8s/flux/secrets/tailscale-operator-values.sops.yaml deleted file mode 100644 index 34e82eaa..00000000 --- a/k8s/flux/secrets/tailscale-operator-values.sops.yaml +++ /dev/null @@ -1,121 +0,0 @@ -apiVersion: ENC[AES256_GCM,data:tSs=,iv:9Jxg2iewFJnF2FLmGGAKfvZ3GVaxKKa5vSmdTPvdN2A=,tag:MiYzwAYV5zcDl/B4qQVriQ==,type:str] -data: - values.yaml: ENC[AES256_GCM,data:7dbdaxQ6XElHS82BwL6wbCIVo+tWjVAKUM5QwEGj2O+LoZyuqdxCVHQ0IeF26704/EUTRZphZAhsaGoA/dgHjEpIXxWtygKyyUvXq8XVKB5WWNBAMSBV7WUme7+i884zmbymeJRZ2MpIf1WFc+qneR7fWF8w9PDiHCqmqTYFlobYkP+7ay5wrS0jFPzbNr0+6ehvNsEg7pSTGfCyohVTKjQ5rCbE7qvujZxtHPNtGbC8sgA1mMe2bPMMY2Ly9HCM5jnfWroG4JE05kKeJYurd/K2Px61u9DH9Au1r27wQg0=,iv:imJ1XBFGNdrCzjPQsWTdZJdacnhv7C1NlmmxGO2QXKQ=,tag:kX4MC4szQxyS2zjAPAD8Vw==,type:str] -kind: ENC[AES256_GCM,data:SqZ83+Gf,iv:qW99vd9BS70dj5qBZDUB7uEB2gaVtBxAeG1m+WUhoNg=,tag:KBNqAkEsjTTyY95CjH7+Gw==,type:str] -metadata: - name: ENC[AES256_GCM,data:dyIU2zdYgdLOjYeVMBo85UwAiQ5jLO7cZA==,iv:4VP0GfYxbXcizLp/PXIqh548tDp+sBEluM5oEV9CXVA=,tag:aP+k5gzNdN4fRZ0zACeIkA==,type:str] - namespace: ENC[AES256_GCM,data:4+XMfD/sLWHcZWQ=,iv:6yOmI5SN8V0PAnrE7DXtcUtoZijwEmoXITtoXBpypFQ=,tag:qbFP/OvYY8L01FKIY5b8eQ==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwYVMvbkhPcUdTbzJSRnZs - ODNVelJlMHAzN000dTRqaTVpNGgwbHluelZnCkUzZXQ2NEZBOWVjcnRTM0k1bzFS - UGF3Z1RaY3U3YUprVnpycktybU9vVEUKLS0tIFFlVVBKbGlOSEs4L3REc21Idnlu - QnNnOHA5RWxsZnpxam1mV2FvdWIyR3MKOJbIe9a/5yMAx5+FDUzu8h0ObHQGYc6p - 4GjT7IJ9gDSDJXvljWHoI54BdEOkmX6Vy4nkLnMTvwhDiDhri8Occw== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNcGk0cVJXM01MVHlYZnJH - ZVZpZ2ZBUkR4WnZnZ2JnRm1EY2o4eEZFRHkwCnlrNmhyZkN0cXh5ZzJ5YmJRWHlx - R0t4bmllTkJkZitlVG9HZlBSa2FFaTQKLS0tIFdrQkpyUkVjWEZSY1lOc2psR0Nq - QTJJdHRWTE9yL0dxcGNRdkEwQWN3aVUK2fmULutNwncvkWOd8z2RlCcBo0eVWcgM - UKbNW3VPn0NkHX5+hpbdjYZjiUzb3E68yCCMgbmc0Tv6p2scqs2JlQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWU21UdnNIVmRjd3lNdlk4 - bE5LWmhCNzJzUVBUd2VoVDRwTHAvLzFndFdNCjhSckd2NEtCeGYwUEpZUlJiOGVi - Sk9rb0Jsa1NjWDRTcXFUeW5HTFIrbTQKLS0tIDhleG5hb05NNHkwWkRnenQrSVgx - N2EzTjdVZWt2ZUJraGVvS0dXUFJqa2MKsv65LOVLh19So7Ewbm12Y66QlDY9Mjbd - fJDVjkGV/rLiftfDO+BOMs3p8xSZTEvJw0zsx5Nc+b/vgor4oa4NRA== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2SjBPRjB3TXlwb1BHZ0k0 - eEMydE14ckIvUUwwR2twRmNHU3R2N0dsL21jCjRZdFN0UFRhY2t3dmhQdldBTkQz - bVZtUFh4TE55VkZ6RlBEdjdVbXFCT2MKLS0tIFhhOGhydnhCWW1GUHlDNytER2h3 - SE03TWZiWTJlVkF1dmhQcEc2dlBaTzgKHO4d+wfy5sOmBnDZGlyVhng65c2iGtDy - MVMFvtcLs5+dvvhvw6FBmtBxxmyki7LV1V7Papl6DjOg0QTV1GhiGg== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0elJWcmNXN2JXYitFcGJ5 - dHRobDlTeE1TSEc0Sm1TUjZPUjNhak5YOTBnCmRwYjRSd2tMRjlNMFJPSytlaGp1 - TDVPUCtWUEhmQTM4dVVmSFoyeURZV0UKLS0tIDZOVDJ3ZVVuNTVLdTcvWWdDWlJV - TGUvQjJSUVFVSllUdURVY0RMZFEySFkKKPF/ki5mFicwU2CLV8n47TPbT+JOOtrJ - mw3c59SLFhCV+M3QGfsPNP5FUqXu4Oztc8Lqq5NJR18tQseZa0xP3w== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaczFaRFRLcmtDNGdvaFkr - eVdmVzdTRnhFQ05CbzVGZ0dNOEdyUHR6MFFvCm5HdXNPbzF4R1RrRk1Zc0xlaDNj - Rk9jYW1xZkUweTVHa1luUms3QUUwc28KLS0tIGVnRS9HYTd3VStPN2ZWeEljYXBO - UCtGKzhTd1UrYktiMzVCT2xCcDYxMnMK3cFTHHr7klYp4ZxcXWPOSfNtTNNLgsCt - ZjGOYp1oi6tlhFTo5vwn+BHjJYXArVHt++1K4nUXex5VO6g/BLQ68w== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArYVFIVW1XYlNFZjhSSVBz - Nngwdzd5SkJiSitaZHhwcW4vRlNBQjRyMUdZCmhscnp6RmY1eXZMRG5WbHFGSGZ4 - UWlqWkJrL0hSQnBpN1I1ZStuZ2RaVkEKLS0tIFMyeWVIeGJzRDY1MVZwVDB3N25r - WUV5Nlp1VU9nK1o3S2RRR1FaMjFxbGMKwfDFEiiwcDBtasP4DICwtebExHDQASGt - LlqEKmx9LhC7Nkqt7wXfCvf8pSy3iSKKlvjMIOZ3EDRcTYdkPda5xg== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrY0hzdk1PYVo0cmU4NC9G - YVpVUlViWkZVSWpqZ29scndEY2lCUUpiOVJvClRDck9Qc0lRVFlLSWRWaWtXNDRp - VTBaQ3MwaWN4bGV0Wk04MlZEelZlTWcKLS0tIEV4cWt1Z2ZJa2h2U1dLWjd6NWox - R2VKcE45NFQyT0E3R2dCc2dIcTZad3cKe8UHFtXZPNRRS/zHopirw6eccZr8ie3C - FaLNcvCCguXeIo71nLvqmUnzDtPMKSexJicDs5mKu7dU0FNwpJO9jg== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDQkx6WkdxamtLQTNETlhL - MjZrSzgrbTVERkYvaHZVUlYwaUtra1NSeTJjCnZUeDJac2pjci9nd2N4Nm5QeE10 - VjJVNkJLWFZCR1MvTS83T0VYOUpVUW8KLS0tIFgvVzBJTFRDdUZNaUJ4ZkxEaUJN - bWFwV3RtM1RIZ1cxa2daN0NPU3FJdlEK0Yx5GUSceAs4h0U+jke7G5TxWuze+66n - juyrFmTze+rjn6F4PQBO7DDFXk/4GxqHpBTZy2BJd9mHGEE066YvUw== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFZHFGN0xDdDY3Q3I1OEcx - WVFrUzMwdFE5a0Y1a0dSQVd0Sm1nekVubnhFCm1mem1YWWdVcU1xeGI2N1RVUjYw - SWFqZmtjQVNIc28wd0NIUVhwQjNFZ0kKLS0tIFhJaDhyNnlkV0lEcWVMd1R6eU5v - RWRVUXlmL3hFNllGeEMyM3JDVFVyZ1kKzd5/nxzCPWRz/P9uxf9/QOtoziG+0Bnr - +iws2WukZ6LTbV7FMU34GHVblXYRqU8jZfyBvCIPnVtOIvAQ5NNBzw== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjTzV6K21tcStUUldaNzgv - WTZSV2lGUEFBYk90ZGlNS2dJTlA5ZnlSR2xZCk9Oc2dYZXVVc2tZUG9nRGduK1ly - YzF3cVpaUU1OWmMvcmJmbW5WdW5LNkEKLS0tIEhQblJGODdHU0tRaGExVGV3clRm - MUtzSXpEVUZlRk1zRXlEalNKay9aaDQKm/rPb7/XwYz8e+jcL4aizDwV7P4gf8zq - Ywb0mN/hwmVREGaRzOOaXAR0AIiK+D1Qam7Q1pl7pFmxvVh6/SRsLg== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmdlRZL2lrSUhETGpvRlUw - dTRvUllvVXVsRHI5b1pLbTBONlFzeDJ4bmpZCmVoYUFySjdIOXVGSjdlQThkV0ta - R2gxL1E4QmtlZmxsTFZ2aXpjZGRZSHMKLS0tIE9CajhiSmdXczBrakcrYzliWjQy - amdYWER4aE96Z1VDeFZ3TlpQRXk2NUkKQNqV4OA/UInTrCvCHQ7ANcNdpAKHbHC8 - yK015+pzzs9Smvfwc6WZtFtAPiE8F0az5F9Q8Ksp23EmXtO9sk0ljA== - -----END AGE ENCRYPTED FILE----- - recipient: age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth - lastmodified: "2026-07-01T19:24:47Z" - mac: ENC[AES256_GCM,data:Q7KQ05P27ukWzUcWSjfoy3skMnPkTA5GVlRsmeiO3fQVkWc9TI4GhtG7uGGo0a0CdayW925ziHZglVgzjA4F6uRu19hYypNjA1XnUvLXqXAff7hDOlxexHbJwpo9eDnTx14oEK1S0wh37LJhW2tF41Rg6q8GFb7ipukuVYKYFuc=,iv:zZrfMU2qrufP8tdDC1GJQzPyUUUN/gK+wunoAKPBhQ0=,tag:tQBvVHHOH4g9qpiQJEvv9w==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.1 diff --git a/k8s/flux/sources/global.values.yaml b/k8s/flux/sources/global.values.yaml deleted file mode 100644 index 3297ab58..00000000 --- a/k8s/flux/sources/global.values.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# Shared operational constants and OCI image pins. Bump once and every -# chart that references these values picks it up automatically. -global: - images: - alpine: docker.io/library/alpine:3.24@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b - rclone: rclone/rclone:1.75@sha256:b06aed988cf5967de7c25be5925240983981c757f4ed1ac9d2fa659d51d60548 - - failover: - # Fast eviction when a node goes NotReady/Unreachable. Mirrors the - # app-pod toleration so CNPG and stateful workloads fail over quickly. - fastTolerationSeconds: 60 diff --git a/k8s/flux/sources/helmrepositories.yaml b/k8s/flux/sources/helmrepositories.yaml deleted file mode 100644 index cc2c403d..00000000 --- a/k8s/flux/sources/helmrepositories.yaml +++ /dev/null @@ -1,79 +0,0 @@ -apiVersion: source.toolkit.fluxcd.io/v1 -kind: HelmRepository -metadata: - name: grafana -spec: - interval: 15m - url: https://grafana.github.io/helm-charts ---- -apiVersion: source.toolkit.fluxcd.io/v1 -kind: HelmRepository -metadata: - name: prometheus-community -spec: - interval: 15m - url: https://prometheus-community.github.io/helm-charts ---- -apiVersion: source.toolkit.fluxcd.io/v1 -kind: HelmRepository -metadata: - name: traefik -spec: - interval: 15m - url: https://traefik.github.io/charts ---- -apiVersion: source.toolkit.fluxcd.io/v1 -kind: HelmRepository -metadata: - name: longhorn -spec: - interval: 15m - url: https://charts.longhorn.io ---- -apiVersion: source.toolkit.fluxcd.io/v1 -kind: HelmRepository -metadata: - name: cnpg -spec: - interval: 15m - url: https://cloudnative-pg.github.io/charts ---- -apiVersion: source.toolkit.fluxcd.io/v1 -kind: HelmRepository -metadata: - name: tailscale -spec: - interval: 15m - url: https://pkgs.tailscale.com/helmcharts ---- -apiVersion: source.toolkit.fluxcd.io/v1 -kind: HelmRepository -metadata: - name: jetstack -spec: - interval: 15m - url: https://charts.jetstack.io ---- -apiVersion: source.toolkit.fluxcd.io/v1 -kind: HelmRepository -metadata: - name: nfd -spec: - interval: 15m - url: https://kubernetes-sigs.github.io/node-feature-discovery/charts ---- -apiVersion: source.toolkit.fluxcd.io/v1 -kind: HelmRepository -metadata: - name: intel -spec: - interval: 15m - url: https://intel.github.io/helm-charts/ ---- -apiVersion: source.toolkit.fluxcd.io/v1 -kind: HelmRepository -metadata: - name: emberstack -spec: - interval: 15m - url: https://emberstack.github.io/helm-charts diff --git a/k8s/flux/sources/kustomization.yaml b/k8s/flux/sources/kustomization.yaml deleted file mode 100644 index 84a97391..00000000 --- a/k8s/flux/sources/kustomization.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -namespace: flux-system -resources: - - helmrepositories.yaml -configMapGenerator: - - name: cute-haus-global - files: - - values.yaml=global.values.yaml - options: - disableNameSuffixHash: true - annotations: - cute.haus/secret-policy: non-secret-values-only diff --git a/k8s/flux/system/README.md b/k8s/flux/system/README.md deleted file mode 100644 index 2e760d28..00000000 --- a/k8s/flux/system/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Flux System - -Flux was bootstrapped from exported manifests (Option B), not via -`flux bootstrap github`. The manifests in this directory were applied manually -to the cluster. Preserve `layers.yaml` and keep it included from -`kustomization.yaml`; it wires the child reconciliation layers for this repo. - -Under the current bootstrap model, `flux-system/sops-age` is a bootstrap -artifact applied out-of-band, not an encrypted Flux-managed Secret. diff --git a/k8s/flux/system/gotk-components.yaml b/k8s/flux/system/gotk-components.yaml deleted file mode 100644 index 8d67b26e..00000000 --- a/k8s/flux/system/gotk-components.yaml +++ /dev/null @@ -1,6092 +0,0 @@ ---- -# This manifest was generated by flux. DO NOT EDIT. -# Flux Version: v2.9.4 -# Components: source-controller,kustomize-controller,helm-controller,notification-controller -apiVersion: v1 -kind: Namespace -metadata: - labels: - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - pod-security.kubernetes.io/warn: restricted - pod-security.kubernetes.io/warn-version: latest - name: flux-system ---- -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - labels: - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: allow-egress - namespace: flux-system -spec: - egress: - - {} - ingress: - - from: - - podSelector: {} - podSelector: {} - policyTypes: - - Ingress - - Egress ---- -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - labels: - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: allow-scraping - namespace: flux-system -spec: - ingress: - - from: - - namespaceSelector: {} - ports: - - port: 8080 - protocol: TCP - podSelector: {} - policyTypes: - - Ingress ---- -apiVersion: networking.k8s.io/v1 -kind: NetworkPolicy -metadata: - labels: - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: allow-webhooks - namespace: flux-system -spec: - ingress: - - from: - - namespaceSelector: {} - ports: - - port: 9292 - protocol: TCP - podSelector: - matchLabels: - app: notification-controller - policyTypes: - - Ingress ---- -apiVersion: v1 -kind: ResourceQuota -metadata: - labels: - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: critical-pods-flux-system - namespace: flux-system -spec: - hard: - pods: "1000" - scopeSelector: - matchExpressions: - - operator: In - scopeName: PriorityClass - values: - - system-node-critical - - system-cluster-critical ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: crd-controller-flux-system -rules: -- apiGroups: - - source.toolkit.fluxcd.io - resources: - - '*' - verbs: - - '*' -- apiGroups: - - kustomize.toolkit.fluxcd.io - resources: - - '*' - verbs: - - '*' -- apiGroups: - - helm.toolkit.fluxcd.io - resources: - - '*' - verbs: - - '*' -- apiGroups: - - notification.toolkit.fluxcd.io - resources: - - '*' - verbs: - - '*' -- apiGroups: - - image.toolkit.fluxcd.io - resources: - - '*' - verbs: - - '*' -- apiGroups: - - source.extensions.fluxcd.io - resources: - - '*' - verbs: - - '*' -- apiGroups: - - "" - resources: - - namespaces - - secrets - - configmaps - - serviceaccounts - verbs: - - get - - list - - watch -- apiGroups: - - "" - resources: - - events - verbs: - - create - - patch -- apiGroups: - - "" - resources: - - configmaps - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - configmaps/status - verbs: - - get - - update - - patch -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - "" - resources: - - serviceaccounts/token - verbs: - - create -- nonResourceURLs: - - /livez/ping - verbs: - - head ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - rbac.authorization.k8s.io/aggregate-to-admin: "true" - rbac.authorization.k8s.io/aggregate-to-edit: "true" - name: flux-edit-flux-system -rules: -- apiGroups: - - notification.toolkit.fluxcd.io - - source.toolkit.fluxcd.io - - source.extensions.fluxcd.io - - helm.toolkit.fluxcd.io - - image.toolkit.fluxcd.io - - kustomize.toolkit.fluxcd.io - resources: - - '*' - verbs: - - create - - delete - - deletecollection - - patch - - update ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - rbac.authorization.k8s.io/aggregate-to-admin: "true" - rbac.authorization.k8s.io/aggregate-to-edit: "true" - rbac.authorization.k8s.io/aggregate-to-view: "true" - name: flux-view-flux-system -rules: -- apiGroups: - - notification.toolkit.fluxcd.io - - source.toolkit.fluxcd.io - - source.extensions.fluxcd.io - - helm.toolkit.fluxcd.io - - image.toolkit.fluxcd.io - - kustomize.toolkit.fluxcd.io - resources: - - '*' - verbs: - - get - - list - - watch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: cluster-reconciler-flux-system -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: cluster-admin -subjects: -- kind: ServiceAccount - name: kustomize-controller - namespace: flux-system -- kind: ServiceAccount - name: helm-controller - namespace: flux-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: crd-controller-flux-system -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: crd-controller-flux-system -subjects: -- kind: ServiceAccount - name: kustomize-controller - namespace: flux-system -- kind: ServiceAccount - name: helm-controller - namespace: flux-system -- kind: ServiceAccount - name: source-controller - namespace: flux-system -- kind: ServiceAccount - name: notification-controller - namespace: flux-system -- kind: ServiceAccount - name: image-reflector-controller - namespace: flux-system -- kind: ServiceAccount - name: image-automation-controller - namespace: flux-system -- kind: ServiceAccount - name: source-watcher - namespace: flux-system ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled - labels: - app.kubernetes.io/component: source-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: buckets.source.toolkit.fluxcd.io -spec: - group: source.toolkit.fluxcd.io - names: - categories: - - all - - fluxcd - - fluxcd-sources - kind: Bucket - listKind: BucketList - plural: buckets - singular: bucket - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.endpoint - name: Endpoint - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - name: v1 - schema: - openAPIV3Schema: - description: Bucket is the Schema for the buckets API. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: |- - BucketSpec specifies the required configuration to produce an Artifact for - an object storage bucket. - properties: - bucketName: - description: BucketName is the name of the object storage bucket. - type: string - certSecretRef: - description: |- - CertSecretRef can be given the name of a Secret containing - either or both of - - - a PEM-encoded client certificate (`tls.crt`) and private - key (`tls.key`); - - a PEM-encoded CA certificate (`ca.crt`) - - and whichever are supplied, will be used for connecting to the - bucket. The client cert and key are useful if you are - authenticating with a certificate; the CA cert is useful if - you are using a self-signed server certificate. The Secret must - be of type `Opaque` or `kubernetes.io/tls`. - - This field is only supported for the `generic` provider. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - endpoint: - description: Endpoint is the object storage address the BucketName - is located at. - type: string - ignore: - description: |- - Ignore overrides the set of excluded patterns in the .sourceignore format - (which is the same as .gitignore). If not provided, a default will be used, - consult the documentation for your version to find out what those are. - type: string - insecure: - description: Insecure allows connecting to a non-TLS HTTP Endpoint. - type: boolean - interval: - description: |- - Interval at which the Bucket Endpoint is checked for updates. - This interval is approximate and may be subject to jitter to ensure - efficient use of resources. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - prefix: - description: Prefix to use for server-side filtering of files in the - Bucket. - type: string - provider: - default: generic - description: |- - Provider of the object storage bucket. - Defaults to 'generic', which expects an S3 (API) compatible object - storage. - enum: - - generic - - aws - - gcp - - azure - type: string - proxySecretRef: - description: |- - ProxySecretRef specifies the Secret containing the proxy configuration - to use while communicating with the Bucket server. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - region: - description: Region of the Endpoint where the BucketName is located - in. - type: string - secretRef: - description: |- - SecretRef specifies the Secret containing authentication credentials - for the Bucket. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - serviceAccountName: - description: |- - ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate - the bucket. This field is only supported for the 'gcp' and 'aws' providers. - For more information about workload identity: - https://fluxcd.io/flux/components/source/buckets/#workload-identity - type: string - sts: - description: |- - STS specifies the required configuration to use a Security Token - Service for fetching temporary credentials to authenticate in a - Bucket provider. - - This field is only supported for the `aws` and `generic` providers. - properties: - certSecretRef: - description: |- - CertSecretRef can be given the name of a Secret containing - either or both of - - - a PEM-encoded client certificate (`tls.crt`) and private - key (`tls.key`); - - a PEM-encoded CA certificate (`ca.crt`) - - and whichever are supplied, will be used for connecting to the - STS endpoint. The client cert and key are useful if you are - authenticating with a certificate; the CA cert is useful if - you are using a self-signed server certificate. The Secret must - be of type `Opaque` or `kubernetes.io/tls`. - - This field is only supported for the `ldap` provider. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - endpoint: - description: |- - Endpoint is the HTTP/S endpoint of the Security Token Service from - where temporary credentials will be fetched. - pattern: ^(http|https)://.*$ - type: string - provider: - description: Provider of the Security Token Service. - enum: - - aws - - ldap - type: string - secretRef: - description: |- - SecretRef specifies the Secret containing authentication credentials - for the STS endpoint. This Secret must contain the fields `username` - and `password` and is supported only for the `ldap` provider. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - required: - - endpoint - - provider - type: object - suspend: - description: |- - Suspend tells the controller to suspend the reconciliation of this - Bucket. - type: boolean - timeout: - default: 60s - description: Timeout for fetch operations, defaults to 60s. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ - type: string - required: - - bucketName - - endpoint - - interval - type: object - x-kubernetes-validations: - - message: STS configuration is only supported for the 'aws' and 'generic' - Bucket providers - rule: self.provider == 'aws' || self.provider == 'generic' || !has(self.sts) - - message: '''aws'' is the only supported STS provider for the ''aws'' - Bucket provider' - rule: self.provider != 'aws' || !has(self.sts) || self.sts.provider - == 'aws' - - message: '''ldap'' is the only supported STS provider for the ''generic'' - Bucket provider' - rule: self.provider != 'generic' || !has(self.sts) || self.sts.provider - == 'ldap' - - message: spec.sts.secretRef is not required for the 'aws' STS provider - rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.secretRef)' - - message: spec.sts.certSecretRef is not required for the 'aws' STS provider - rule: '!has(self.sts) || self.sts.provider != ''aws'' || !has(self.sts.certSecretRef)' - - message: ServiceAccountName is not supported for the 'generic' Bucket - provider - rule: self.provider != 'generic' || !has(self.serviceAccountName) - - message: cannot set both .spec.secretRef and .spec.serviceAccountName - rule: '!has(self.secretRef) || !has(self.serviceAccountName)' - status: - default: - observedGeneration: -1 - description: BucketStatus records the observed state of a Bucket. - properties: - artifact: - description: Artifact represents the last successful Bucket reconciliation. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - Path is the relative file path of the Artifact. It can be used to locate - the file in the root of the Artifact storage on the local file system of - the controller managing the Source. - type: string - revision: - description: |- - Revision is a human-readable identifier traceable in the origin source - system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - URL is the HTTP address of the Artifact as exposed by the controller - managing the Source. It can be used to retrieve the Artifact for - consumption, e.g. by another controller applying the Artifact contents. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the Bucket. - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedGeneration: - description: ObservedGeneration is the last observed generation of - the Bucket object. - format: int64 - type: integer - observedIgnore: - description: |- - ObservedIgnore is the observed exclusion patterns used for constructing - the source artifact. - type: string - url: - description: |- - URL is the dynamic fetch link for the latest Artifact. - It is provided on a "best effort" basis, and using the precise - BucketStatus.Artifact data is recommended. - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled - labels: - app.kubernetes.io/component: source-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: externalartifacts.source.toolkit.fluxcd.io -spec: - group: source.toolkit.fluxcd.io - names: - categories: - - all - - fluxcd - - fluxcd-sources - kind: ExternalArtifact - listKind: ExternalArtifactList - plural: externalartifacts - shortNames: - - ea - singular: externalartifact - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - - jsonPath: .spec.sourceRef.name - name: Source - type: string - name: v1 - schema: - openAPIV3Schema: - description: ExternalArtifact is the Schema for the external artifacts API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: ExternalArtifactSpec defines the desired state of ExternalArtifact - properties: - sourceRef: - description: |- - SourceRef points to the Kubernetes custom resource for - which the artifact is generated. - properties: - apiVersion: - description: API version of the referent, if not specified the - Kubernetes preferred version will be used. - type: string - kind: - description: Kind of the referent. - type: string - name: - description: Name of the referent. - type: string - namespace: - description: Namespace of the referent, when not specified it - acts as LocalObjectReference. - type: string - required: - - kind - - name - type: object - type: object - status: - description: ExternalArtifactStatus defines the observed state of ExternalArtifact - properties: - artifact: - description: Artifact represents the output of an ExternalArtifact - reconciliation. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - Path is the relative file path of the Artifact. It can be used to locate - the file in the root of the Artifact storage on the local file system of - the controller managing the Source. - type: string - revision: - description: |- - Revision is a human-readable identifier traceable in the origin source - system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - URL is the HTTP address of the Artifact as exposed by the controller - managing the Source. It can be used to retrieve the Artifact for - consumption, e.g. by another controller applying the Artifact contents. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the ExternalArtifact. - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled - labels: - app.kubernetes.io/component: source-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: gitrepositories.source.toolkit.fluxcd.io -spec: - group: source.toolkit.fluxcd.io - names: - categories: - - all - - fluxcd - - fluxcd-sources - kind: GitRepository - listKind: GitRepositoryList - plural: gitrepositories - shortNames: - - gitrepo - singular: gitrepository - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.url - name: URL - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - name: v1 - schema: - openAPIV3Schema: - description: GitRepository is the Schema for the gitrepositories API. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: |- - GitRepositorySpec specifies the required configuration to produce an - Artifact for a Git repository. - properties: - ignore: - description: |- - Ignore overrides the set of excluded patterns in the .sourceignore format - (which is the same as .gitignore). If not provided, a default will be used, - consult the documentation for your version to find out what those are. - type: string - include: - description: |- - Include specifies a list of GitRepository resources which Artifacts - should be included in the Artifact produced for this GitRepository. - items: - description: |- - GitRepositoryInclude specifies a local reference to a GitRepository which - Artifact (sub-)contents must be included, and where they should be placed. - properties: - fromPath: - description: |- - FromPath specifies the path to copy contents from, defaults to the root - of the Artifact. - type: string - repository: - description: |- - GitRepositoryRef specifies the GitRepository which Artifact contents - must be included. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - toPath: - description: |- - ToPath specifies the path to copy contents to, defaults to the name of - the GitRepositoryRef. - type: string - required: - - repository - type: object - type: array - interval: - description: |- - Interval at which the GitRepository URL is checked for updates. - This interval is approximate and may be subject to jitter to ensure - efficient use of resources. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - provider: - description: |- - Provider used for authentication, can be 'aws', 'azure', 'github', 'generic'. - When not specified, defaults to 'generic'. - enum: - - generic - - aws - - azure - - github - type: string - proxySecretRef: - description: |- - ProxySecretRef specifies the Secret containing the proxy configuration - to use while communicating with the Git server. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - recurseSubmodules: - description: |- - RecurseSubmodules enables the initialization of all submodules within - the GitRepository as cloned from the URL, using their default settings. - type: boolean - ref: - description: |- - Reference specifies the Git reference to resolve and monitor for - changes, defaults to the 'master' branch. - properties: - branch: - description: Branch to check out, defaults to 'master' if no other - field is defined. - type: string - commit: - description: |- - Commit SHA to check out, takes precedence over all reference fields. - - This can be combined with Branch to shallow clone the branch, in which - the commit is expected to exist. - type: string - name: - description: |- - Name of the reference to check out; takes precedence over Branch, Tag and SemVer. - - It must be a valid Git reference: https://git-scm.com/docs/git-check-ref-format#_description - Examples: "refs/heads/main", "refs/tags/v0.1.0", "refs/pull/420/head", "refs/merge-requests/1/head" - type: string - semver: - description: SemVer tag expression to check out, takes precedence - over Tag. - type: string - tag: - description: Tag to check out, takes precedence over Branch. - type: string - type: object - secretRef: - description: |- - SecretRef specifies the Secret containing authentication credentials for - the GitRepository. - For HTTPS repositories the Secret must contain 'username' and 'password' - fields for basic auth or 'bearerToken' field for token auth. - For SSH repositories the Secret must contain 'identity' - and 'known_hosts' fields. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - serviceAccountName: - description: |- - ServiceAccountName is the name of the Kubernetes ServiceAccount used to - authenticate to the GitRepository. This field is only supported for 'azure' and 'aws' providers. - type: string - sparseCheckout: - description: |- - SparseCheckout specifies a list of directories to checkout when cloning - the repository. If specified, only these directories are included in the - Artifact produced for this GitRepository. - items: - type: string - type: array - suspend: - description: |- - Suspend tells the controller to suspend the reconciliation of this - GitRepository. - type: boolean - timeout: - default: 60s - description: Timeout for Git operations like cloning, defaults to - 60s. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ - type: string - url: - description: URL specifies the Git repository URL, it can be an HTTP/S - or SSH address. - pattern: ^(http|https|ssh)://.*$ - type: string - verify: - description: |- - Verification specifies the configuration to verify the Git commit - signature(s). - properties: - mode: - default: HEAD - description: |- - Mode specifies which Git object(s) should be verified. - - The variants "head" and "HEAD" both imply the same thing, i.e. verify - the commit that the HEAD of the Git repository points to. The variant - "head" solely exists to ensure backwards compatibility. - enum: - - head - - HEAD - - Tag - - TagAndHEAD - type: string - secretRef: - description: |- - SecretRef specifies the Secret containing the public keys of trusted Git - authors. PGP public keys must be stored under keys with the .asc suffix, - and SSH public keys must be stored under keys with the .sshpub suffix. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - required: - - secretRef - type: object - required: - - interval - - url - type: object - x-kubernetes-validations: - - message: serviceAccountName can only be set when provider is 'azure' - or 'aws' - rule: '!has(self.serviceAccountName) || (has(self.provider) && (self.provider - == ''azure'' || self.provider == ''aws''))' - status: - default: - observedGeneration: -1 - description: GitRepositoryStatus records the observed state of a Git repository. - properties: - artifact: - description: Artifact represents the last successful GitRepository - reconciliation. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - Path is the relative file path of the Artifact. It can be used to locate - the file in the root of the Artifact storage on the local file system of - the controller managing the Source. - type: string - revision: - description: |- - Revision is a human-readable identifier traceable in the origin source - system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - URL is the HTTP address of the Artifact as exposed by the controller - managing the Source. It can be used to retrieve the Artifact for - consumption, e.g. by another controller applying the Artifact contents. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the GitRepository. - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - includedArtifacts: - description: |- - IncludedArtifacts contains a list of the last successfully included - Artifacts as instructed by GitRepositorySpec.Include. - items: - description: Artifact represents the output of a Source reconciliation. - properties: - digest: - description: Digest is the digest of the file in the form of - ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI - annotations. - type: object - path: - description: |- - Path is the relative file path of the Artifact. It can be used to locate - the file in the root of the Artifact storage on the local file system of - the controller managing the Source. - type: string - revision: - description: |- - Revision is a human-readable identifier traceable in the origin source - system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - URL is the HTTP address of the Artifact as exposed by the controller - managing the Source. It can be used to retrieve the Artifact for - consumption, e.g. by another controller applying the Artifact contents. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - type: array - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedGeneration: - description: |- - ObservedGeneration is the last observed generation of the GitRepository - object. - format: int64 - type: integer - observedIgnore: - description: |- - ObservedIgnore is the observed exclusion patterns used for constructing - the source artifact. - type: string - observedInclude: - description: |- - ObservedInclude is the observed list of GitRepository resources used to - produce the current Artifact. - items: - description: |- - GitRepositoryInclude specifies a local reference to a GitRepository which - Artifact (sub-)contents must be included, and where they should be placed. - properties: - fromPath: - description: |- - FromPath specifies the path to copy contents from, defaults to the root - of the Artifact. - type: string - repository: - description: |- - GitRepositoryRef specifies the GitRepository which Artifact contents - must be included. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - toPath: - description: |- - ToPath specifies the path to copy contents to, defaults to the name of - the GitRepositoryRef. - type: string - required: - - repository - type: object - type: array - observedRecurseSubmodules: - description: |- - ObservedRecurseSubmodules is the observed resource submodules - configuration used to produce the current Artifact. - type: boolean - observedSparseCheckout: - description: |- - ObservedSparseCheckout is the observed list of directories used to - produce the current Artifact. - items: - type: string - type: array - sourceVerificationMode: - description: |- - SourceVerificationMode is the last used verification mode indicating - which Git object(s) have been verified. - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled - labels: - app.kubernetes.io/component: source-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: helmcharts.source.toolkit.fluxcd.io -spec: - group: source.toolkit.fluxcd.io - names: - categories: - - all - - fluxcd - - fluxcd-sources - kind: HelmChart - listKind: HelmChartList - plural: helmcharts - shortNames: - - hc - singular: helmchart - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.chart - name: Chart - type: string - - jsonPath: .spec.version - name: Version - type: string - - jsonPath: .spec.sourceRef.kind - name: Source Kind - type: string - - jsonPath: .spec.sourceRef.name - name: Source Name - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - name: v1 - schema: - openAPIV3Schema: - description: HelmChart is the Schema for the helmcharts API. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: HelmChartSpec specifies the desired state of a Helm chart. - properties: - chart: - description: |- - Chart is the name or path the Helm chart is available at in the - SourceRef. - type: string - ignoreMissingValuesFiles: - description: |- - IgnoreMissingValuesFiles controls whether to silently ignore missing values - files rather than failing. - type: boolean - interval: - description: |- - Interval at which the HelmChart SourceRef is checked for updates. - This interval is approximate and may be subject to jitter to ensure - efficient use of resources. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - reconcileStrategy: - default: ChartVersion - description: |- - ReconcileStrategy determines what enables the creation of a new artifact. - Valid values are ('ChartVersion', 'Revision'). - See the documentation of the values for an explanation on their behavior. - Defaults to ChartVersion when omitted. - enum: - - ChartVersion - - Revision - type: string - sourceRef: - description: SourceRef is the reference to the Source the chart is - available at. - properties: - apiVersion: - description: APIVersion of the referent. - type: string - kind: - description: |- - Kind of the referent, valid values are ('HelmRepository', 'GitRepository', - 'Bucket'). - enum: - - HelmRepository - - GitRepository - - Bucket - type: string - name: - description: Name of the referent. - type: string - required: - - kind - - name - type: object - suspend: - description: |- - Suspend tells the controller to suspend the reconciliation of this - source. - type: boolean - valuesFiles: - description: |- - ValuesFiles is an alternative list of values files to use as the chart - values (values.yaml is not included by default), expected to be a - relative path in the SourceRef. - Values files are merged in the order of this list with the last file - overriding the first. Ignored when omitted. - items: - type: string - type: array - verify: - description: |- - Verify contains the secret name containing the trusted public keys - used to verify the signature and specifies which provider to use to check - whether OCI image is authentic. - This field is only supported when using HelmRepository source with spec.type 'oci'. - Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified. - properties: - matchOIDCIdentity: - description: |- - MatchOIDCIdentity specifies the identity matching criteria to use - while verifying an OCI artifact which was signed using Cosign keyless - signing. The artifact's identity is deemed to be verified if any of the - specified matchers match against the identity. - items: - description: |- - OIDCIdentityMatch specifies options for verifying the certificate identity, - i.e. the issuer and the subject of the certificate. - properties: - issuer: - description: |- - Issuer specifies the regex pattern to match against to verify - the OIDC issuer in the Fulcio certificate. The pattern must be a - valid Go regular expression. - type: string - subject: - description: |- - Subject specifies the regex pattern to match against to verify - the identity subject in the Fulcio certificate. The pattern must - be a valid Go regular expression. - type: string - required: - - issuer - - subject - type: object - type: array - provider: - default: cosign - description: Provider specifies the technology used to sign the - OCI Artifact. - enum: - - cosign - - notation - type: string - secretRef: - description: |- - SecretRef specifies the Kubernetes Secret containing the - trusted public keys. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - required: - - provider - type: object - version: - default: '*' - description: |- - Version is the chart version semver expression, ignored for charts from - GitRepository and Bucket sources. Defaults to latest when omitted. - type: string - required: - - chart - - interval - - sourceRef - type: object - x-kubernetes-validations: - - message: spec.verify is only supported when spec.sourceRef.kind is 'HelmRepository' - rule: '!has(self.verify) || self.sourceRef.kind == ''HelmRepository''' - status: - default: - observedGeneration: -1 - description: HelmChartStatus records the observed state of the HelmChart. - properties: - artifact: - description: Artifact represents the output of the last successful - reconciliation. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - Path is the relative file path of the Artifact. It can be used to locate - the file in the root of the Artifact storage on the local file system of - the controller managing the Source. - type: string - revision: - description: |- - Revision is a human-readable identifier traceable in the origin source - system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - URL is the HTTP address of the Artifact as exposed by the controller - managing the Source. It can be used to retrieve the Artifact for - consumption, e.g. by another controller applying the Artifact contents. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the HelmChart. - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedChartName: - description: |- - ObservedChartName is the last observed chart name as specified by the - resolved chart reference. - type: string - observedGeneration: - description: |- - ObservedGeneration is the last observed generation of the HelmChart - object. - format: int64 - type: integer - observedSourceArtifactRevision: - description: |- - ObservedSourceArtifactRevision is the last observed Artifact.Revision - of the HelmChartSpec.SourceRef. - type: string - observedValuesFiles: - description: |- - ObservedValuesFiles are the observed value files of the last successful - reconciliation. - It matches the chart in the last successfully reconciled artifact. - items: - type: string - type: array - url: - description: |- - URL is the dynamic fetch link for the latest Artifact. - It is provided on a "best effort" basis, and using the precise - HelmChartStatus.Artifact data is recommended. - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled - labels: - app.kubernetes.io/component: source-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: helmrepositories.source.toolkit.fluxcd.io -spec: - group: source.toolkit.fluxcd.io - names: - categories: - - all - - fluxcd - - fluxcd-sources - kind: HelmRepository - listKind: HelmRepositoryList - plural: helmrepositories - shortNames: - - helmrepo - singular: helmrepository - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.url - name: URL - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - name: v1 - schema: - openAPIV3Schema: - description: HelmRepository is the Schema for the helmrepositories API. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: |- - HelmRepositorySpec specifies the required configuration to produce an - Artifact for a Helm repository index YAML. - properties: - accessFrom: - description: |- - AccessFrom specifies an Access Control List for allowing cross-namespace - references to this object. - NOTE: Not implemented, provisional as of https://github.com/fluxcd/flux2/pull/2092 - properties: - namespaceSelectors: - description: |- - NamespaceSelectors is the list of namespace selectors to which this ACL applies. - Items in this list are evaluated using a logical OR operation. - items: - description: |- - NamespaceSelector selects the namespaces to which this ACL applies. - An empty map of MatchLabels matches all namespaces in a cluster. - properties: - matchLabels: - additionalProperties: - type: string - description: |- - MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - type: object - type: array - required: - - namespaceSelectors - type: object - certSecretRef: - description: |- - CertSecretRef can be given the name of a Secret containing - either or both of - - - a PEM-encoded client certificate (`tls.crt`) and private - key (`tls.key`); - - a PEM-encoded CA certificate (`ca.crt`) - - and whichever are supplied, will be used for connecting to the - registry. The client cert and key are useful if you are - authenticating with a certificate; the CA cert is useful if - you are using a self-signed server certificate. The Secret must - be of type `Opaque` or `kubernetes.io/tls`. - - It takes precedence over the values specified in the Secret referred - to by `.spec.secretRef`. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - insecure: - description: |- - Insecure allows connecting to a non-TLS HTTP container registry. - This field is only taken into account if the .spec.type field is set to 'oci'. - type: boolean - interval: - description: |- - Interval at which the HelmRepository URL is checked for updates. - This interval is approximate and may be subject to jitter to ensure - efficient use of resources. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - passCredentials: - description: |- - PassCredentials allows the credentials from the SecretRef to be passed - on to a host that does not match the host as defined in URL. - This may be required if the host of the advertised chart URLs in the - index differ from the defined URL. - Enabling this should be done with caution, as it can potentially result - in credentials getting stolen in a MITM-attack. - type: boolean - provider: - default: generic - description: |- - Provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. - This field is optional, and only taken into account if the .spec.type field is set to 'oci'. - When not specified, defaults to 'generic'. - enum: - - generic - - aws - - azure - - gcp - type: string - secretRef: - description: |- - SecretRef specifies the Secret containing authentication credentials - for the HelmRepository. - For HTTP/S basic auth the secret must contain 'username' and 'password' - fields. - Support for TLS auth using the 'certFile' and 'keyFile', and/or 'caFile' - keys is deprecated. Please use `.spec.certSecretRef` instead. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - suspend: - description: |- - Suspend tells the controller to suspend the reconciliation of this - HelmRepository. - type: boolean - timeout: - description: |- - Timeout is used for the index fetch operation for an HTTPS helm repository, - and for remote OCI Repository operations like pulling for an OCI helm - chart by the associated HelmChart. - Its default value is 60s. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ - type: string - type: - description: |- - Type of the HelmRepository. - When this field is set to "oci", the URL field value must be prefixed with "oci://". - enum: - - default - - oci - type: string - url: - description: |- - URL of the Helm repository, a valid URL contains at least a protocol and - host. - pattern: ^(http|https|oci)://.*$ - type: string - required: - - url - type: object - status: - default: - observedGeneration: -1 - description: HelmRepositoryStatus records the observed state of the HelmRepository. - properties: - artifact: - description: Artifact represents the last successful HelmRepository - reconciliation. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - Path is the relative file path of the Artifact. It can be used to locate - the file in the root of the Artifact storage on the local file system of - the controller managing the Source. - type: string - revision: - description: |- - Revision is a human-readable identifier traceable in the origin source - system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - URL is the HTTP address of the Artifact as exposed by the controller - managing the Source. It can be used to retrieve the Artifact for - consumption, e.g. by another controller applying the Artifact contents. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the HelmRepository. - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedGeneration: - description: |- - ObservedGeneration is the last observed generation of the HelmRepository - object. - format: int64 - type: integer - url: - description: |- - URL is the dynamic fetch link for the latest Artifact. - It is provided on a "best effort" basis, and using the precise - HelmRepositoryStatus.Artifact data is recommended. - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled - labels: - app.kubernetes.io/component: source-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: ocirepositories.source.toolkit.fluxcd.io -spec: - group: source.toolkit.fluxcd.io - names: - categories: - - all - - fluxcd - - fluxcd-sources - kind: OCIRepository - listKind: OCIRepositoryList - plural: ocirepositories - shortNames: - - ocirepo - singular: ocirepository - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .spec.url - name: URL - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1 - schema: - openAPIV3Schema: - description: OCIRepository is the Schema for the ocirepositories API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: OCIRepositorySpec defines the desired state of OCIRepository - properties: - certSecretRef: - description: |- - CertSecretRef can be given the name of a Secret containing - either or both of - - - a PEM-encoded client certificate (`tls.crt`) and private - key (`tls.key`); - - a PEM-encoded CA certificate (`ca.crt`) - - and whichever are supplied, will be used for connecting to the - registry. The client cert and key are useful if you are - authenticating with a certificate; the CA cert is useful if - you are using a self-signed server certificate. The Secret must - be of type `Opaque` or `kubernetes.io/tls`. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - ignore: - description: |- - Ignore overrides the set of excluded patterns in the .sourceignore format - (which is the same as .gitignore). If not provided, a default will be used, - consult the documentation for your version to find out what those are. - type: string - insecure: - description: Insecure allows connecting to a non-TLS HTTP container - registry. - type: boolean - interval: - description: |- - Interval at which the OCIRepository URL is checked for updates. - This interval is approximate and may be subject to jitter to ensure - efficient use of resources. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - layerSelector: - description: |- - LayerSelector specifies which layer should be extracted from the OCI artifact. - When not specified, the first layer found in the artifact is selected. - properties: - mediaType: - description: |- - MediaType specifies the OCI media type of the layer - which should be extracted from the OCI Artifact. The - first layer matching this type is selected. - type: string - operation: - description: |- - Operation specifies how the selected layer should be processed. - By default, the layer compressed content is extracted to storage. - When the operation is set to 'copy', the layer compressed content - is persisted to storage as it is. - enum: - - extract - - copy - type: string - type: object - provider: - default: generic - description: |- - The provider used for authentication, can be 'aws', 'azure', 'gcp' or 'generic'. - When not specified, defaults to 'generic'. - enum: - - generic - - aws - - azure - - gcp - type: string - proxySecretRef: - description: |- - ProxySecretRef specifies the Secret containing the proxy configuration - to use while communicating with the container registry. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - ref: - description: |- - The OCI reference to pull and monitor for changes, - defaults to the latest tag. - properties: - digest: - description: |- - Digest is the image digest to pull, takes precedence over SemVer. - The value should be in the format 'sha256:'. - type: string - semver: - description: |- - SemVer is the range of tags to pull selecting the latest within - the range, takes precedence over Tag. - type: string - semverFilter: - description: SemverFilter is a regex pattern to filter the tags - within the SemVer range. - type: string - tag: - description: Tag is the image tag to pull, defaults to latest. - type: string - type: object - secretRef: - description: |- - SecretRef contains the secret name containing the registry login - credentials to resolve image metadata. - The secret must be of type kubernetes.io/dockerconfigjson. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - serviceAccountName: - description: |- - ServiceAccountName is the name of the Kubernetes ServiceAccount used to authenticate - the image pull if the service account has attached pull secrets. For more information: - https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account - type: string - suspend: - description: This flag tells the controller to suspend the reconciliation - of this source. - type: boolean - timeout: - default: 60s - description: The timeout for remote OCI Repository operations like - pulling, defaults to 60s. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ - type: string - url: - description: |- - URL is a reference to an OCI artifact repository hosted - on a remote container registry. - pattern: ^oci://.*$ - type: string - verify: - description: |- - Verify contains the secret name containing the trusted public keys - used to verify the signature and specifies which provider to use to check - whether OCI image is authentic. - properties: - matchOIDCIdentity: - description: |- - MatchOIDCIdentity specifies the identity matching criteria to use - while verifying an OCI artifact which was signed using Cosign keyless - signing. The artifact's identity is deemed to be verified if any of the - specified matchers match against the identity. - items: - description: |- - OIDCIdentityMatch specifies options for verifying the certificate identity, - i.e. the issuer and the subject of the certificate. - properties: - issuer: - description: |- - Issuer specifies the regex pattern to match against to verify - the OIDC issuer in the Fulcio certificate. The pattern must be a - valid Go regular expression. - type: string - subject: - description: |- - Subject specifies the regex pattern to match against to verify - the identity subject in the Fulcio certificate. The pattern must - be a valid Go regular expression. - type: string - required: - - issuer - - subject - type: object - type: array - provider: - default: cosign - description: Provider specifies the technology used to sign the - OCI Artifact. - enum: - - cosign - - notation - type: string - secretRef: - description: |- - SecretRef specifies the Kubernetes Secret containing the - trusted public keys. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - trustedRootSecretRef: - description: |- - TrustedRootSecretRef specifies the Kubernetes Secret containing a - Sigstore trusted_root.json file. This enables verification against - self-hosted Sigstore infrastructure (custom Fulcio CA, self-hosted - Rekor instance). The Secret must contain a key named "trusted_root.json". - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - required: - - provider - type: object - required: - - interval - - url - type: object - status: - default: - observedGeneration: -1 - description: OCIRepositoryStatus defines the observed state of OCIRepository - properties: - artifact: - description: Artifact represents the output of the last successful - OCI Repository sync. - properties: - digest: - description: Digest is the digest of the file in the form of ':'. - pattern: ^[a-z0-9]+(?:[.+_-][a-z0-9]+)*:[a-zA-Z0-9=_-]+$ - type: string - lastUpdateTime: - description: |- - LastUpdateTime is the timestamp corresponding to the last update of the - Artifact. - format: date-time - type: string - metadata: - additionalProperties: - type: string - description: Metadata holds upstream information such as OCI annotations. - type: object - path: - description: |- - Path is the relative file path of the Artifact. It can be used to locate - the file in the root of the Artifact storage on the local file system of - the controller managing the Source. - type: string - revision: - description: |- - Revision is a human-readable identifier traceable in the origin source - system. It can be a Git commit SHA, Git tag, a Helm chart version, etc. - type: string - size: - description: Size is the number of bytes in the file. - format: int64 - type: integer - url: - description: |- - URL is the HTTP address of the Artifact as exposed by the controller - managing the Source. It can be used to retrieve the Artifact for - consumption, e.g. by another controller applying the Artifact contents. - type: string - required: - - digest - - lastUpdateTime - - path - - revision - - url - type: object - conditions: - description: Conditions holds the conditions for the OCIRepository. - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedGeneration: - description: ObservedGeneration is the last observed generation. - format: int64 - type: integer - observedIgnore: - description: |- - ObservedIgnore is the observed exclusion patterns used for constructing - the source artifact. - type: string - observedLayerSelector: - description: |- - ObservedLayerSelector is the observed layer selector used for constructing - the source artifact. - properties: - mediaType: - description: |- - MediaType specifies the OCI media type of the layer - which should be extracted from the OCI Artifact. The - first layer matching this type is selected. - type: string - operation: - description: |- - Operation specifies how the selected layer should be processed. - By default, the layer compressed content is extracted to storage. - When the operation is set to 'copy', the layer compressed content - is persisted to storage as it is. - enum: - - extract - - copy - type: string - type: object - url: - description: URL is the download link for the artifact output of the - last OCI Repository sync. - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/component: source-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: source-controller - namespace: flux-system ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/component: source-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - control-plane: controller - name: source-controller - namespace: flux-system -spec: - ports: - - name: http - port: 80 - protocol: TCP - targetPort: http - selector: - app: source-controller - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/component: source-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - control-plane: controller - name: source-controller - namespace: flux-system -spec: - replicas: 1 - selector: - matchLabels: - app: source-controller - strategy: - type: Recreate - template: - metadata: - annotations: - prometheus.io/port: "8080" - prometheus.io/scrape: "true" - labels: - app: source-controller - app.kubernetes.io/component: source-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - spec: - containers: - - args: - - --events-addr=http://notification-controller.$(RUNTIME_NAMESPACE).svc.cluster.local./ - - --watch-all-namespaces=true - - --log-level=info - - --log-encoding=json - - --enable-leader-election - - --storage-path=/data - - --storage-adv-addr=source-controller.$(RUNTIME_NAMESPACE).svc.cluster.local. - env: - - name: RUNTIME_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: TUF_ROOT - value: /tmp/.sigstore - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - containerName: manager - resource: limits.memory - image: ghcr.io/fluxcd/source-controller:v1.9.4 - imagePullPolicy: IfNotPresent - livenessProbe: - httpGet: - path: /healthz - port: healthz - name: manager - ports: - - containerPort: 9090 - name: http - protocol: TCP - - containerPort: 8080 - name: http-prom - protocol: TCP - - containerPort: 9440 - name: healthz - protocol: TCP - readinessProbe: - httpGet: - path: / - port: http - resources: - limits: - cpu: 1000m - memory: 1Gi - requests: - cpu: 50m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - readOnlyRootFilesystem: true - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /data - name: data - - mountPath: /tmp - name: tmp - nodeSelector: - kubernetes.io/os: linux - priorityClassName: system-cluster-critical - securityContext: - fsGroup: 1337 - serviceAccountName: source-controller - terminationGracePeriodSeconds: 10 - volumes: - - emptyDir: {} - name: data - - emptyDir: {} - name: tmp ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled - labels: - app.kubernetes.io/component: kustomize-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: kustomizations.kustomize.toolkit.fluxcd.io -spec: - group: kustomize.toolkit.fluxcd.io - names: - categories: - - all - - fluxcd - - fluxcd-appliers - kind: Kustomization - listKind: KustomizationList - plural: kustomizations - shortNames: - - ks - singular: kustomization - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - name: v1 - schema: - openAPIV3Schema: - description: Kustomization is the Schema for the kustomizations API. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: |- - KustomizationSpec defines the configuration to calculate the desired state - from a Source using Kustomize. - properties: - buildMetadata: - description: |- - BuildMetadata specifies which kustomize build metadata should be added - to the built resources. The allowed values are 'originAnnotations' to - annotate resources with their source origin, and 'transformerAnnotations' - to annotate resources with the transformers that produced them. - items: - description: BuildMetadataOption defines the supported buildMetadata - options. - enum: - - originAnnotations - - transformerAnnotations - type: string - type: array - commonMetadata: - description: |- - CommonMetadata specifies the common labels and annotations that are - applied to all resources. Any existing label or annotation will be - overridden if its key matches a common one. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to be added to the object's metadata. - type: object - labels: - additionalProperties: - type: string - description: Labels to be added to the object's metadata. - type: object - type: object - components: - description: Components specifies relative paths to kustomize Components. - items: - type: string - type: array - decryption: - description: Decrypt Kubernetes secrets before applying them on the - cluster. - properties: - provider: - description: Provider is the name of the decryption engine. - enum: - - sops - type: string - secretRef: - description: |- - The secret name containing the private OpenPGP keys used for decryption. - A static credential for a cloud provider defined inside the Secret - takes priority to secret-less authentication with the ServiceAccountName - field. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - serviceAccountName: - description: |- - ServiceAccountName is the name of the service account used to - authenticate with KMS services from cloud providers. If a - static credential for a given cloud provider is defined - inside the Secret referenced by SecretRef, that static - credential takes priority. - type: string - required: - - provider - type: object - deletionPolicy: - description: |- - DeletionPolicy can be used to control garbage collection when this - Kustomization is deleted. Valid values are ('MirrorPrune', 'Delete', - 'WaitForTermination', 'Orphan'). 'MirrorPrune' mirrors the Prune field - (orphan if false, delete if true). Defaults to 'MirrorPrune'. - enum: - - MirrorPrune - - Delete - - WaitForTermination - - Orphan - type: string - dependsOn: - description: |- - DependsOn may contain a DependencyReference slice - with references to Kustomization resources that must be ready before this - Kustomization can be reconciled. - items: - description: |- - DependencyReference contains enough information to locate the referenced Kubernetes resource object - and optional CEL expression to assess its readiness. - properties: - name: - description: Name of the referent. - type: string - namespace: - description: |- - Namespace of the referent, defaults to the namespace of the resource - object that contains the reference. - type: string - readyExpr: - description: |- - ReadyExpr is a CEL expression that can be used to assess the readiness - of a dependency. When specified, the built-in readiness check - is replaced by the logic defined in the CEL expression. - To make the CEL expression additive to the built-in readiness check, - the feature gate `AdditiveCELDependencyCheck` must be set to `true`. - type: string - required: - - name - type: object - type: array - force: - default: false - description: |- - Force instructs the controller to recreate resources - when patching fails due to an immutable field change. - type: boolean - healthCheckExprs: - description: |- - HealthCheckExprs is a list of healthcheck expressions for evaluating the - health of custom resources using Common Expression Language (CEL). - The expressions are evaluated only when Wait or HealthChecks are specified. - items: - description: CustomHealthCheck defines the health check for custom - resources. - properties: - apiVersion: - description: APIVersion of the custom resource under evaluation. - type: string - current: - description: |- - Current is the CEL expression that determines if the status - of the custom resource has reached the desired state. - type: string - failed: - description: |- - Failed is the CEL expression that determines if the status - of the custom resource has failed to reach the desired state. - type: string - inProgress: - description: |- - InProgress is the CEL expression that determines if the status - of the custom resource has not yet reached the desired state. - type: string - kind: - description: Kind of the custom resource under evaluation. - type: string - required: - - apiVersion - - current - type: object - type: array - healthChecks: - description: A list of resources to be included in the health assessment. - items: - description: |- - NamespacedObjectKindReference contains enough information to locate the typed referenced Kubernetes resource object - in any namespace. - properties: - apiVersion: - description: API version of the referent, if not specified the - Kubernetes preferred version will be used. - type: string - kind: - description: Kind of the referent. - type: string - name: - description: Name of the referent. - type: string - namespace: - description: Namespace of the referent, when not specified it - acts as LocalObjectReference. - type: string - required: - - kind - - name - type: object - type: array - ignore: - description: |- - Ignore is a list of rules for specifying which changes to ignore - during drift detection. These rules are applied to the resources managed - by the Kustomization and are used to exclude specific JSON pointer paths - from the drift detection and apply process. - items: - description: |- - IgnoreRule defines a rule to selectively disregard specific changes during - the drift detection process. - properties: - paths: - description: |- - Paths is a list of JSON Pointer (RFC 6901) paths to be excluded from - consideration in a Kubernetes object. - items: - type: string - type: array - target: - description: |- - Target is a selector for specifying Kubernetes objects to which this - rule applies. - If Target is not set, the Paths will be ignored for all Kubernetes - objects within the manifest of the Kustomization. - properties: - annotationSelector: - description: |- - AnnotationSelector is a string that follows the label selection expression - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api - It matches with the resource annotations. - type: string - group: - description: |- - Group is the API group to select resources from. - Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - kind: - description: |- - Kind of the API Group to select resources from. - Together with Group and Version it is capable of unambiguously - identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - labelSelector: - description: |- - LabelSelector is a string that follows the label selection expression - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api - It matches with the resource labels. - type: string - name: - description: Name to match resources with. - type: string - namespace: - description: Namespace to select resources from. - type: string - version: - description: |- - Version of the API Group to select resources from. - Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - type: object - required: - - paths - type: object - type: array - ignoreMissingComponents: - description: |- - IgnoreMissingComponents instructs the controller to ignore Components paths - not found in source by removing them from the generated kustomization.yaml - before running kustomize build. - type: boolean - images: - description: |- - Images is a list of (image name, new name, new tag or digest) - for changing image names, tags or digests. This can also be achieved with a - patch, but this operator is simpler to specify. - items: - description: Image contains an image name, a new name, a new tag - or digest, which will replace the original name and tag. - properties: - digest: - description: |- - Digest is the value used to replace the original image tag. - If digest is present NewTag value is ignored. - type: string - name: - description: Name is a tag-less image name. - type: string - newName: - description: NewName is the value used to replace the original - name. - type: string - newTag: - description: NewTag is the value used to replace the original - tag. - type: string - required: - - name - type: object - type: array - interval: - description: |- - The interval at which to reconcile the Kustomization. - This interval is approximate and may be subject to jitter to ensure - efficient use of resources. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - kubeConfig: - description: |- - The KubeConfig for reconciling the Kustomization on a remote cluster. - When used in combination with KustomizationSpec.ServiceAccountName, - forces the controller to act on behalf of that Service Account at the - target cluster. - If the --default-service-account flag is set, its value will be used as - a controller level fallback for when KustomizationSpec.ServiceAccountName - is empty. - properties: - configMapRef: - description: |- - ConfigMapRef holds an optional name of a ConfigMap that contains - the following keys: - - - `provider`: the provider to use. One of `aws`, `azure`, `gcp`, or - `generic`. Required. - - `cluster`: the fully qualified resource name of the Kubernetes - cluster in the cloud provider API. Not used by the `generic` - provider. Required when one of `address` or `ca.crt` is not set. - - `address`: the address of the Kubernetes API server. Required - for `generic`. For the other providers, if not specified, the - first address in the cluster resource will be used, and if - specified, it must match one of the addresses in the cluster - resource. - If audiences is not set, will be used as the audience for the - `generic` provider. - - `ca.crt`: the optional PEM-encoded CA certificate for the - Kubernetes API server. If not set, the controller will use the - CA certificate from the cluster resource. - - `audiences`: the optional audiences as a list of - line-break-separated strings for the Kubernetes ServiceAccount - token. Defaults to the `address` for the `generic` provider, or - to specific values for the other providers depending on the - provider. - - `serviceAccountName`: the optional name of the Kubernetes - ServiceAccount in the same namespace that should be used - for authentication. If not specified, the controller - ServiceAccount will be used. - - Mutually exclusive with SecretRef. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - secretRef: - description: |- - SecretRef holds an optional name of a secret that contains a key with - the kubeconfig file as the value. If no key is set, the key will default - to 'value'. Mutually exclusive with ConfigMapRef. - It is recommended that the kubeconfig is self-contained, and the secret - is regularly updated if credentials such as a cloud-access-token expire. - Cloud specific `cmd-path` auth helpers will not function without adding - binaries and credentials to the Pod that is responsible for reconciling - Kubernetes resources. Supported only for the generic provider. - properties: - key: - description: Key in the Secret, when not specified an implementation-specific - default key is used. - type: string - name: - description: Name of the Secret. - type: string - required: - - name - type: object - type: object - x-kubernetes-validations: - - message: exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef - must be specified - rule: has(self.configMapRef) || has(self.secretRef) - - message: exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef - must be specified - rule: '!has(self.configMapRef) || !has(self.secretRef)' - namePrefix: - description: NamePrefix will prefix the names of all managed resources. - maxLength: 200 - minLength: 1 - type: string - nameSuffix: - description: NameSuffix will suffix the names of all managed resources. - maxLength: 200 - minLength: 1 - type: string - patches: - description: |- - Strategic merge and JSON patches, defined as inline YAML objects, - capable of targeting objects based on kind, label and annotation selectors. - items: - description: |- - Patch contains an inline StrategicMerge or JSON6902 patch, and the target the patch should - be applied to. - properties: - patch: - description: |- - Patch contains an inline StrategicMerge patch or an inline JSON6902 patch with - an array of operation objects. - type: string - target: - description: Target points to the resources that the patch document - should be applied to. - properties: - annotationSelector: - description: |- - AnnotationSelector is a string that follows the label selection expression - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api - It matches with the resource annotations. - type: string - group: - description: |- - Group is the API group to select resources from. - Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - kind: - description: |- - Kind of the API Group to select resources from. - Together with Group and Version it is capable of unambiguously - identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - labelSelector: - description: |- - LabelSelector is a string that follows the label selection expression - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api - It matches with the resource labels. - type: string - name: - description: Name to match resources with. - type: string - namespace: - description: Namespace to select resources from. - type: string - version: - description: |- - Version of the API Group to select resources from. - Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - type: object - required: - - patch - type: object - type: array - path: - description: |- - Path to the directory containing the kustomization.yaml file, or the - set of plain YAMLs a kustomization.yaml should be generated for. - Defaults to 'None', which translates to the root path of the SourceRef. - type: string - postBuild: - description: |- - PostBuild describes which actions to perform on the YAML manifest - generated by building the kustomize overlay. - properties: - substitute: - additionalProperties: - type: string - description: |- - Substitute holds a map of key/value pairs. - The variables defined in your YAML manifests that match any of the keys - defined in the map will be substituted with the set value. - Includes support for bash string replacement functions - e.g. ${var:=default}, ${var:position} and ${var/substring/replacement}. - type: object - substituteFrom: - description: |- - SubstituteFrom holds references to ConfigMaps and Secrets containing - the variables and their values to be substituted in the YAML manifests. - The ConfigMap and the Secret data keys represent the var names, and they - must match the vars declared in the manifests for the substitution to - happen. - items: - description: |- - SubstituteReference contains a reference to a resource containing - the variables name and value. - properties: - kind: - description: Kind of the values referent, valid values are - ('Secret', 'ConfigMap'). - enum: - - Secret - - ConfigMap - type: string - name: - description: |- - Name of the values referent. Should reside in the same namespace as the - referring resource. - maxLength: 253 - minLength: 1 - type: string - optional: - default: false - description: |- - Optional indicates whether the referenced resource must exist, or whether to - tolerate its absence. If true and the referenced resource is absent, proceed - as if the resource was present but empty, without any variables defined. - type: boolean - required: - - kind - - name - type: object - type: array - substituteStrategy: - description: |- - SubstituteStrategy defines the strategy for substituting variables in the YAML manifests. - Valid values are: - - - WithVariables (the default): require at least one variable to be defined, - either through the inline map or through the resolved references to ConfigMaps - and Secrets. - - Always: perform the substitution even if no variables are defined. - enum: - - WithVariables - - Always - type: string - type: object - prune: - description: Prune enables garbage collection. - type: boolean - retryInterval: - description: |- - The interval at which to retry a previously failed reconciliation. - When not specified, the controller uses the KustomizationSpec.Interval - value to retry failures. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - serviceAccountName: - description: |- - The name of the Kubernetes service account to impersonate - when reconciling this Kustomization. - type: string - sourceRef: - description: Reference of the source where the kustomization file - is. - properties: - apiVersion: - description: API version of the referent. - type: string - kind: - description: Kind of the referent. - enum: - - OCIRepository - - GitRepository - - Bucket - - ExternalArtifact - type: string - name: - description: Name of the referent. - type: string - namespace: - description: |- - Namespace of the referent, defaults to the namespace of the Kubernetes - resource object that contains the reference. - type: string - required: - - kind - - name - type: object - suspend: - description: |- - This flag tells the controller to suspend subsequent kustomize executions, - it does not apply to already started executions. Defaults to false. - type: boolean - targetNamespace: - description: |- - TargetNamespace sets or overrides the namespace in the - kustomization.yaml file. - maxLength: 63 - minLength: 1 - type: string - timeout: - description: |- - Timeout for validation, apply and health checking operations. - Defaults to 'Interval' duration. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - wait: - description: |- - Wait instructs the controller to check the health of all the reconciled - resources. When enabled, the HealthChecks are ignored. Defaults to false. - type: boolean - required: - - interval - - prune - - sourceRef - type: object - status: - default: - observedGeneration: -1 - description: KustomizationStatus defines the observed state of a kustomization. - properties: - conditions: - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - history: - description: |- - History contains a set of snapshots of the last reconciliation attempts - tracking the revision, the state and the duration of each attempt. - items: - description: |- - Snapshot represents a point-in-time record of a group of resources reconciliation, - including timing information, status, and a unique digest identifier. - properties: - digest: - description: Digest is the checksum in the format `:` - of the resources in this snapshot. - type: string - firstReconciled: - description: FirstReconciled is the time when this revision - was first reconciled to the cluster. - format: date-time - type: string - lastReconciled: - description: LastReconciled is the time when this revision was - last reconciled to the cluster. - format: date-time - type: string - lastReconciledDuration: - description: LastReconciledDuration is time it took to reconcile - the resources in this revision. - type: string - lastReconciledStatus: - description: LastReconciledStatus is the status of the last - reconciliation. - type: string - metadata: - additionalProperties: - type: string - description: Metadata contains additional information about - the snapshot. - type: object - totalReconciliations: - description: TotalReconciliations is the total number of reconciliations - that have occurred for this snapshot. - format: int64 - type: integer - required: - - digest - - firstReconciled - - lastReconciled - - lastReconciledDuration - - lastReconciledStatus - - totalReconciliations - type: object - type: array - inventory: - description: |- - Inventory contains the list of Kubernetes resource object references that - have been successfully applied. - properties: - entries: - description: Entries of Kubernetes resource object references. - items: - description: ResourceRef contains the information necessary - to locate a resource within a cluster. - properties: - id: - description: |- - ID is the string representation of the Kubernetes resource object's metadata, - in the format '___'. - type: string - v: - description: Version is the API version of the Kubernetes - resource object's kind. - type: string - required: - - id - - v - type: object - type: array - required: - - entries - type: object - lastAppliedOriginRevision: - description: |- - The last successfully applied origin revision. - Equals the origin revision of the applied Artifact from the referenced Source. - Usually present on the Metadata of the applied Artifact and depends on the - Source type, e.g. for OCI it's the value associated with the key - "org.opencontainers.image.revision". - type: string - lastAppliedRevision: - description: |- - The last successfully applied revision. - Equals the Revision of the applied Artifact from the referenced Source. - type: string - lastAttemptedRevision: - description: LastAttemptedRevision is the revision of the last reconciliation - attempt. - type: string - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedGeneration: - description: ObservedGeneration is the last reconciled generation. - format: int64 - type: integer - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/component: kustomize-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: kustomize-controller - namespace: flux-system ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/component: kustomize-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - control-plane: controller - name: kustomize-controller - namespace: flux-system -spec: - replicas: 1 - selector: - matchLabels: - app: kustomize-controller - template: - metadata: - annotations: - prometheus.io/port: "8080" - prometheus.io/scrape: "true" - labels: - app: kustomize-controller - app.kubernetes.io/component: kustomize-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - spec: - containers: - - args: - - --events-addr=http://notification-controller.$(RUNTIME_NAMESPACE).svc.cluster.local./ - - --watch-all-namespaces=true - - --log-level=info - - --log-encoding=json - - --enable-leader-election - env: - - name: RUNTIME_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - containerName: manager - resource: limits.memory - image: ghcr.io/fluxcd/kustomize-controller:v1.9.4 - imagePullPolicy: IfNotPresent - livenessProbe: - httpGet: - path: /healthz - port: healthz - name: manager - ports: - - containerPort: 8080 - name: http-prom - protocol: TCP - - containerPort: 9440 - name: healthz - protocol: TCP - readinessProbe: - httpGet: - path: /readyz - port: healthz - resources: - limits: - cpu: 1000m - memory: 1Gi - requests: - cpu: 100m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - readOnlyRootFilesystem: true - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /tmp - name: temp - nodeSelector: - kubernetes.io/os: linux - priorityClassName: system-cluster-critical - securityContext: - fsGroup: 1337 - serviceAccountName: kustomize-controller - terminationGracePeriodSeconds: 60 - volumes: - - emptyDir: {} - name: temp ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled - labels: - app.kubernetes.io/component: helm-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: helmreleases.helm.toolkit.fluxcd.io -spec: - group: helm.toolkit.fluxcd.io - names: - categories: - - all - - fluxcd - - fluxcd-appliers - kind: HelmRelease - listKind: HelmReleaseList - plural: helmreleases - shortNames: - - hr - singular: helmrelease - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - name: v2 - schema: - openAPIV3Schema: - description: HelmRelease is the Schema for the helmreleases API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: HelmReleaseSpec defines the desired state of a Helm release. - properties: - chart: - description: |- - Chart defines the template of the v1.HelmChart that should be created - for this HelmRelease. - properties: - metadata: - description: ObjectMeta holds the template for metadata like labels - and annotations. - properties: - annotations: - additionalProperties: - type: string - description: |- - Annotations is an unstructured key value map stored with a resource that may be - set by external tools to store and retrieve arbitrary metadata. They are not - queryable and should be preserved when modifying objects. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ - type: object - labels: - additionalProperties: - type: string - description: |- - Map of string keys and values that can be used to organize and categorize - (scope and select) objects. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ - type: object - type: object - spec: - description: Spec holds the template for the v1.HelmChartSpec - for this HelmRelease. - properties: - chart: - description: The name or path the Helm chart is available - at in the SourceRef. - maxLength: 2048 - minLength: 1 - type: string - ignoreMissingValuesFiles: - description: IgnoreMissingValuesFiles controls whether to - silently ignore missing values files rather than failing. - type: boolean - interval: - description: |- - Interval at which to check the v1.Source for updates. Defaults to - 'HelmReleaseSpec.Interval'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - reconcileStrategy: - default: ChartVersion - description: |- - Determines what enables the creation of a new artifact. Valid values are - ('ChartVersion', 'Revision'). - See the documentation of the values for an explanation on their behavior. - Defaults to ChartVersion when omitted. - enum: - - ChartVersion - - Revision - type: string - sourceRef: - description: The name and namespace of the v1.Source the chart - is available at. - properties: - apiVersion: - description: APIVersion of the referent. - type: string - kind: - description: Kind of the referent. - enum: - - HelmRepository - - GitRepository - - Bucket - type: string - name: - description: Name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: Namespace of the referent. - maxLength: 63 - minLength: 1 - type: string - required: - - kind - - name - type: object - valuesFiles: - description: |- - Alternative list of values files to use as the chart values (values.yaml - is not included by default), expected to be a relative path in the SourceRef. - Values files are merged in the order of this list with the last file overriding - the first. Ignored when omitted. - items: - type: string - type: array - verify: - description: |- - Verify contains the secret name containing the trusted public keys - used to verify the signature and specifies which provider to use to check - whether OCI image is authentic. - This field is only supported for OCI sources. - Chart dependencies, which are not bundled in the umbrella chart artifact, - are not verified. - properties: - provider: - default: cosign - description: Provider specifies the technology used to - sign the OCI Helm chart. - enum: - - cosign - - notation - type: string - secretRef: - description: |- - SecretRef specifies the Kubernetes Secret containing the - trusted public keys. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - required: - - provider - type: object - version: - default: '*' - description: |- - Version semver expression, ignored for charts from v1.GitRepository and - v1beta2.Bucket sources. Defaults to latest when omitted. - type: string - required: - - chart - - sourceRef - type: object - required: - - spec - type: object - chartRef: - description: |- - ChartRef holds a reference to a source controller resource containing the - Helm chart artifact. - properties: - apiVersion: - description: APIVersion of the referent. - type: string - kind: - description: Kind of the referent. - enum: - - OCIRepository - - HelmChart - - ExternalArtifact - type: string - name: - description: Name of the referent. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: |- - Namespace of the referent, defaults to the namespace of the Kubernetes - resource object that contains the reference. - maxLength: 63 - minLength: 1 - type: string - required: - - kind - - name - type: object - commonMetadata: - description: |- - CommonMetadata specifies the common labels and annotations that are - applied to all resources. Any existing label or annotation will be - overridden if its key matches a common one. - properties: - annotations: - additionalProperties: - type: string - description: Annotations to be added to the object's metadata. - type: object - labels: - additionalProperties: - type: string - description: Labels to be added to the object's metadata. - type: object - type: object - dependsOn: - description: |- - DependsOn may contain a DependencyReference slice with - references to HelmRelease resources that must be ready before this HelmRelease - can be reconciled. - items: - description: |- - DependencyReference contains enough information to locate the referenced Kubernetes resource object - and optional CEL expression to assess its readiness. - properties: - name: - description: Name of the referent. - type: string - namespace: - description: |- - Namespace of the referent, defaults to the namespace of the resource - object that contains the reference. - type: string - readyExpr: - description: |- - ReadyExpr is a CEL expression that can be used to assess the readiness - of a dependency. When specified, the built-in readiness check - is replaced by the logic defined in the CEL expression. - To make the CEL expression additive to the built-in readiness check, - the feature gate `AdditiveCELDependencyCheck` must be set to `true`. - type: string - required: - - name - type: object - type: array - driftDetection: - description: |- - DriftDetection holds the configuration for detecting and handling - differences between the manifest in the Helm storage and the resources - currently existing in the cluster. - properties: - ignore: - description: |- - Ignore contains a list of rules for specifying which changes to ignore - during diffing. - items: - description: |- - IgnoreRule defines a rule to selectively disregard specific changes during - the drift detection process. - properties: - paths: - description: |- - Paths is a list of JSON Pointer (RFC 6901) paths to be excluded from - consideration in a Kubernetes object. - items: - type: string - type: array - target: - description: |- - Target is a selector for specifying Kubernetes objects to which this - rule applies. - If Target is not set, the Paths will be ignored for all Kubernetes - objects within the manifest of the Helm release. - properties: - annotationSelector: - description: |- - AnnotationSelector is a string that follows the label selection expression - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api - It matches with the resource annotations. - type: string - group: - description: |- - Group is the API group to select resources from. - Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - kind: - description: |- - Kind of the API Group to select resources from. - Together with Group and Version it is capable of unambiguously - identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - labelSelector: - description: |- - LabelSelector is a string that follows the label selection expression - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api - It matches with the resource labels. - type: string - name: - description: Name to match resources with. - type: string - namespace: - description: Namespace to select resources from. - type: string - version: - description: |- - Version of the API Group to select resources from. - Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - type: object - required: - - paths - type: object - type: array - mode: - description: |- - Mode defines how differences should be handled between the Helm manifest - and the manifest currently applied to the cluster. - If not explicitly set, it defaults to DiffModeDisabled. - enum: - - enabled - - warn - - disabled - type: string - type: object - healthCheckExprs: - description: |- - HealthCheckExprs is a list of healthcheck expressions for evaluating the - health of custom resources using Common Expression Language (CEL). - The expressions are evaluated only when the specific Helm action - taking place has wait enabled, i.e. DisableWait is false, and the - 'poller' WaitStrategy is used. - items: - description: CustomHealthCheck defines the health check for custom - resources. - properties: - apiVersion: - description: APIVersion of the custom resource under evaluation. - type: string - current: - description: |- - Current is the CEL expression that determines if the status - of the custom resource has reached the desired state. - type: string - failed: - description: |- - Failed is the CEL expression that determines if the status - of the custom resource has failed to reach the desired state. - type: string - inProgress: - description: |- - InProgress is the CEL expression that determines if the status - of the custom resource has not yet reached the desired state. - type: string - kind: - description: Kind of the custom resource under evaluation. - type: string - required: - - apiVersion - - current - type: object - type: array - install: - description: Install holds the configuration for Helm install actions - for this HelmRelease. - properties: - crds: - description: |- - CRDs upgrade CRDs from the Helm Chart's crds directory according - to the CRD upgrade policy provided here. Valid values are `Skip`, - `Create` or `CreateReplace`. Default is `Create` and if omitted - CRDs are installed but not updated. - - Skip: do neither install nor replace (update) any CRDs. - - Create: new CRDs are created, existing CRDs are neither updated nor deleted. - - CreateReplace: new CRDs are created, existing CRDs are updated (replaced) - but not deleted. - - By default, CRDs are applied (installed) during Helm install action. - With this option users can opt in to CRD replace existing CRDs on Helm - install actions, which is not (yet) natively supported by Helm. - https://helm.sh/docs/chart_best_practices/custom_resource_definitions. - enum: - - Skip - - Create - - CreateReplace - type: string - createNamespace: - description: |- - CreateNamespace tells the Helm install action to create the - HelmReleaseSpec.TargetNamespace if it does not exist yet. - On uninstall, the namespace will not be garbage collected. - type: boolean - disableHooks: - description: DisableHooks prevents hooks from running during the - Helm install action. - type: boolean - disableOpenAPIValidation: - description: |- - DisableOpenAPIValidation prevents the Helm install action from validating - rendered templates against the Kubernetes OpenAPI Schema. - type: boolean - disableSchemaValidation: - description: |- - DisableSchemaValidation prevents the Helm install action from validating - the values against the JSON Schema. - type: boolean - disableTakeOwnership: - description: |- - DisableTakeOwnership disables taking ownership of existing resources - during the Helm install action. Defaults to false. - type: boolean - disableWait: - description: |- - DisableWait disables the waiting for resources to be ready after a Helm - install has been performed. - type: boolean - disableWaitForJobs: - description: |- - DisableWaitForJobs disables waiting for jobs to complete after a Helm - install has been performed. - type: boolean - remediation: - description: |- - Remediation holds the remediation configuration for when the Helm install - action for the HelmRelease fails. The default is to not perform any action. - properties: - ignoreTestFailures: - description: |- - IgnoreTestFailures tells the controller to skip remediation when the Helm - tests are run after an install action but fail. Defaults to - 'Test.IgnoreFailures'. - type: boolean - remediateLastFailure: - description: |- - RemediateLastFailure tells the controller to remediate the last failure, when - no retries remain. Defaults to 'false'. - type: boolean - retries: - description: |- - Retries is the number of retries that should be attempted on failures before - bailing. Remediation, using an uninstall, is performed between each attempt. - Defaults to '0', a negative integer equals to unlimited retries. - type: integer - type: object - replace: - description: |- - Replace tells the Helm install action to re-use the 'ReleaseName', but only - if that name is a deleted release which remains in the history. - type: boolean - serverSideApply: - description: |- - ServerSideApply enables server-side apply for resources during install. - Defaults to true (or false when UseHelm3Defaults feature gate is enabled). - type: boolean - skipCRDs: - description: |- - SkipCRDs tells the Helm install action to not install any CRDs. By default, - CRDs are installed if not already present. - - Deprecated use CRD policy (`crds`) attribute with value `Skip` instead. - type: boolean - strategy: - description: |- - Strategy defines the install strategy to use for this HelmRelease. - Defaults to 'RemediateOnFailure', or 'RetryOnFailure' when the - DefaultToRetryOnFailure feature gate is enabled. - properties: - name: - description: Name of the install strategy. - enum: - - RemediateOnFailure - - RetryOnFailure - type: string - retryInterval: - description: |- - RetryInterval is the interval at which to retry a failed install. - Can be used only when Name is set to RetryOnFailure. - Defaults to '5m'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - required: - - name - type: object - x-kubernetes-validations: - - message: .retryInterval cannot be set when .name is 'RemediateOnFailure' - rule: '!has(self.retryInterval) || self.name != ''RemediateOnFailure''' - timeout: - description: |- - Timeout is the time to wait for any individual Kubernetes operation (like - Jobs for hooks) during the performance of a Helm install action. Defaults to - 'HelmReleaseSpec.Timeout'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - type: object - interval: - description: Interval at which to reconcile the Helm release. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - kubeConfig: - description: |- - KubeConfig for reconciling the HelmRelease on a remote cluster. - When used in combination with HelmReleaseSpec.ServiceAccountName, - forces the controller to act on behalf of that Service Account at the - target cluster. - If the --default-service-account flag is set, its value will be used as - a controller level fallback for when HelmReleaseSpec.ServiceAccountName - is empty. - properties: - configMapRef: - description: |- - ConfigMapRef holds an optional name of a ConfigMap that contains - the following keys: - - - `provider`: the provider to use. One of `aws`, `azure`, `gcp`, or - `generic`. Required. - - `cluster`: the fully qualified resource name of the Kubernetes - cluster in the cloud provider API. Not used by the `generic` - provider. Required when one of `address` or `ca.crt` is not set. - - `address`: the address of the Kubernetes API server. Required - for `generic`. For the other providers, if not specified, the - first address in the cluster resource will be used, and if - specified, it must match one of the addresses in the cluster - resource. - If audiences is not set, will be used as the audience for the - `generic` provider. - - `ca.crt`: the optional PEM-encoded CA certificate for the - Kubernetes API server. If not set, the controller will use the - CA certificate from the cluster resource. - - `audiences`: the optional audiences as a list of - line-break-separated strings for the Kubernetes ServiceAccount - token. Defaults to the `address` for the `generic` provider, or - to specific values for the other providers depending on the - provider. - - `serviceAccountName`: the optional name of the Kubernetes - ServiceAccount in the same namespace that should be used - for authentication. If not specified, the controller - ServiceAccount will be used. - - Mutually exclusive with SecretRef. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - secretRef: - description: |- - SecretRef holds an optional name of a secret that contains a key with - the kubeconfig file as the value. If no key is set, the key will default - to 'value'. Mutually exclusive with ConfigMapRef. - It is recommended that the kubeconfig is self-contained, and the secret - is regularly updated if credentials such as a cloud-access-token expire. - Cloud specific `cmd-path` auth helpers will not function without adding - binaries and credentials to the Pod that is responsible for reconciling - Kubernetes resources. Supported only for the generic provider. - properties: - key: - description: Key in the Secret, when not specified an implementation-specific - default key is used. - type: string - name: - description: Name of the Secret. - type: string - required: - - name - type: object - type: object - x-kubernetes-validations: - - message: exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef - must be specified - rule: has(self.configMapRef) || has(self.secretRef) - - message: exactly one of spec.kubeConfig.configMapRef or spec.kubeConfig.secretRef - must be specified - rule: '!has(self.configMapRef) || !has(self.secretRef)' - maxHistory: - description: |- - MaxHistory is the number of revisions saved by Helm for this HelmRelease. - Use '0' for an unlimited number of revisions; defaults to '5'. - type: integer - persistentClient: - description: |- - PersistentClient tells the controller to use a persistent Kubernetes - client for this release. When enabled, the client will be reused for the - duration of the reconciliation, instead of being created and destroyed - for each (step of a) Helm action. - - This can improve performance, but may cause issues with some Helm charts - that for example do create Custom Resource Definitions during installation - outside Helm's CRD lifecycle hooks, which are then not observed to be - available by e.g. post-install hooks. - - If not set, it defaults to true. - type: boolean - postRenderStrategy: - description: |- - PostRenderStrategy defines the strategy for sending hooks to post-renderers. - Valid values are 'nohooks' (hooks not sent to post-renderers, Helm 3 behavior), - 'combined' (hooks and templates sent together, Helm 4 default), and 'separate' - (hooks and templates sent in separate streams, Helm 4.2 opt-in). - Defaults to 'combined', or 'nohooks' when the UseHelm3Defaults feature gate is enabled. - enum: - - nohooks - - combined - - separate - type: string - postRenderers: - description: |- - PostRenderers holds an array of Helm PostRenderers, which will be applied in order - of their definition. - items: - description: PostRenderer contains a Helm PostRenderer specification. - properties: - kustomize: - description: Kustomization to apply as PostRenderer. - properties: - images: - description: |- - Images is a list of (image name, new name, new tag or digest) - for changing image names, tags or digests. This can also be achieved with a - patch, but this operator is simpler to specify. - items: - description: Image contains an image name, a new name, - a new tag or digest, which will replace the original - name and tag. - properties: - digest: - description: |- - Digest is the value used to replace the original image tag. - If digest is present NewTag value is ignored. - type: string - name: - description: Name is a tag-less image name. - type: string - newName: - description: NewName is the value used to replace - the original name. - type: string - newTag: - description: NewTag is the value used to replace the - original tag. - type: string - required: - - name - type: object - type: array - patches: - description: |- - Strategic merge and JSON patches, defined as inline YAML objects, - capable of targeting objects based on kind, label and annotation selectors. - items: - description: |- - Patch contains an inline StrategicMerge or JSON6902 patch, and the target the patch should - be applied to. - properties: - patch: - description: |- - Patch contains an inline StrategicMerge patch or an inline JSON6902 patch with - an array of operation objects. - type: string - target: - description: Target points to the resources that the - patch document should be applied to. - properties: - annotationSelector: - description: |- - AnnotationSelector is a string that follows the label selection expression - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api - It matches with the resource annotations. - type: string - group: - description: |- - Group is the API group to select resources from. - Together with Version and Kind it is capable of unambiguously identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - kind: - description: |- - Kind of the API Group to select resources from. - Together with Group and Version it is capable of unambiguously - identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - labelSelector: - description: |- - LabelSelector is a string that follows the label selection expression - https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#api - It matches with the resource labels. - type: string - name: - description: Name to match resources with. - type: string - namespace: - description: Namespace to select resources from. - type: string - version: - description: |- - Version of the API Group to select resources from. - Together with Group and Kind it is capable of unambiguously identifying and/or selecting resources. - https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-machinery/api-group.md - type: string - type: object - required: - - patch - type: object - type: array - type: object - type: object - type: array - releaseName: - description: |- - ReleaseName used for the Helm release. Defaults to a composition of - '[TargetNamespace-]Name'. - maxLength: 53 - minLength: 1 - type: string - rollback: - description: Rollback holds the configuration for Helm rollback actions - for this HelmRelease. - properties: - cleanupOnFail: - description: |- - CleanupOnFail allows deletion of new resources created during the Helm - rollback action when it fails. - type: boolean - disableHooks: - description: DisableHooks prevents hooks from running during the - Helm rollback action. - type: boolean - disableWait: - description: |- - DisableWait disables the waiting for resources to be ready after a Helm - rollback has been performed. - type: boolean - disableWaitForJobs: - description: |- - DisableWaitForJobs disables waiting for jobs to complete after a Helm - rollback has been performed. - type: boolean - force: - description: |- - Force forces resource updates through a replacement strategy - that avoids 3-way merge conflicts on client-side apply. - This field is ignored for server-side apply (which always - forces conflicts with other field managers). - type: boolean - recreate: - description: |- - Recreate performs pod restarts for any managed workloads. - - Deprecated: This behavior was deprecated in Helm 3: - - Deprecation: https://github.com/helm/helm/pull/6463 - - Removal: https://github.com/helm/helm/pull/31023 - After helm-controller was upgraded to the Helm 4 SDK, - this field is no longer functional and will print a - warning if set to true. It will also be removed in a - future release. - type: boolean - serverSideApply: - description: |- - ServerSideApply enables server-side apply for resources during rollback. - Can be "enabled", "disabled", or "auto". - When "auto", server-side apply usage will be based on the release's previous usage. - Defaults to "auto". - enum: - - enabled - - disabled - - auto - type: string - timeout: - description: |- - Timeout is the time to wait for any individual Kubernetes operation (like - Jobs for hooks) during the performance of a Helm rollback action. Defaults to - 'HelmReleaseSpec.Timeout'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - type: object - serviceAccountName: - description: |- - The name of the Kubernetes service account to impersonate - when reconciling this HelmRelease. - maxLength: 253 - minLength: 1 - type: string - storageNamespace: - description: |- - StorageNamespace used for the Helm storage. - Defaults to the namespace of the HelmRelease. - maxLength: 63 - minLength: 1 - type: string - suspend: - description: |- - Suspend tells the controller to suspend reconciliation for this HelmRelease, - it does not apply to already started reconciliations. Defaults to false. - type: boolean - targetNamespace: - description: |- - TargetNamespace to target when performing operations for the HelmRelease. - Defaults to the namespace of the HelmRelease. - maxLength: 63 - minLength: 1 - type: string - test: - description: Test holds the configuration for Helm test actions for - this HelmRelease. - properties: - enable: - description: |- - Enable enables Helm test actions for this HelmRelease after an Helm install - or upgrade action has been performed. - type: boolean - filters: - description: Filters is a list of tests to run or exclude from - running. - items: - description: Filter holds the configuration for individual Helm - test filters. - properties: - exclude: - description: Exclude specifies whether the named test should - be excluded. - type: boolean - name: - description: Name is the name of the test. - maxLength: 253 - minLength: 1 - type: string - required: - - name - type: object - type: array - ignoreFailures: - description: |- - IgnoreFailures tells the controller to skip remediation when the Helm tests - are run but fail. Can be overwritten for tests run after install or upgrade - actions in 'Install.IgnoreTestFailures' and 'Upgrade.IgnoreTestFailures'. - type: boolean - timeout: - description: |- - Timeout is the time to wait for any individual Kubernetes operation during - the performance of a Helm test action. Defaults to 'HelmReleaseSpec.Timeout'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - type: object - timeout: - description: |- - Timeout is the time to wait for any individual Kubernetes operation (like Jobs - for hooks) during the performance of a Helm action. Defaults to '5m0s'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - uninstall: - description: Uninstall holds the configuration for Helm uninstall - actions for this HelmRelease. - properties: - deletionPropagation: - default: background - description: |- - DeletionPropagation specifies the deletion propagation policy when - a Helm uninstall is performed. - enum: - - background - - foreground - - orphan - type: string - disableHooks: - description: DisableHooks prevents hooks from running during the - Helm rollback action. - type: boolean - disableWait: - description: |- - DisableWait disables waiting for all the resources to be deleted after - a Helm uninstall is performed. - type: boolean - keepHistory: - description: |- - KeepHistory tells Helm to remove all associated resources and mark the - release as deleted, but retain the release history. - type: boolean - timeout: - description: |- - Timeout is the time to wait for any individual Kubernetes operation (like - Jobs for hooks) during the performance of a Helm uninstall action. Defaults - to 'HelmReleaseSpec.Timeout'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - type: object - upgrade: - description: Upgrade holds the configuration for Helm upgrade actions - for this HelmRelease. - properties: - chartNameChangeStrategy: - description: |- - ChartNameChangeStrategy defines the strategy to use when a Helm chart name changes. - Valid values are 'Reinstall' or 'InPlaceUpdate'. Defaults to 'Reinstall' if omitted. - - Reinstall: Reinstall the Helm release, uninstalling the existing Helm release. - - InPlaceUpdate: Update the Helm release in place. - enum: - - InPlaceUpdate - - Reinstall - type: string - cleanupOnFail: - description: |- - CleanupOnFail allows deletion of new resources created during the Helm - upgrade action when it fails. - type: boolean - crds: - description: |- - CRDs upgrade CRDs from the Helm Chart's crds directory according - to the CRD upgrade policy provided here. Valid values are `Skip`, - `Create` or `CreateReplace`. Default is `Skip` and if omitted - CRDs are neither installed nor upgraded. - - Skip: do neither install nor replace (update) any CRDs. - - Create: new CRDs are created, existing CRDs are neither updated nor deleted. - - CreateReplace: new CRDs are created, existing CRDs are updated (replaced) - but not deleted. - - By default, CRDs are not applied during Helm upgrade action. With this - option users can opt-in to CRD upgrade, which is not (yet) natively supported by Helm. - https://helm.sh/docs/chart_best_practices/custom_resource_definitions. - enum: - - Skip - - Create - - CreateReplace - type: string - disableHooks: - description: DisableHooks prevents hooks from running during the - Helm upgrade action. - type: boolean - disableOpenAPIValidation: - description: |- - DisableOpenAPIValidation prevents the Helm upgrade action from validating - rendered templates against the Kubernetes OpenAPI Schema. - type: boolean - disableSchemaValidation: - description: |- - DisableSchemaValidation prevents the Helm upgrade action from validating - the values against the JSON Schema. - type: boolean - disableTakeOwnership: - description: |- - DisableTakeOwnership disables taking ownership of existing resources - during the Helm upgrade action. Defaults to false. - type: boolean - disableWait: - description: |- - DisableWait disables the waiting for resources to be ready after a Helm - upgrade has been performed. - type: boolean - disableWaitForJobs: - description: |- - DisableWaitForJobs disables waiting for jobs to complete after a Helm - upgrade has been performed. - type: boolean - force: - description: |- - Force forces resource updates through a replacement strategy - that avoids 3-way merge conflicts on client-side apply. - This field is ignored for server-side apply (which always - forces conflicts with other field managers). - type: boolean - preserveValues: - description: |- - PreserveValues will make Helm reuse the last release's values and merge in - overrides from 'Values'. Setting this flag makes the HelmRelease - non-declarative. - type: boolean - remediation: - description: |- - Remediation holds the remediation configuration for when the Helm upgrade - action for the HelmRelease fails. The default is to not perform any action. - properties: - ignoreTestFailures: - description: |- - IgnoreTestFailures tells the controller to skip remediation when the Helm - tests are run after an upgrade action but fail. - Defaults to 'Test.IgnoreFailures'. - type: boolean - remediateLastFailure: - description: |- - RemediateLastFailure tells the controller to remediate the last failure, when - no retries remain. Defaults to 'false' unless 'Retries' is greater than 0. - type: boolean - retries: - description: |- - Retries is the number of retries that should be attempted on failures before - bailing. Remediation, using 'Strategy', is performed between each attempt. - Defaults to '0', a negative integer equals to unlimited retries. - type: integer - strategy: - description: Strategy to use for failure remediation. Defaults - to 'rollback'. - enum: - - rollback - - uninstall - type: string - type: object - serverSideApply: - description: |- - ServerSideApply enables server-side apply for resources during upgrade. - Can be "enabled", "disabled", or "auto". - When "auto", server-side apply usage will be based on the release's previous usage. - Defaults to "auto". - enum: - - enabled - - disabled - - auto - type: string - strategy: - description: |- - Strategy defines the upgrade strategy to use for this HelmRelease. - Defaults to 'RemediateOnFailure', or 'RetryOnFailure' when the - DefaultToRetryOnFailure feature gate is enabled. - properties: - name: - description: Name of the upgrade strategy. - enum: - - RemediateOnFailure - - RetryOnFailure - type: string - retryInterval: - description: |- - RetryInterval is the interval at which to retry a failed upgrade. - Can be used only when Name is set to RetryOnFailure. - Defaults to '5m'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - required: - - name - type: object - x-kubernetes-validations: - - message: .retryInterval can only be set when .name is 'RetryOnFailure' - rule: '!has(self.retryInterval) || self.name == ''RetryOnFailure''' - timeout: - description: |- - Timeout is the time to wait for any individual Kubernetes operation (like - Jobs for hooks) during the performance of a Helm upgrade action. Defaults to - 'HelmReleaseSpec.Timeout'. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - type: object - values: - description: Values holds the values for this Helm release. - x-kubernetes-preserve-unknown-fields: true - valuesFrom: - description: |- - ValuesFrom holds references to resources containing Helm values for this HelmRelease, - and information about how they should be merged. - items: - description: |- - ValuesReference contains a reference to a resource containing Helm values, - and optionally the key they can be found at. - properties: - kind: - description: Kind of the values referent, valid values are ('Secret', - 'ConfigMap'). - enum: - - Secret - - ConfigMap - type: string - literal: - description: |- - Literal marks this ValuesReference as a literal value. When set in - combination with TargetPath, the referenced value is merged at the target - path without interpreting Helm's `--set` syntax (commas, brackets, dots, - equal signs, etc.), mirroring the behavior of `helm --set-literal`. This - is the only safe way to inject arbitrary file content (config files, JSON - blobs, multi-line strings containing special characters) through - `valuesFrom`. Has no effect when TargetPath is empty: in that mode the - referenced value is always YAML-merged at the root. - type: boolean - name: - description: |- - Name of the values referent. Should reside in the same namespace as the - referring resource. - maxLength: 253 - minLength: 1 - type: string - optional: - description: |- - Optional marks this ValuesReference as optional. When set, a not found error - for the values reference is ignored, but any ValuesKey, TargetPath or - transient error will still result in a reconciliation failure. - type: boolean - targetPath: - description: |- - TargetPath is the YAML dot notation path the value should be merged at. When - set, the ValuesKey is expected to be a single flat value. Defaults to 'None', - which results in the values getting merged at the root. - maxLength: 250 - pattern: ^([a-zA-Z0-9_\-.\\\/]|\[[0-9]{1,5}\])+$ - type: string - valuesKey: - description: |- - ValuesKey is the data key where the values.yaml or a specific value can be - found at. Defaults to 'values.yaml'. - maxLength: 253 - pattern: ^[\-._a-zA-Z0-9]+$ - type: string - required: - - kind - - name - type: object - type: array - waitStrategy: - description: |- - WaitStrategy defines Helm's wait strategy for waiting for applied - resources to become ready. - properties: - name: - description: |- - Name is Helm's wait strategy for waiting for applied resources to - become ready. One of 'poller' or 'legacy'. The 'poller' strategy uses - kstatus to poll resource statuses, while the 'legacy' strategy uses - Helm v3's waiting logic. - Defaults to 'poller', or to 'legacy' when UseHelm3Defaults feature - gate is enabled. - enum: - - poller - - legacy - type: string - required: - - name - type: object - required: - - interval - type: object - x-kubernetes-validations: - - message: either chart or chartRef must be set - rule: (has(self.chart) && !has(self.chartRef)) || (!has(self.chart) - && has(self.chartRef)) - status: - default: - observedGeneration: -1 - description: HelmReleaseStatus defines the observed state of a HelmRelease. - properties: - conditions: - description: Conditions holds the conditions for the HelmRelease. - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - failures: - description: |- - Failures is the reconciliation failure count against the latest desired - state. It is reset after a successful reconciliation. - format: int64 - type: integer - helmChart: - description: |- - HelmChart is the namespaced name of the HelmChart resource created by - the controller for the HelmRelease. - type: string - history: - description: |- - History holds the history of Helm releases performed for this HelmRelease - up to the last successfully completed release. - items: - description: |- - Snapshot captures a point-in-time copy of the status information for a Helm release, - as managed by the controller. - properties: - action: - description: Action is the action that resulted in this snapshot - being created. - type: string - apiVersion: - description: |- - APIVersion is the API version of the Snapshot. - When the calculation method of the Digest field is changed, this - field will be used to distinguish between the old and new methods. - type: string - appVersion: - description: AppVersion is the chart app version of the release - object in storage. - type: string - chartName: - description: ChartName is the chart name of the release object - in storage. - type: string - chartVersion: - description: |- - ChartVersion is the chart version of the release object in - storage. - type: string - configDigest: - description: |- - ConfigDigest is the checksum of the config (better known as - "values") of the release object in storage. - It has the format of `:`. - type: string - deleted: - description: Deleted is when the release was deleted. - format: date-time - type: string - digest: - description: |- - Digest is the checksum of the release object in storage. - It has the format of `:`. - type: string - firstDeployed: - description: FirstDeployed is when the release was first deployed. - format: date-time - type: string - lastDeployed: - description: LastDeployed is when the release was last deployed. - format: date-time - type: string - name: - description: Name is the name of the release. - type: string - namespace: - description: Namespace is the namespace the release is deployed - to. - type: string - ociDigest: - description: OCIDigest is the digest of the OCI artifact associated - with the release. - type: string - status: - description: Status is the current state of the release. - type: string - testHooks: - additionalProperties: - description: |- - TestHookStatus holds the status information for a test hook as observed - to be run by the controller. - properties: - lastCompleted: - description: LastCompleted is the time the test hook last - completed. - format: date-time - type: string - lastStarted: - description: LastStarted is the time the test hook was - last started. - format: date-time - type: string - phase: - description: Phase the test hook was observed to be in. - type: string - type: object - description: |- - TestHooks is the list of test hooks for the release as observed to be - run by the controller. - type: object - version: - description: Version is the version of the release object in - storage. - type: integer - required: - - chartName - - chartVersion - - configDigest - - digest - - firstDeployed - - lastDeployed - - name - - namespace - - status - - version - type: object - type: array - installFailures: - description: |- - InstallFailures is the install failure count against the latest desired - state. It is reset after a successful reconciliation. - format: int64 - type: integer - inventory: - description: |- - Inventory contains the list of Kubernetes resource object references - that have been applied for this release. - properties: - entries: - description: Entries of Kubernetes resource object references. - items: - description: ResourceRef contains the information necessary - to locate a resource within a cluster. - properties: - id: - description: |- - ID is the string representation of the Kubernetes resource object's metadata, - in the format '___'. - type: string - v: - description: Version is the API version of the Kubernetes - resource object's kind. - type: string - required: - - id - - v - type: object - type: array - required: - - entries - type: object - lastAttemptedConfigDigest: - description: |- - LastAttemptedConfigDigest is the digest for the config (better known as - "values") of the last reconciliation attempt. - type: string - lastAttemptedGeneration: - description: |- - LastAttemptedGeneration is the last generation the controller attempted - to reconcile. - format: int64 - type: integer - lastAttemptedReleaseAction: - description: |- - LastAttemptedReleaseAction is the last release action performed for this - HelmRelease. It is used to determine the active retry or remediation - strategy. - enum: - - install - - upgrade - type: string - lastAttemptedReleaseActionDuration: - description: |- - LastAttemptedReleaseActionDuration is the duration of the last - release action performed for this HelmRelease. - type: string - lastAttemptedRevision: - description: |- - LastAttemptedRevision is the Source revision of the last reconciliation - attempt. For OCIRepository sources, the 12 first characters of the digest are - appended to the chart version e.g. "1.2.3+1234567890ab". - type: string - lastAttemptedRevisionDigest: - description: |- - LastAttemptedRevisionDigest is the digest of the last reconciliation attempt. - This is only set for OCIRepository sources. - type: string - lastAttemptedValuesChecksum: - description: |- - LastAttemptedValuesChecksum is the SHA1 checksum for the values of the last - reconciliation attempt. - - Deprecated: Use LastAttemptedConfigDigest instead. - type: string - lastHandledForceAt: - description: |- - LastHandledForceAt holds the value of the most recent - force request value, so a change of the annotation value - can be detected. - type: string - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - lastHandledResetAt: - description: |- - LastHandledResetAt holds the value of the most recent reset request - value, so a change of the annotation value can be detected. - type: string - lastReleaseRevision: - description: |- - LastReleaseRevision is the revision of the last successful Helm release. - - Deprecated: Use History instead. - type: integer - observedCommonMetadataDigest: - description: |- - ObservedCommonMetadataDigest is the digest for the common metadata of - the last successful reconciliation attempt. - type: string - observedGeneration: - description: ObservedGeneration is the last observed generation. - format: int64 - type: integer - observedPostRenderersDigest: - description: |- - ObservedPostRenderersDigest is the digest for the post-renderers of - the last successful reconciliation attempt. - type: string - storageNamespace: - description: |- - StorageNamespace is the namespace of the Helm release storage for the - current release. - maxLength: 63 - minLength: 1 - type: string - upgradeFailures: - description: |- - UpgradeFailures is the upgrade failure count against the latest desired - state. It is reset after a successful reconciliation. - format: int64 - type: integer - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/component: helm-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: helm-controller - namespace: flux-system ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/component: helm-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - control-plane: controller - name: helm-controller - namespace: flux-system -spec: - replicas: 1 - selector: - matchLabels: - app: helm-controller - template: - metadata: - annotations: - prometheus.io/port: "8080" - prometheus.io/scrape: "true" - labels: - app: helm-controller - app.kubernetes.io/component: helm-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - spec: - containers: - - args: - - --events-addr=http://notification-controller.$(RUNTIME_NAMESPACE).svc.cluster.local./ - - --watch-all-namespaces=true - - --log-level=info - - --log-encoding=json - - --enable-leader-election - env: - - name: RUNTIME_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - containerName: manager - resource: limits.memory - image: ghcr.io/fluxcd/helm-controller:v1.6.3 - imagePullPolicy: IfNotPresent - livenessProbe: - httpGet: - path: /healthz - port: healthz - name: manager - ports: - - containerPort: 8080 - name: http-prom - protocol: TCP - - containerPort: 9440 - name: healthz - protocol: TCP - readinessProbe: - httpGet: - path: /readyz - port: healthz - resources: - limits: - cpu: 1000m - memory: 1Gi - requests: - cpu: 100m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - readOnlyRootFilesystem: true - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /tmp - name: temp - nodeSelector: - kubernetes.io/os: linux - priorityClassName: system-cluster-critical - securityContext: - fsGroup: 1337 - serviceAccountName: helm-controller - terminationGracePeriodSeconds: 600 - volumes: - - emptyDir: {} - name: temp ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled - labels: - app.kubernetes.io/component: notification-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: alerts.notification.toolkit.fluxcd.io -spec: - group: notification.toolkit.fluxcd.io - names: - categories: - - all - - fluxcd - - fluxcd-notifications - kind: Alert - listKind: AlertList - plural: alerts - singular: alert - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1beta3 - schema: - openAPIV3Schema: - description: Alert is the Schema for the alerts API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: AlertSpec defines an alerting rule for events involving a - list of objects. - properties: - eventMetadata: - additionalProperties: - type: string - description: |- - EventMetadata is an optional field for adding metadata to events dispatched by the - controller. This can be used for enhancing the context of the event. If a field - would override one already present on the original event as generated by the emitter, - then the override doesn't happen, i.e. the original value is preserved, and an info - log is printed. - type: object - eventSeverity: - default: info - description: |- - EventSeverity specifies how to filter events based on severity. - If set to 'info' no events will be filtered. - enum: - - info - - error - type: string - eventSources: - description: |- - EventSources specifies how to filter events based - on the involved object kind, name and namespace. - items: - description: |- - CrossNamespaceObjectReference contains enough information to let you locate the - typed referenced object at cluster level - properties: - apiVersion: - description: API version of the referent - type: string - kind: - description: Kind of the referent - enum: - - Bucket - - GitRepository - - Kustomization - - HelmRelease - - HelmChart - - HelmRepository - - ImageRepository - - ImagePolicy - - ImageUpdateAutomation - - OCIRepository - - ArtifactGenerator - - ExternalArtifact - type: string - matchLabels: - additionalProperties: - type: string - description: |- - MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - MatchLabels requires the name to be set to `*`. - type: object - name: - description: |- - Name of the referent - If multiple resources are targeted `*` may be set. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: Namespace of the referent - maxLength: 253 - minLength: 1 - type: string - required: - - kind - - name - type: object - type: array - exclusionList: - description: |- - ExclusionList specifies a list of Golang regular expressions - to be used for excluding messages. - items: - type: string - type: array - inclusionList: - description: |- - InclusionList specifies a list of Golang regular expressions - to be used for including messages. - items: - type: string - type: array - providerRef: - description: ProviderRef specifies which Provider this Alert should - use. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - summary: - description: |- - Summary holds a short description of the impact and affected cluster. - Deprecated: Use EventMetadata instead. - maxLength: 255 - type: string - suspend: - description: |- - Suspend tells the controller to suspend subsequent - events handling for this Alert. - type: boolean - required: - - eventSources - - providerRef - type: object - type: object - served: true - storage: true - subresources: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled - labels: - app.kubernetes.io/component: notification-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: providers.notification.toolkit.fluxcd.io -spec: - group: notification.toolkit.fluxcd.io - names: - categories: - - all - - fluxcd - - fluxcd-notifications - kind: Provider - listKind: ProviderList - plural: providers - singular: provider - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1beta3 - schema: - openAPIV3Schema: - description: Provider is the Schema for the providers API - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: ProviderSpec defines the desired state of the Provider. - properties: - address: - description: |- - Address specifies the endpoint, in a generic sense, to where alerts are sent. - What kind of endpoint depends on the specific Provider type being used. - For the generic Provider, for example, this is an HTTP/S address. - For other Provider types this could be a project ID or a namespace. - maxLength: 2048 - type: string - certSecretRef: - description: |- - CertSecretRef specifies the Secret containing TLS certificates - for secure communication. - - Supported configurations: - - CA-only: Server authentication (provide ca.crt only) - - mTLS: Mutual authentication (provide ca.crt + tls.crt + tls.key) - - Client-only: Client authentication with system CA (provide tls.crt + tls.key only) - - Legacy keys "caFile", "certFile", "keyFile" are supported but deprecated. Use "ca.crt", "tls.crt", "tls.key" instead. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - channel: - description: Channel specifies the destination channel where events - should be posted. - maxLength: 2048 - type: string - commitStatusExpr: - description: |- - CommitStatusExpr is a CEL expression that evaluates to a string value - that can be used to generate a custom commit status message for use - with eligible Provider types (github, gitlab, gitea, bitbucketserver, - bitbucket, azuredevops). Supported variables are: event, provider, - and alert. - type: string - interval: - description: |- - Interval at which to reconcile the Provider with its Secret references. - Deprecated and not used in v1beta3. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - proxy: - description: |- - Proxy the HTTP/S address of the proxy server. - Deprecated: Use ProxySecretRef instead. Will be removed in v1. - maxLength: 2048 - pattern: ^(http|https)://.*$ - type: string - proxySecretRef: - description: |- - ProxySecretRef specifies the Secret containing the proxy configuration - for this Provider. The Secret should contain an 'address' key with the - HTTP/S address of the proxy server. Optional 'username' and 'password' - keys can be provided for proxy authentication. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - secretRef: - description: |- - SecretRef specifies the Secret containing the authentication - credentials for this Provider. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - serviceAccountName: - description: |- - ServiceAccountName is the name of the Kubernetes ServiceAccount used to - authenticate with cloud provider services through workload identity. - This enables multi-tenant authentication without storing static credentials. - - Supported provider types: azureeventhub, azuredevops, googlepubsub - - When specified, the controller will: - 1. Create an OIDC token for the specified ServiceAccount - 2. Exchange it for cloud provider credentials via STS - 3. Use the obtained credentials for API authentication - - When unspecified, controller-level authentication is used (single-tenant). - - An error is thrown if static credentials are also defined in SecretRef. - This field requires the ObjectLevelWorkloadIdentity feature gate to be enabled. - type: string - suspend: - description: |- - Suspend tells the controller to suspend subsequent - events handling for this Provider. - type: boolean - timeout: - description: Timeout for sending alerts to the Provider. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m))+$ - type: string - type: - description: Type specifies which Provider implementation to use. - enum: - - slack - - discord - - msteams - - rocket - - generic - - generic-hmac - - github - - gitlab - - gitea - - giteapullrequestcomment - - bitbucketserver - - bitbucket - - azuredevops - - googlechat - - googlepubsub - - webex - - sentry - - azureeventhub - - telegram - - lark - - matrix - - opsgenie - - alertmanager - - grafana - - githubdispatch - - githubpullrequestcomment - - gitlabmergerequestcomment - - pagerduty - - datadog - - nats - - zulip - - otel - type: string - username: - description: Username specifies the name under which events are posted. - maxLength: 2048 - type: string - required: - - type - type: object - x-kubernetes-validations: - - message: spec.commitStatusExpr is only supported for the 'github', 'gitlab', - 'gitea', 'bitbucketserver', 'bitbucket', 'azuredevops' provider types - rule: self.type == 'github' || self.type == 'gitlab' || self.type == - 'gitea' || self.type == 'bitbucketserver' || self.type == 'bitbucket' - || self.type == 'azuredevops' || !has(self.commitStatusExpr) - type: object - served: true - storage: true - subresources: {} ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.21.0 - kustomize.toolkit.fluxcd.io/substitute: disabled - labels: - app.kubernetes.io/component: notification-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: receivers.notification.toolkit.fluxcd.io -spec: - group: notification.toolkit.fluxcd.io - names: - categories: - - all - - fluxcd - - fluxcd-notifications - kind: Receiver - listKind: ReceiverList - plural: receivers - singular: receiver - scope: Namespaced - versions: - - additionalPrinterColumns: - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - - jsonPath: .status.conditions[?(@.type=="Ready")].status - name: Ready - type: string - - jsonPath: .status.conditions[?(@.type=="Ready")].message - name: Status - type: string - name: v1 - schema: - openAPIV3Schema: - description: Receiver is the Schema for the receivers API. - properties: - apiVersion: - description: |- - APIVersion defines the versioned schema of this representation of an object. - Servers should convert recognized schemas to the latest internal value, and - may reject unrecognized values. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources - type: string - kind: - description: |- - Kind is a string value representing the REST resource this object represents. - Servers may infer this from the endpoint the client submits requests to. - Cannot be updated. - In CamelCase. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - metadata: - type: object - spec: - description: ReceiverSpec defines the desired state of the Receiver. - properties: - events: - description: |- - Events specifies the list of event types to handle, - e.g. 'push' for GitHub or 'Push Hook' for GitLab. - items: - type: string - type: array - interval: - default: 10m - description: Interval at which to reconcile the Receiver with its - Secret references. - pattern: ^([0-9]+(\.[0-9]+)?(ms|s|m|h))+$ - type: string - oidcProviders: - description: |- - OIDCProviders specifies the OIDC providers used to authenticate incoming - requests when Type is 'generic-oidc'. The provider whose IssuerURL matches - the token's 'iss' claim is used to verify the token signature, expiration - and audience, and to evaluate the configured CEL validations against the - token claims. - items: - description: |- - OIDCProvider configures an OIDC issuer used to authenticate requests for a - 'generic-oidc' Receiver. - properties: - audience: - description: |- - Audience is the expected audience ('aud' claim) for tokens issued by - this provider. Defaults to 'notification-controller'. - type: string - issuerURL: - description: |- - IssuerURL is the OIDC issuer URL used for provider discovery. It must - match the 'iss' claim of tokens issued by this provider. - pattern: ^https?:// - type: string - validations: - description: |- - Validations is the list of CEL boolean expressions evaluated against the - token claims and the variables. The request is accepted only if all of - them evaluate to true; the message of each failing expression is returned - to the caller. - - At least one validation is required. A valid signature alone does not - authorize a request: public issuers issue tokens to any caller on the - platform, so the validations must constrain the caller's identity claims - (e.g. 'repository_owner' for GitHub Actions). - items: - description: |- - OIDCValidation is a CEL boolean expression evaluated against the OIDC token - claims and variables of a 'generic-oidc' Receiver. - properties: - expression: - description: Expression is the CEL boolean expression - to evaluate. - type: string - message: - description: Message is returned to the caller when the - expression evaluates to false. - type: string - required: - - expression - - message - type: object - minItems: 1 - type: array - variables: - description: |- - Variables is an optional list of named CEL expressions, evaluated in order - and exposed as 'vars.'. Each expression can read the token claims - via 'claims' and any variable defined before it. Use it to share - sub-expressions across validations. - items: - description: |- - OIDCVariable is a named CEL expression evaluated against the OIDC token - claims of a 'generic-oidc' Receiver. - properties: - expression: - description: Expression is the CEL expression that defines - the variable value. - type: string - name: - description: Name is the variable name; it must be a valid - CEL identifier. - type: string - required: - - expression - - name - type: object - type: array - required: - - issuerURL - - validations - type: object - type: array - x-kubernetes-list-map-keys: - - issuerURL - x-kubernetes-list-type: map - resourceFilter: - description: |- - ResourceFilter is a CEL expression expected to return a boolean that is - evaluated for each resource referenced in the Resources field when a - webhook is received. If the expression returns false then the controller - will not request a reconciliation for the resource. - The expression can read the resource metadata via 'res' and the webhook - request body via 'req'. For generic-oidc receivers, the verified OIDC - token claims are also available via 'claims'. - When the expression is specified the controller will parse it and mark - the object as terminally failed if the expression is invalid or does not - return a boolean. - type: string - resources: - description: A list of resources to be notified about changes. - items: - description: |- - ReceiverResource references a resource to be notified about changes, with an - optional per-resource CEL filter. - properties: - apiVersion: - description: API version of the referent - type: string - filter: - description: |- - Filter is a CEL expression expected to return a boolean that is evaluated - for each resource matched by this reference when a webhook is received, - in addition to the top-level resourceFilter. A reconciliation is requested - only when both expressions (when set) return true. - The expression can read the resource metadata via 'res' and the webhook - request body via 'req'. For generic-oidc receivers, the verified OIDC - token claims are also available via 'claims'. - When the expression is specified the controller will parse it and mark - the object as terminally failed if the expression is invalid or does not - return a boolean. - type: string - kind: - description: Kind of the referent - enum: - - Bucket - - GitRepository - - Kustomization - - HelmRelease - - HelmChart - - HelmRepository - - ImageRepository - - ImagePolicy - - ImageUpdateAutomation - - OCIRepository - - ArtifactGenerator - - ExternalArtifact - type: string - matchLabels: - additionalProperties: - type: string - description: |- - MatchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - MatchLabels requires the name to be set to `*`. - type: object - name: - description: |- - Name of the referent - If multiple resources are targeted `*` may be set. - maxLength: 253 - minLength: 1 - type: string - namespace: - description: Namespace of the referent - maxLength: 253 - minLength: 1 - type: string - required: - - kind - - name - type: object - type: array - secretRef: - description: |- - SecretRef specifies the Secret containing the token used - to validate the payload authenticity. The Secret must contain a 'token' - key. For GCR receivers, the Secret must also contain an 'email' key - with the IAM service account email configured on the Pub/Sub push - subscription, and an 'audience' key with the expected OIDC token audience. - - Required for all receiver types except 'generic-oidc', which authenticates - requests using the OIDC token instead and must not set this field. - properties: - name: - description: Name of the referent. - type: string - required: - - name - type: object - suspend: - description: |- - Suspend tells the controller to suspend subsequent - events handling for this receiver. - type: boolean - type: - description: |- - Type of webhook sender, used to determine - the validation procedure and payload deserialization. - enum: - - generic - - generic-hmac - - generic-oidc - - github - - gitlab - - bitbucket - - harbor - - dockerhub - - quay - - gcr - - nexus - - acr - - cdevents - type: string - required: - - resources - - type - type: object - x-kubernetes-validations: - - message: generic-oidc receivers must define at least one oidcProvider - rule: self.type != 'generic-oidc' || (has(self.oidcProviders) && size(self.oidcProviders) - > 0) - - message: oidcProviders can only be set when type is generic-oidc - rule: self.type == 'generic-oidc' || !has(self.oidcProviders) || size(self.oidcProviders) - == 0 - - message: secretRef cannot be set when type is generic-oidc - rule: self.type != 'generic-oidc' || !has(self.secretRef) - - message: secretRef is required when type is not generic-oidc - rule: self.type == 'generic-oidc' || has(self.secretRef) - status: - default: - observedGeneration: -1 - description: ReceiverStatus defines the observed state of the Receiver. - properties: - conditions: - description: Conditions holds the conditions for the Receiver. - items: - description: Condition contains details for one aspect of the current - state of this API Resource. - properties: - lastTransitionTime: - description: |- - lastTransitionTime is the last time the condition transitioned from one status to another. - This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. - format: date-time - type: string - message: - description: |- - message is a human readable message indicating details about the transition. - This may be an empty string. - maxLength: 32768 - type: string - observedGeneration: - description: |- - observedGeneration represents the .metadata.generation that the condition was set based upon. - For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date - with respect to the current state of the instance. - format: int64 - minimum: 0 - type: integer - reason: - description: |- - reason contains a programmatic identifier indicating the reason for the condition's last transition. - Producers of specific condition types may define expected values and meanings for this field, - and whether the values are considered a guaranteed API. - The value should be a CamelCase string. - This field may not be empty. - maxLength: 1024 - minLength: 1 - pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ - type: string - status: - description: status of the condition, one of True, False, Unknown. - enum: - - "True" - - "False" - - Unknown - type: string - type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - maxLength: 316 - pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ - type: string - required: - - lastTransitionTime - - message - - reason - - status - - type - type: object - type: array - lastHandledReconcileAt: - description: |- - LastHandledReconcileAt holds the value of the most recent - reconcile request value, so a change of the annotation value - can be detected. - type: string - observedGeneration: - description: ObservedGeneration is the last observed generation of - the Receiver object. - format: int64 - type: integer - webhookPath: - description: |- - WebhookPath is the generated incoming webhook address in the format - of '/hook/sha256sum(token+name+namespace)'. - type: string - type: object - type: object - served: true - storage: true - subresources: - status: {} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/component: notification-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - name: notification-controller - namespace: flux-system ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/component: notification-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - control-plane: controller - name: notification-controller - namespace: flux-system -spec: - ports: - - name: http - port: 80 - protocol: TCP - targetPort: http - selector: - app: notification-controller - type: ClusterIP ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/component: notification-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - control-plane: controller - name: webhook-receiver - namespace: flux-system -spec: - ports: - - name: http - port: 80 - protocol: TCP - targetPort: http-webhook - selector: - app: notification-controller - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/component: notification-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - control-plane: controller - name: notification-controller - namespace: flux-system -spec: - replicas: 1 - selector: - matchLabels: - app: notification-controller - template: - metadata: - annotations: - prometheus.io/port: "8080" - prometheus.io/scrape: "true" - labels: - app: notification-controller - app.kubernetes.io/component: notification-controller - app.kubernetes.io/instance: flux-system - app.kubernetes.io/part-of: flux - app.kubernetes.io/version: v2.9.4 - spec: - containers: - - args: - - --watch-all-namespaces=true - - --log-level=info - - --log-encoding=json - - --enable-leader-election - env: - - name: RUNTIME_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace - - name: GOMEMLIMIT - valueFrom: - resourceFieldRef: - containerName: manager - resource: limits.memory - image: ghcr.io/fluxcd/notification-controller:v1.9.3 - imagePullPolicy: IfNotPresent - livenessProbe: - httpGet: - path: /healthz - port: healthz - name: manager - ports: - - containerPort: 9090 - name: http - protocol: TCP - - containerPort: 9292 - name: http-webhook - protocol: TCP - - containerPort: 8080 - name: http-prom - protocol: TCP - - containerPort: 9440 - name: healthz - protocol: TCP - readinessProbe: - httpGet: - path: /readyz - port: healthz - resources: - limits: - cpu: 1000m - memory: 1Gi - requests: - cpu: 100m - memory: 64Mi - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - readOnlyRootFilesystem: true - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - volumeMounts: - - mountPath: /tmp - name: temp - nodeSelector: - kubernetes.io/os: linux - securityContext: - fsGroup: 1337 - serviceAccountName: notification-controller - terminationGracePeriodSeconds: 10 - volumes: - - emptyDir: {} - name: temp diff --git a/k8s/flux/system/gotk-sync.yaml b/k8s/flux/system/gotk-sync.yaml deleted file mode 100644 index c6ce39ab..00000000 --- a/k8s/flux/system/gotk-sync.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: source.toolkit.fluxcd.io/v1 -kind: GitRepository -metadata: - name: flux-system - namespace: flux-system -spec: - interval: 15m0s - ref: - branch: master - url: https://github.com/alyraffauf/infra ---- -apiVersion: kustomize.toolkit.fluxcd.io/v1 -kind: Kustomization -metadata: - name: flux-system - namespace: flux-system -spec: - interval: 15m0s - path: ./k8s/flux/system - prune: true - sourceRef: - kind: GitRepository - name: flux-system diff --git a/k8s/flux/system/kustomization.yaml b/k8s/flux/system/kustomization.yaml deleted file mode 100644 index 4a2b4559..00000000 --- a/k8s/flux/system/kustomization.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -resources: - - gotk-components.yaml - - gotk-sync.yaml - - layers.yaml diff --git a/k8s/flux/system/layers.yaml b/k8s/flux/system/layers.yaml deleted file mode 100644 index 93db204a..00000000 --- a/k8s/flux/system/layers.yaml +++ /dev/null @@ -1,170 +0,0 @@ -apiVersion: kustomize.toolkit.fluxcd.io/v1 -kind: Kustomization -metadata: - name: sources - namespace: flux-system -spec: - interval: 15m - path: ./k8s/flux/sources - prune: true - sourceRef: - kind: GitRepository - name: flux-system ---- -apiVersion: kustomize.toolkit.fluxcd.io/v1 -kind: Kustomization -metadata: - name: secrets - namespace: flux-system -spec: - dependsOn: - - name: sources - decryption: - provider: sops - secretRef: - name: sops-age - interval: 15m - path: ./k8s/flux/secrets - prune: true - sourceRef: - kind: GitRepository - name: flux-system ---- -apiVersion: kustomize.toolkit.fluxcd.io/v1 -kind: Kustomization -metadata: - name: infra-crds - namespace: flux-system -spec: - dependsOn: - - name: secrets - interval: 15m - path: ./k8s/flux/infra-crds - prune: true - wait: true - healthChecks: - - apiVersion: helm.toolkit.fluxcd.io/v2 - kind: HelmRelease - name: cert-manager-issuers - namespace: flux-system - - apiVersion: helm.toolkit.fluxcd.io/v2 - kind: HelmRelease - name: cert-manager - namespace: flux-system - - apiVersion: helm.toolkit.fluxcd.io/v2 - kind: HelmRelease - name: cnpg - namespace: flux-system - sourceRef: - kind: GitRepository - name: flux-system ---- -apiVersion: kustomize.toolkit.fluxcd.io/v1 -kind: Kustomization -metadata: - name: infra-core - namespace: flux-system -spec: - dependsOn: - - name: infra-crds - interval: 15m - path: ./k8s/flux/infra-core - prune: true - wait: true - healthChecks: - - apiVersion: helm.toolkit.fluxcd.io/v2 - kind: HelmRelease - name: intel-device-plugins-operator - namespace: flux-system - - apiVersion: helm.toolkit.fluxcd.io/v2 - kind: HelmRelease - name: intel-gpu-plugin - namespace: flux-system - - apiVersion: helm.toolkit.fluxcd.io/v2 - kind: HelmRelease - name: longhorn - namespace: flux-system - - apiVersion: helm.toolkit.fluxcd.io/v2 - kind: HelmRelease - name: longhorn-creds - namespace: flux-system - - apiVersion: helm.toolkit.fluxcd.io/v2 - kind: HelmRelease - name: node-feature-discovery - namespace: flux-system - - apiVersion: helm.toolkit.fluxcd.io/v2 - kind: HelmRelease - name: reflector - namespace: flux-system - - apiVersion: helm.toolkit.fluxcd.io/v2 - kind: HelmRelease - name: tailscale-operator - namespace: flux-system - - apiVersion: helm.toolkit.fluxcd.io/v2 - kind: HelmRelease - name: traefik - namespace: flux-system - sourceRef: - kind: GitRepository - name: flux-system ---- -apiVersion: kustomize.toolkit.fluxcd.io/v1 -kind: Kustomization -metadata: - name: platform - namespace: flux-system -spec: - dependsOn: - - name: infra-core - interval: 15m - path: ./k8s/flux/platform - prune: true - wait: true - healthChecks: - - apiVersion: helm.toolkit.fluxcd.io/v2 - kind: HelmRelease - name: kubernetes-alloy - namespace: flux-system - - apiVersion: helm.toolkit.fluxcd.io/v2 - kind: HelmRelease - name: kubernetes-prometheus - namespace: flux-system - - apiVersion: helm.toolkit.fluxcd.io/v2 - kind: HelmRelease - name: pg-shared - namespace: flux-system - sourceRef: - kind: GitRepository - name: flux-system ---- -apiVersion: kustomize.toolkit.fluxcd.io/v1 -kind: Kustomization -metadata: - name: apps - namespace: flux-system -spec: - dependsOn: - - name: platform - interval: 15m - path: ./k8s/flux/apps - prune: true - timeout: 30m - wait: true - sourceRef: - kind: GitRepository - name: flux-system ---- -apiVersion: kustomize.toolkit.fluxcd.io/v1 -kind: Kustomization -metadata: - name: external-routes - namespace: flux-system -spec: - dependsOn: - - name: infra-core - interval: 15m - path: ./k8s/flux/external-routes - prune: true - sourceRef: - kind: GitRepository - name: flux-system diff --git a/keys/aly_fortree.pub b/keys/aly_fortree.pub index 72b4f3b6..424878fc 100644 --- a/keys/aly_fortree.pub +++ b/keys/aly_fortree.pub @@ -1 +1 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDm4T5eCKOtMERpFYOccN/M0Hla2q9cGyQL1hWLsXZKU aly@fortree +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAx92dtg9xdm8D444KxgkRlfoGDUwkFIIf2Lv6ZuoG/b aly@Alys-MacBook-Air.local diff --git a/keys/aly_jubilife.pub b/keys/aly_goldenrod.pub similarity index 67% rename from keys/aly_jubilife.pub rename to keys/aly_goldenrod.pub index 3e41b4e9..415f7d78 100644 --- a/keys/aly_jubilife.pub +++ b/keys/aly_goldenrod.pub @@ -1 +1 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3YdXgLFwvyVAzj3CpqCf079SEhX3EzNEu2rFR3Bbyb aly@jubilife +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3YdXgLFwvyVAzj3CpqCf079SEhX3EzNEu2rFR3Bbyb aly@goldenrod diff --git a/keys/aly_mauville.pub b/keys/aly_mauville.pub new file mode 100644 index 00000000..dfce0078 --- /dev/null +++ b/keys/aly_mauville.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIO9VecytyMC/JIlGZ2iRhnFP77TCKzJARQZhEq5pBLf aly@mauville diff --git a/keys/aly_rustboro.pub b/keys/aly_rustboro.pub index f34efe1b..c4c7a81a 100644 --- a/keys/aly_rustboro.pub +++ b/keys/aly_rustboro.pub @@ -1 +1 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC6aJrTE2d3I3acDeg4aCyYSs+/KCPIrbw+JAuDnuJeq aly@rustboro +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPxGj4y75Q7fZt59MkSwhqqg6ARRRnNC3HSJPTHtR93Z aly@rustboro diff --git a/keys/aly_snowpoint.pub b/keys/aly_snowpoint.pub deleted file mode 100644 index d37bc33a..00000000 --- a/keys/aly_snowpoint.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMnHdI4VNHHfOck1QvEmWQQ6nG9/BDg7NUJdCg/9L72m aly@snowpoint diff --git a/keys/flux_k8s.pub b/keys/flux_k8s.pub deleted file mode 100644 index fe372123..00000000 --- a/keys/flux_k8s.pub +++ /dev/null @@ -1 +0,0 @@ -age1yq47x0cyf95jg372v84ttptgnppsrfmxshsua6p58ecmgzxc5c0s5stfth diff --git a/keys/root_jubilife.pub b/keys/root_jubilife.pub deleted file mode 100644 index 23a2eaf8..00000000 --- a/keys/root_jubilife.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHiyAgNRLlcCrMNaJVuU6U/c80ctrR/pQNziDePk82Sd root@jubilife diff --git a/keys/root_pastoria.pub b/keys/root_pastoria.pub deleted file mode 100644 index 44eab667..00000000 --- a/keys/root_pastoria.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAurNYjTIdDAhM3x2l7/LLTzQ40uKz8nfydcbr73c8eh root@pastoria diff --git a/keys/root_petalburg.pub b/keys/root_petalburg.pub deleted file mode 100644 index 8e28dd29..00000000 --- a/keys/root_petalburg.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIOz80JftfawxbBmKMRdjgqGFPdUdQUvkMLlAxNvmjo6 root@petalburg diff --git a/keys/root_snowpoint.pub b/keys/root_snowpoint.pub deleted file mode 100644 index 17db4c2f..00000000 --- a/keys/root_snowpoint.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPCZPnqmEXSxjFqLByOZr/rOGLXhW8o3bMj6IGANUP88 root@snowpoint diff --git a/nix/devShells.nix b/nix/devShells.nix new file mode 100644 index 00000000..f6cdf499 --- /dev/null +++ b/nix/devShells.nix @@ -0,0 +1,21 @@ +_: { + perSystem = {pkgs, ...}: { + devShells.default = pkgs.mkShell { + packages = [ + pkgs.age + pkgs.git + pkgs.jq + pkgs.just + pkgs.opentofu + pkgs.sops + pkgs.ssh-to-age + pkgs.yq-go + ]; + + shellHook = '' + export FLAKE="." NH_FLAKE="." + echo "Welcome to the infra devShell." + ''; + }; + }; +} diff --git a/nix/modules/deployments.nix b/nix/modules/deployments.nix deleted file mode 100644 index 7a5fb1e9..00000000 --- a/nix/modules/deployments.nix +++ /dev/null @@ -1,21 +0,0 @@ -{self, ...}: { - blzrd.nodes = { - jubilife = { - output = self.nixosConfigurations.jubilife.config.system.build.toplevel; - type = "nixos"; - user = "root"; - }; - - pastoria = { - output = self.nixosConfigurations.pastoria.config.system.build.toplevel; - type = "nixos"; - user = "root"; - }; - - snowpoint = { - output = self.nixosConfigurations.snowpoint.config.system.build.toplevel; - type = "nixos"; - user = "root"; - }; - }; -} diff --git a/nix/modules/devShells.nix b/nix/modules/devShells.nix deleted file mode 100644 index 42116e7e..00000000 --- a/nix/modules/devShells.nix +++ /dev/null @@ -1,59 +0,0 @@ -{ - perSystem = { - lib, - pkgs, - inputs', - self', - ... - }: let - # `kubernetes.core` ansible collection needs the kubernetes python lib. - ansibleWithK8s = pkgs.python3.withPackages (ps: - with ps; [ - ansible - ansible-core - kubernetes - ]); - - helmWithDiff = pkgs.wrapHelm pkgs.kubernetes-helm { - plugins = [pkgs.kubernetes-helmPlugins.helm-diff]; - }; - in { - devShells.default = pkgs.mkShell { - packages = - (with pkgs; [ - age - ansibleWithK8s - bun - fluxcd - git - just - kustomize - kubectl - kubeconform - helmWithDiff - nh - skopeo - sops - ssh-to-age - opentofu - uv # runs flux-local (not packaged in nixpkgs) via `just flux-test` - yq-go # extracts cute-haus-global values for `just k8s apply/diff` - ]) - # ++ lib.attrValues config.treefmt.build.programs - ++ [ - inputs'.blzrd.packages.blzrd - self'.packages.gen-files - ] - ++ lib.optionals pkgs.stdenv.isLinux [ - inputs'.disko.packages.disko-install - ]; - - shellHook = '' - echo "Generating files..." - ${lib.getExe self'.packages.gen-files} - export FLAKE="." NH_FLAKE="." - echo "👋 Welcome to the cute.haus devShell!" - ''; - }; - }; -} diff --git a/nix/modules/disko/btrfs-subvolumes.nix b/nix/modules/disko/btrfs-subvolumes.nix deleted file mode 100644 index c183669f..00000000 --- a/nix/modules/disko/btrfs-subvolumes.nix +++ /dev/null @@ -1,72 +0,0 @@ -_: { - flake.nixosModules.btrfsSubvolumes = {config, ...}: { - assertions = [ - { - assertion = config.myDisko.installDrive != ""; - message = "config.myDisko.installDrive cannot be empty."; - } - ]; - - disko.devices = { - disk = { - main = { - type = "disk"; - device = config.myDisko.installDrive; - - content = { - type = "gpt"; - - partitions = { - ESP = { - content = { - format = "vfat"; - mountOptions = ["umask=0077"]; - mountpoint = "/boot"; - type = "filesystem"; - }; - - end = "1024M"; - name = "ESP"; - priority = 1; - start = "1M"; - type = "EF00"; - }; - - root = { - size = "100%"; - content = { - type = "btrfs"; - extraArgs = ["-f"]; - - subvolumes = { - "/rootfs" = { - mountOptions = ["compress=zstd" "noatime"]; - mountpoint = "/"; - }; - - "/home" = { - mountOptions = ["compress=zstd" "noatime"]; - mountpoint = "/home"; - }; - - "/home/.snapshots" = { - mountOptions = ["compress=zstd" "noatime"]; - mountpoint = "/home/.snapshots"; - }; - - "/nix" = { - mountOptions = ["compress=zstd" "noatime"]; - mountpoint = "/nix"; - }; - }; - - mountpoint = "/partition-root"; - }; - }; - }; - }; - }; - }; - }; - }; -} diff --git a/nix/modules/disko/configurations.nix b/nix/modules/disko/configurations.nix deleted file mode 100644 index 2d2169e7..00000000 --- a/nix/modules/disko/configurations.nix +++ /dev/null @@ -1,26 +0,0 @@ -{self, ...}: { - flake.diskoConfigurations = { - btrfs-subvolumes = { - imports = [ - self.nixosModules.disko - self.nixosModules.btrfsSubvolumes - ]; - myDisko.installDrive = "/dev/nvme0n1"; - }; - - luks-btrfs-subvolumes = { - imports = [ - self.nixosModules.disko - self.nixosModules.luksBtrfsSubvolumes - ]; - myDisko.installDrive = "/dev/nvme0n1"; - }; - - lvm-ext4 = { - imports = [ - self.nixosModules.disko - self.nixosModules.lvmExt4 - ]; - }; - }; -} diff --git a/nix/modules/disko/default.nix b/nix/modules/disko/default.nix deleted file mode 100644 index 71c027ea..00000000 --- a/nix/modules/disko/default.nix +++ /dev/null @@ -1,9 +0,0 @@ -_: { - flake.nixosModules.disko = {lib, ...}: { - options.myDisko.installDrive = lib.mkOption { - description = "Disk to install NixOS to."; - default = "/dev/sda"; - type = lib.types.str; - }; - }; -} diff --git a/nix/modules/disko/luks-btrfs-subvolumes.nix b/nix/modules/disko/luks-btrfs-subvolumes.nix deleted file mode 100644 index 96388593..00000000 --- a/nix/modules/disko/luks-btrfs-subvolumes.nix +++ /dev/null @@ -1,88 +0,0 @@ -_: { - flake.nixosModules.luksBtrfsSubvolumes = {config, ...}: { - assertions = [ - { - assertion = config.myDisko.installDrive != ""; - message = "config.myDisko.installDrive cannot be empty."; - } - ]; - - disko.devices = { - disk = { - vdb = { - type = "disk"; - device = config.myDisko.installDrive; - - content = { - type = "gpt"; - - partitions = { - ESP = { - content = { - format = "vfat"; - - mountOptions = [ - "defaults" - "umask=0077" - ]; - - mountpoint = "/boot"; - type = "filesystem"; - }; - - size = "1024M"; - type = "EF00"; - }; - - luks = { - size = "100%"; - content = { - type = "luks"; - name = "crypted"; - - content = { - type = "btrfs"; - extraArgs = ["-f"]; - - subvolumes = { - "/home" = { - mountpoint = "/home"; - mountOptions = ["compress=zstd" "noatime"]; - }; - - "/home/.snapshots" = { - mountOptions = ["compress=zstd" "noatime"]; - mountpoint = "/home/.snapshots"; - }; - - "/nix" = { - mountpoint = "/nix"; - mountOptions = ["compress=zstd" "noatime"]; - }; - - "persist" = { - mountpoint = "/persist"; - mountOptions = ["compress=zstd" "noatime"]; - }; - - "/root" = { - mountpoint = "/"; - mountOptions = ["compress=zstd" "noatime"]; - }; - }; - }; - - settings = { - allowDiscards = true; - bypassWorkqueues = true; - crypttabExtraOpts = ["fido2-device=auto" "token-timeout=20"]; - }; - }; - }; - }; - }; - }; - }; - }; - }; -} diff --git a/nix/modules/disko/lvm-ext4.nix b/nix/modules/disko/lvm-ext4.nix deleted file mode 100644 index 6beeb002..00000000 --- a/nix/modules/disko/lvm-ext4.nix +++ /dev/null @@ -1,64 +0,0 @@ -_: { - flake.nixosModules.lvmExt4 = {config, ...}: { - assertions = [ - { - assertion = config.myDisko.installDrive != ""; - message = "config.myDisko.installDrive cannot be empty."; - } - ]; - - disko.devices = { - disk.disk1 = { - device = config.myDisko.installDrive; - type = "disk"; - content = { - type = "gpt"; - partitions = { - boot = { - name = "boot"; - size = "1M"; - type = "EF02"; - }; - esp = { - name = "ESP"; - size = "500M"; - type = "EF00"; - content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; - }; - }; - root = { - name = "root"; - size = "100%"; - content = { - type = "lvm_pv"; - vg = "pool"; - }; - }; - }; - }; - }; - - lvm_vg = { - pool = { - type = "lvm_vg"; - lvs = { - root = { - size = "100%FREE"; - content = { - type = "filesystem"; - format = "ext4"; - mountpoint = "/"; - mountOptions = [ - "defaults" - ]; - }; - }; - }; - }; - }; - }; - }; -} diff --git a/nix/modules/files/zed.nix b/nix/modules/files/zed.nix deleted file mode 100644 index bec4328a..00000000 --- a/nix/modules/files/zed.nix +++ /dev/null @@ -1,87 +0,0 @@ -{ - perSystem = { - lib, - pkgs, - ... - }: { - files.files = [ - { - checkFile = false; - path_ = ".zed/settings.json"; - - drv = (pkgs.formats.json {}).generate "zed-setting.json" { - auto_install_extensions = { - basher = true; - helm = true; - nix = true; - }; - - file_types = { - Helm = [ - "**/templates/**/*.tpl" - "**/templates/**/*.yaml" - "**/templates/**/*.yml" - "**/values*.yaml" - ]; - }; - - languages = { - JSON = { - format_on_save = "on"; - - formatter = { - external = { - command = lib.getExe pkgs.prettier; - arguments = ["--stdin-filepath" "{buffer_path}"]; - }; - }; - }; - - Markdown = { - format_on_save = "on"; - - formatter.external = { - command = lib.getExe pkgs.prettier; - arguments = ["--stdin-filepath" "{buffer_path}"]; - }; - }; - - Nix = { - format_on_save = "on"; - formatter.external = { - command = lib.getExe pkgs.alejandra; - arguments = ["--quiet" "--"]; - }; - - language_servers = ["nixd"]; - }; - - "Shell Script" = { - format_on_save = "on"; - - formatter = { - external = { - command = lib.getExe pkgs.shfmt; - arguments = ["--filename" "{buffer_path}" "-i" "2"]; - }; - }; - - tab_size = 2; - hard_tabs = false; - }; - - YAML = { - format_on_save = "on"; - formatter.external = { - command = lib.getExe pkgs.prettier; - arguments = ["--stdin-filepath" "{buffer_path}"]; - }; - }; - }; - - lsp.nixd.binary.path = lib.getExe pkgs.nixd; - }; - } - ]; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/auto-upgrade.nix b/nix/modules/hosts/nixos/jubilife/auto-upgrade.nix deleted file mode 100644 index cdeaa774..00000000 --- a/nix/modules/hosts/nixos/jubilife/auto-upgrade.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - system.autoUpgrade.dates = "04:15"; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/backups.nix b/nix/modules/hosts/nixos/jubilife/backups.nix deleted file mode 100644 index e0840d0c..00000000 --- a/nix/modules/hosts/nixos/jubilife/backups.nix +++ /dev/null @@ -1,33 +0,0 @@ -_: { - flake.nixosModules.jubilife = {config, ...}: { - myNixOs.profile.backups.jobs = let - dataDirectory = "/mnt/Data"; - in { - immich.paths = [ - "${dataDirectory}/immich/library" - "${dataDirectory}/immich/profile" - "${dataDirectory}/immich/upload" - "${dataDirectory}/immich/backups" - "${dataDirectory}/immich/postgres" - ]; - garage.paths = ["${dataDirectory}/garage"]; - nextcloud.paths = [ - "${dataDirectory}/nextcloud/html" - "${dataDirectory}/postgres" - ]; - paperless.paths = ["${dataDirectory}/paperless"]; - plex = { - exclude = ["${dataDirectory}/plex/Library/Application Support/Plex Media Server/Plug-in Support/Databases"]; - paths = ["${dataDirectory}/plex"]; - }; - syncthing-roms = { - paths = [config.myNixOs.service.syncthing.romsPath]; - repository = "rclone:b2:aly-backups/syncthing/roms"; - }; - syncthing-sync = { - paths = ["/home/aly/sync"]; - repository = "rclone:b2:aly-backups/syncthing/sync"; - }; - }; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/containers.nix b/nix/modules/hosts/nixos/jubilife/containers.nix deleted file mode 100644 index f11730b0..00000000 --- a/nix/modules/hosts/nixos/jubilife/containers.nix +++ /dev/null @@ -1,18 +0,0 @@ -_: { - flake.nixosModules.jubilife = _: { - systemd.tmpfiles.rules = [ - "z /mnt/Data 0755 root root - -" - "d /mnt/Data/arm/home 0755 1000 1000 - -" - "d /mnt/Data/arm/config 0755 1000 1000 - -" - "d /mnt/Data/arm 0755 1000 1000 - -" - "d /mnt/Data/jellyfin 0700 1000 1000 - -" - "d /mnt/Data/garage 0750 garage garage - -" - "d /mnt/Data/garage/meta 0700 garage garage - -" - "d /mnt/Data/garage/data 0700 garage garage - -" - "d /mnt/Data/paperless 0750 1000 1000 - -" - "d /mnt/Data/paperless/data 0750 1000 1000 - -" - "d /mnt/Data/paperless/consume 0750 1000 1000 - -" - "d /mnt/Data/paperless/media 0750 1000 1000 - -" - ]; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/containers/collabora.nix b/nix/modules/hosts/nixos/jubilife/containers/collabora.nix deleted file mode 100644 index b97d44ba..00000000 --- a/nix/modules/hosts/nixos/jubilife/containers/collabora.nix +++ /dev/null @@ -1,20 +0,0 @@ -_: { - flake.nixosModules.jubilife = _: { - virtualisation.oci-containers.containers.collabora = { - image = "docker.io/collabora/code:latest@sha256:6b70f91f0b6e9c76f75f162f58ef0a12cf9415d78e14713d33c0318ddc4a2cc0"; - environment = { - DONT_GEN_SSL_CERT = "true"; - aliasgroup1 = "https://nextcloud\\.cute\\.haus"; - extra_params = "--o:ssl.enable=false --o:ssl.termination=true"; - server_name = "collabora.cute.haus"; - }; - extraOptions = [ - "--cap-add=MKNOD" - "--memory=4g" - ]; - ports = ["10.254.0.1:9980:9980"]; - }; - - systemd.services.docker-collabora.unitConfig.RequiresMountsFor = ["/mnt/Data"]; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/containers/immich.nix b/nix/modules/hosts/nixos/jubilife/containers/immich.nix deleted file mode 100644 index 66d0da77..00000000 --- a/nix/modules/hosts/nixos/jubilife/containers/immich.nix +++ /dev/null @@ -1,119 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - config, - inputs, - pkgs, - ... - }: { - systemd.tmpfiles.rules = [ - "d /mnt/Data/immich/ml-cache 0755 root root - -" - "d /mnt/Data/immich/postgres 0700 999 999 - -" - ]; - - sops.secrets = { - immichDbPassword = { - sopsFile = "${inputs.self}/k8s/flux/secrets/immich-env.sops.yaml"; - key = "data/DB_PASSWORD"; - }; - immichConfigBase64 = { - sopsFile = "${inputs.self}/k8s/flux/secrets/immich-config.sops.yaml"; - key = "data/config.json"; - restartUnits = ["docker-immich.service"]; - }; - }; - - sops.templates = { - immich-postgres-environment.content = "POSTGRES_PASSWORD=${config.sops.placeholder.immichDbPassword}"; - immich-server-environment.content = "DB_PASSWORD=${config.sops.placeholder.immichDbPassword}"; - }; - - myNixOs.docker.networks.immich.containers = [ - "immich-postgres" - "immich-machine-learning" - "immich-valkey" - "immich" - ]; - - virtualisation.oci-containers.containers = { - immich-postgres = { - image = "ghcr.io/immich-app/postgres:17-vectorchord0.4.3-pgvector0.8.0@sha256:0baf4cde9b54d8d7dc6a6ad8d8c43c3c6b884f82e1c2a023d571414820e39336"; - networks = ["immich"]; - environment = { - PGDATA = "/var/lib/postgresql/data/pgdata"; - POSTGRES_DB = "immich"; - POSTGRES_INITDB_ARGS = "--data-checksums"; - POSTGRES_USER = "immich"; - }; - environmentFiles = [config.sops.templates.immich-postgres-environment.path]; - extraOptions = [ - "--memory=3g" - "--shm-size=128m" - ]; - volumes = ["/mnt/Data/immich/postgres:/var/lib/postgresql/data"]; - }; - - immich-machine-learning = { - image = "ghcr.io/immich-app/immich-machine-learning:v3.1.0-openvino@sha256:627dfaf9339037be132209784883f7be13c1deb6be799454797bf6f231331f5b"; - devices = ["/dev/dri:/dev/dri"]; - networks = ["immich"]; - environment.MACHINE_LEARNING_CACHE_FOLDER = "/cache"; - extraOptions = ["--memory=4g"]; - volumes = ["/mnt/Data/immich/ml-cache:/cache"]; - }; - - immich-valkey = { - image = "valkey/valkey:9-alpine@sha256:ee91f7a174ac4d6a6b0685b3a60e321f0a9dbbb691f9b0e285be2ba1d1be8328"; - networks = ["immich"]; - cmd = ["valkey-server" "--maxmemory" "1gb" "--maxmemory-policy" "volatile-lru"]; - }; - - immich = { - image = "ghcr.io/immich-app/immich-server:v3.1.0@sha256:b434cb9287eea1471c9974845914d4dd328c9c2d652e446ed4930f99944f0ceb"; - dependsOn = [ - "immich-postgres" - "immich-machine-learning" - "immich-valkey" - ]; - networks = ["immich"]; - environment = { - DB_DATABASE_NAME = "immich"; - DB_HOSTNAME = "immich-postgres"; - DB_PORT = "5432"; - DB_USERNAME = "immich"; - IMMICH_CONFIG_FILE = "/etc/immich/config.json"; - IMMICH_MACHINE_LEARNING_URL = "http://immich-machine-learning:3003"; - REDIS_DBINDEX = "4"; - REDIS_HOSTNAME = "immich-valkey"; - TZ = "America/New_York"; - }; - environmentFiles = [config.sops.templates.immich-server-environment.path]; - extraOptions = [ - "--memory=4g" - "--ulimit=nofile=8192:8192" - ]; - ports = ["10.254.0.1:2283:2283"]; - volumes = [ - "/mnt/Data/immich:/data" - "/run/immich/config.json:/etc/immich/config.json:ro" - ]; - }; - }; - - systemd.services = { - docker-immich = { - preStart = '' - ${pkgs.coreutils}/bin/base64 --decode \ - < "${config.sops.secrets.immichConfigBase64.path}" \ - > "$RUNTIME_DIRECTORY/config.json" - ''; - serviceConfig = { - RuntimeDirectory = "immich"; - RuntimeDirectoryMode = "0700"; - }; - unitConfig.RequiresMountsFor = ["/mnt/Data"]; - }; - docker-immich-machine-learning.unitConfig.RequiresMountsFor = ["/mnt/Data"]; - docker-immich-postgres.unitConfig.RequiresMountsFor = ["/mnt/Data"]; - }; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/containers/media.nix b/nix/modules/hosts/nixos/jubilife/containers/media.nix deleted file mode 100644 index cd11cedd..00000000 --- a/nix/modules/hosts/nixos/jubilife/containers/media.nix +++ /dev/null @@ -1,54 +0,0 @@ -_: { - flake.nixosModules.jubilife = {inputs, ...}: { - myNixOs.profile.backups.jobs.dizquetv.paths = ["/mnt/Data/dizquetv"]; - - systemd.tmpfiles.rules = [ - "d /mnt/Data/dizquetv 0755 root root - -" - "d /mnt/Data/plex 0755 1000 1000 - -" - ]; - - virtualisation.oci-containers.containers = { - dizquetv = { - image = "vexorian/dizquetv:latest@sha256:98a7bc11dc5d16732c06c779ac7fd843dc4254853203f2d9dd9293b099743ca1"; - ports = ["0.0.0.0:8000:8000"]; - volumes = [ - "/mnt/Data/dizquetv:/home/node/app/.dizquetv" - "/etc/localtime:/etc/localtime:ro" - ]; - }; - - plex = { - image = "docker.io/plexinc/pms-docker:1.43.3.10861-07dfddaeb@sha256:5bc1d13f48da6366f46aaf2a3ce1a6292897eadc1f8efcbbd7321d30e94f2ed4"; - devices = ["/dev/dri:/dev/dri"]; - environment = { - ADVERTISE_IP = "https://plex.cute.haus:443"; - PLEX_GID = "1000"; - PLEX_UID = "1000"; - TZ = "America/New_York"; - }; - extraOptions = [ - "--group-add=44" - "--memory=4g" - "--network=host" - ]; - volumes = [ - "/mnt/Data/plex:/config" - "/mnt/Media:/mnt/Media:ro" - "/etc/localtime:/etc/localtime:ro" - "/mnt/Backblaze:/mnt/Backblaze:ro,rslave" - "${inputs.audnexus}:/config/Library/Application Support/Plex Media Server/Plug-ins/Audnexus.bundle:ro" - "${inputs.hama}:/config/Library/Application Support/Plex Media Server/Plug-ins/Hama.bundle:ro" - "${inputs.absolute}/Scanners:/config/Library/Application Support/Plex Media Server/Scanners:ro" - ]; - }; - }; - - systemd.services = { - docker-dizquetv.unitConfig.RequiresMountsFor = ["/mnt/Data"]; - docker-plex.unitConfig.RequiresMountsFor = [ - "/mnt/Data" - "/mnt/Media" - ]; - }; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/containers/nextcloud.nix b/nix/modules/hosts/nixos/jubilife/containers/nextcloud.nix deleted file mode 100644 index 9a66673b..00000000 --- a/nix/modules/hosts/nixos/jubilife/containers/nextcloud.nix +++ /dev/null @@ -1,195 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - config, - inputs, - pkgs, - ... - }: { - systemd.tmpfiles.rules = [ - "d /mnt/Data/nextcloud/html 0750 33 33 - -" - "d /mnt/Data/nextcloud/valkey 0750 999 999 - -" - "d /mnt/Data/postgres 0700 999 999 - -" - ]; - - sops.secrets = { - postgresPassword.sopsFile = "${inputs.self}/secrets/postgres.yaml"; - nextcloudAdminPassword = { - sopsFile = "${inputs.self}/k8s/flux/secrets/nextcloud-env.sops.yaml"; - key = "data/NEXTCLOUD_ADMIN_PASSWORD"; - restartUnits = ["docker-nextcloud.service"]; - }; - nextcloudPostgresPassword = { - sopsFile = "${inputs.self}/k8s/flux/secrets/nextcloud-env.sops.yaml"; - key = "data/POSTGRES_PASSWORD"; - }; - nextcloudSmtpPassword = { - sopsFile = "${inputs.self}/k8s/flux/secrets/nextcloud-env.sops.yaml"; - key = "data/SMTP_PASSWORD"; - restartUnits = ["docker-nextcloud.service"]; - }; - nextcloudObjectStoreKey = { - sopsFile = "${inputs.self}/k8s/flux/secrets/nextcloud-garage-env.sops.yaml"; - key = "stringData/OBJECTSTORE_S3_KEY"; - restartUnits = ["docker-nextcloud.service"]; - }; - nextcloudObjectStoreSecret = { - sopsFile = "${inputs.self}/k8s/flux/secrets/nextcloud-garage-env.sops.yaml"; - key = "stringData/OBJECTSTORE_S3_SECRET"; - restartUnits = ["docker-nextcloud.service"]; - }; - }; - - sops.templates = { - postgres-environment.content = '' - POSTGRES_PASSWORD=${config.sops.placeholder.postgresPassword} - NEXTCLOUD_POSTGRES_PASSWORD=${config.sops.placeholder.nextcloudPostgresPassword} - ''; - nextcloud-environment.content = '' - NEXTCLOUD_ADMIN_PASSWORD=${config.sops.placeholder.nextcloudAdminPassword} - POSTGRES_PASSWORD=${config.sops.placeholder.nextcloudPostgresPassword} - SMTP_PASSWORD=${config.sops.placeholder.nextcloudSmtpPassword} - OBJECTSTORE_S3_KEY=${config.sops.placeholder.nextcloudObjectStoreKey} - OBJECTSTORE_S3_SECRET=${config.sops.placeholder.nextcloudObjectStoreSecret} - ''; - }; - - myNixOs.docker.networks.nextcloud = { - containers = [ - "postgres" - "nextcloud-valkey" - "nextcloud" - "nextcloud-cron" - ]; - subnet = "172.19.0.0/16"; - bridgeInterface = "nextcloud0"; - allowedTCPPorts = [3900]; - }; - - virtualisation.oci-containers.containers = { - postgres = { - image = "docker.io/library/postgres:18.6@sha256:cd78ca58eb75f929698e117a589488ccb2bd45107247fe02400b50ff6c418324"; - networks = ["nextcloud"]; - environment = { - POSTGRES_DB = "postgres"; - POSTGRES_USER = "postgres"; - }; - environmentFiles = [config.sops.templates.postgres-environment.path]; - volumes = [ - "/mnt/Data/postgres:/var/lib/postgresql" - "${pkgs.writeShellScript "postgres-init-nextcloud" '' - set -eu - psql --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" \\ - --set=nextcloud_postgres_password="$NEXTCLOUD_POSTGRES_PASSWORD" <<'SQL' - CREATE ROLE nextcloud LOGIN PASSWORD :'nextcloud_postgres_password'; - CREATE DATABASE nextcloud OWNER nextcloud; - SQL - ''}:/docker-entrypoint-initdb.d/10-nextcloud.sh:ro" - ]; - }; - - nextcloud-valkey = { - image = "valkey/valkey:9-alpine@sha256:ee91f7a174ac4d6a6b0685b3a60e321f0a9dbbb691f9b0e285be2ba1d1be8328"; - networks = ["nextcloud"]; - cmd = ["valkey-server" "--maxmemory" "256mb" "--maxmemory-policy" "volatile-lru"]; - volumes = ["/mnt/Data/nextcloud/valkey:/data"]; - }; - - nextcloud = { - image = "docker.io/library/nextcloud:34-apache@sha256:368cd1c75bc4a32c2aee8a119cae31bcebff80c374782f404c440c3295726814"; - dependsOn = ["postgres" "nextcloud-valkey"]; - networks = ["nextcloud"]; - environment = { - APACHE_DISABLE_REWRITE_IP = "1"; - MAIL_DOMAIN = "aly.social"; - MAIL_FROM_ADDRESS = "admin"; - NEXTCLOUD_ADMIN_USER = "alyraffauf"; - NEXTCLOUD_TRUSTED_DOMAINS = "nextcloud.cute.haus"; - OBJECTSTORE_S3_AUTOCREATE = "false"; - OBJECTSTORE_S3_BUCKET = "aly-nextcloud"; - OBJECTSTORE_S3_HOST = "host.docker.internal"; - OBJECTSTORE_S3_PORT = "3900"; - OBJECTSTORE_S3_REGION = "garage"; - OBJECTSTORE_S3_SSL = "false"; - OBJECTSTORE_S3_USEPATH_STYLE = "true"; - OVERWRITECLIURL = "https://nextcloud.cute.haus"; - OVERWRITEHOST = "nextcloud.cute.haus"; - OVERWRITEPROTOCOL = "https"; - PHP_MEMORY_LIMIT = "512M"; - PHP_UPLOAD_LIMIT = "10G"; - POSTGRES_DB = "nextcloud"; - POSTGRES_HOST = "postgres"; - POSTGRES_USER = "nextcloud"; - REDIS_HOST = "nextcloud-valkey"; - REDIS_HOST_PORT = "6379"; - SMTP_AUTHTYPE = "LOGIN"; - SMTP_HOST = "smtp.resend.com"; - SMTP_NAME = "resend"; - SMTP_PORT = "465"; - SMTP_SECURE = "ssl"; - TRUSTED_PROXIES = "10.42.0.0/16"; - }; - environmentFiles = [config.sops.templates.nextcloud-environment.path]; - extraOptions = [ - "--add-host=host.docker.internal:172.19.0.1" - "--memory=4g" - ]; - ports = ["10.254.0.1:8081:80"]; - volumes = ["/mnt/Data/nextcloud/html:/var/www/html"]; - }; - - nextcloud-cron = { - image = "docker.io/library/nextcloud:34-apache@sha256:368cd1c75bc4a32c2aee8a119cae31bcebff80c374782f404c440c3295726814"; - dependsOn = ["nextcloud"]; - networks = ["nextcloud"]; - cmd = ["/bin/sh" "-c" "while true; do php -f /var/www/html/cron.php || true; sleep 60; done"]; - environment = { - POSTGRES_DB = "nextcloud"; - POSTGRES_HOST = "postgres"; - POSTGRES_USER = "nextcloud"; - REDIS_HOST = "nextcloud-valkey"; - REDIS_HOST_PORT = "6379"; - }; - environmentFiles = [config.sops.templates.nextcloud-environment.path]; - extraOptions = [ - "--add-host=host.docker.internal:172.19.0.1" - "--user=33:33" - ]; - volumes = ["/mnt/Data/nextcloud/html:/var/www/html"]; - }; - }; - - systemd.services = { - docker-postgres.unitConfig.RequiresMountsFor = ["/mnt/Data"]; - docker-nextcloud-valkey.unitConfig.RequiresMountsFor = ["/mnt/Data"]; - - docker-nextcloud = { - preStart = '' - config_file=/mnt/Data/nextcloud/html/config/config.php - - if ${pkgs.gnugrep}/bin/grep -Fq "pg-shared-rw.cnpg-system.svc" "$config_file"; then - ${pkgs.gnused}/bin/sed -i \ - -e "s/pg-shared-rw\.cnpg-system\.svc/postgres/" \ - -e "s/valkey\.nextcloud\.svc/nextcloud-valkey/" \ - "$config_file" - elif ! ${pkgs.gnugrep}/bin/grep -Fq "'dbhost' => 'postgres'" "$config_file"; then - echo "Nextcloud database host is neither the cluster nor local PostgreSQL" >&2 - exit 1 - fi - - ${pkgs.gnused}/bin/sed -i \ - "s/10\\.254\\.0\\.1/host.docker.internal/g" \ - "$config_file" - ''; - unitConfig = { - ConditionPathExists = "/mnt/Data/nextcloud/.local-postgres-ready"; - RequiresMountsFor = ["/mnt/Data"]; - }; - }; - - docker-nextcloud-cron.unitConfig = { - ConditionPathExists = "/mnt/Data/nextcloud/.local-postgres-ready"; - RequiresMountsFor = ["/mnt/Data"]; - }; - }; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/containers/paperless.nix b/nix/modules/hosts/nixos/jubilife/containers/paperless.nix deleted file mode 100644 index b88ea75b..00000000 --- a/nix/modules/hosts/nixos/jubilife/containers/paperless.nix +++ /dev/null @@ -1,163 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - config, - inputs, - pkgs, - ... - }: { - sops.secrets = { - paperlessAdminPassword = { - sopsFile = "${inputs.self}/secrets/paperless.yaml"; - key = "PAPERLESS_ADMIN_PASSWORD"; - restartUnits = ["docker-paperless.service"]; - }; - paperlessDatabasePassword = { - sopsFile = "${inputs.self}/secrets/paperless.yaml"; - key = "PAPERLESS_DBPASS"; - }; - paperlessSecretKey = { - sopsFile = "${inputs.self}/secrets/paperless.yaml"; - key = "PAPERLESS_SECRET_KEY"; - restartUnits = ["docker-paperless.service"]; - }; - paperlessSocialAccountProviders = { - sopsFile = "${inputs.self}/secrets/paperless.yaml"; - key = "PAPERLESS_SOCIALACCOUNT_PROVIDERS"; - restartUnits = ["docker-paperless.service"]; - }; - }; - - sops.templates = { - paperless-database-environment.content = '' - PAPERLESS_DBPASS=${config.sops.placeholder.paperlessDatabasePassword} - ''; - paperless-environment.content = '' - PAPERLESS_ADMIN_PASSWORD=${config.sops.placeholder.paperlessAdminPassword} - PAPERLESS_DBPASS=${config.sops.placeholder.paperlessDatabasePassword} - PAPERLESS_SECRET_KEY=${config.sops.placeholder.paperlessSecretKey} - PAPERLESS_SOCIALACCOUNT_PROVIDERS=${config.sops.placeholder.paperlessSocialAccountProviders} - ''; - }; - - myNixOs.docker.networks.paperless.containers = [ - "postgres" - "paperless-valkey" - "tika" - "gotenberg" - "paperless" - ]; - - virtualisation.oci-containers.containers = { - paperless-valkey = { - image = "valkey/valkey:9-alpine@sha256:ee91f7a174ac4d6a6b0685b3a60e321f0a9dbbb691f9b0e285be2ba1d1be8328"; - networks = ["paperless"]; - cmd = ["valkey-server" "--maxmemory" "1gb" "--maxmemory-policy" "volatile-lru"]; - extraOptions = ["--tmpfs=/data:rw,noexec,nosuid,size=1g"]; - }; - - tika = { - image = "apache/tika:3.3.1.0-full@sha256:d8e6ed96260ad89307a93195a1b856102987a818ac648502f8efbaf313d32470"; - networks = ["paperless"]; - extraOptions = ["--memory=4g"]; - ports = ["10.254.0.1:9998:9998"]; - }; - - gotenberg = { - image = "gotenberg/gotenberg:8@sha256:87c16b9f364279d321bc9772d31fa58aa6abe036423c270698bd636c3a8e9466"; - networks = ["paperless"]; - extraOptions = ["--memory=1g"]; - ports = ["10.254.0.1:3000:3000"]; - }; - - paperless = { - image = "ghcr.io/paperless-ngx/paperless-ngx:latest@sha256:65a4cabf0169ea7fbd90ab7bb28ba3f8b5909613635acda1a03ad606f34b456b"; - dependsOn = ["postgres" "paperless-valkey" "tika" "gotenberg"]; - networks = ["paperless"]; - environment = { - PAPERLESS_ACCOUNT_DEFAULT_GROUP = "users"; - PAPERLESS_ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https"; - PAPERLESS_ADMIN_MAIL = "alyraffauf@fastmail.com"; - PAPERLESS_ADMIN_USER = "alyraffauf"; - PAPERLESS_APPS = "allauth.socialaccount.providers.openid_connect"; - PAPERLESS_CONSUMER_DELETE = "true"; - PAPERLESS_CONSUMPTION_DIR = "/paperless/consume"; - PAPERLESS_DATA_DIR = "/paperless/data"; - PAPERLESS_DBHOST = "postgres"; - PAPERLESS_DBNAME = "paperless"; - PAPERLESS_DBPORT = "5432"; - PAPERLESS_DBUSER = "paperless"; - PAPERLESS_MEDIA_ROOT = "/paperless/media"; - PAPERLESS_OCR_LANGUAGE = "eng"; - PAPERLESS_OCR_PAGES = "2"; - PAPERLESS_PROXY_SSL_HEADER = ''["HTTP_X_FORWARDED_PROTO", "https"]''; - PAPERLESS_REDIS = "redis://paperless-valkey:6379/0"; - PAPERLESS_SOCIAL_AUTO_SIGNUP = "True"; - PAPERLESS_TASK_WORKERS = "1"; - PAPERLESS_TIKA_ENABLED = "1"; - PAPERLESS_TIKA_ENDPOINT = "http://tika:9998"; - PAPERLESS_TIKA_GOTENBERG_ENDPOINT = "http://gotenberg:3000"; - PAPERLESS_TIME_ZONE = "America/New_York"; - PAPERLESS_URL = "https://paperless.cute.haus"; - PAPERLESS_USE_X_FORWARD_HOST = "true"; - PAPERLESS_USE_X_FORWARD_PORT = "true"; - USERMAP_GID = "1000"; - USERMAP_UID = "1000"; - }; - environmentFiles = [config.sops.templates.paperless-environment.path]; - extraOptions = ["--memory=8g"]; - ports = ["10.254.0.1:8001:8000"]; - volumes = [ - "/mnt/Data/paperless/data:/paperless/data" - "/mnt/Data/paperless/consume:/paperless/consume" - "/mnt/Data/paperless/media:/paperless/media" - ]; - }; - }; - - systemd.services = { - docker-connect-postgres-paperless = { - description = "Connect PostgreSQL to the Paperless Docker network"; - after = ["docker-network-paperless.service" "docker-postgres.service"]; - requires = ["docker-network-paperless.service" "docker-postgres.service"]; - before = ["postgres-bootstrap-paperless.service"]; - wantedBy = ["multi-user.target"]; - path = [pkgs.docker]; - script = "docker network connect paperless postgres 2>/dev/null || true"; - serviceConfig.Type = "oneshot"; - }; - - postgres-bootstrap-paperless = { - description = "Create the local Paperless PostgreSQL role and database"; - after = ["docker-connect-postgres-paperless.service"]; - requires = ["docker-connect-postgres-paperless.service"]; - before = ["docker-paperless.service"]; - wantedBy = ["multi-user.target"]; - path = [pkgs.docker]; - script = '' - set -eu - source ${config.sops.templates.paperless-database-environment.path} - - docker exec -i postgres psql \ - --username postgres \ - --dbname postgres \ - --set ON_ERROR_STOP=1 \ - --set paperless_database_password="$PAPERLESS_DBPASS" <<'SQL' - SELECT format('CREATE ROLE paperless LOGIN PASSWORD %L', :'paperless_database_password') - WHERE NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'paperless') - \gexec - ALTER ROLE paperless LOGIN PASSWORD :'paperless_database_password'; - SELECT 'CREATE DATABASE paperless OWNER paperless' - WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'paperless') - \gexec - SQL - ''; - serviceConfig.Type = "oneshot"; - }; - - docker-paperless.unitConfig = { - ConditionPathExists = "/mnt/Data/paperless/.local-postgres-ready"; - RequiresMountsFor = ["/mnt/Data"]; - }; - }; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/containers/slingshot.nix b/nix/modules/hosts/nixos/jubilife/containers/slingshot.nix deleted file mode 100644 index 506bccce..00000000 --- a/nix/modules/hosts/nixos/jubilife/containers/slingshot.nix +++ /dev/null @@ -1,22 +0,0 @@ -_: { - flake.nixosModules.jubilife = _: { - virtualisation.oci-containers.containers.slingshot = { - image = "ghcr.io/alyraffauf/slingshot:latest@sha256:6e3a2860f0c4aa98e6f95f9ff6a7d9eb61266f2272e3eaeb6de32ba221b20e38"; - environment = { - SLINGSHOT_CACHE_DIR = "/cache"; - SLINGSHOT_IDENTITY_CACHE_DISK_DB = "2"; - SLINGSHOT_IDENTITY_CACHE_MEMORY_MB = "64"; - SLINGSHOT_JETSTREAM = "wss://jetstream1.us-east.bsky.network/subscribe"; - SLINGSHOT_RECORD_CACHE_DISK_DB = "4"; - SLINGSHOT_RECORD_CACHE_MEMORY_MB = "256"; - }; - extraOptions = [ - "--cpus=2" - "--memory=2g" - "--tmpfs=/cache:rw,size=8g,uid=65532,gid=65532" - "--ulimit=nofile=8192:8192" - ]; - ports = ["10.254.0.1:8765:8080"]; - }; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/default.nix b/nix/modules/hosts/nixos/jubilife/default.nix deleted file mode 100644 index 36dde9c2..00000000 --- a/nix/modules/hosts/nixos/jubilife/default.nix +++ /dev/null @@ -1,39 +0,0 @@ -{ - inputs, - self, - ... -}: { - config.flake.nixosConfigurations.jubilife = inputs.nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - specialArgs = {inherit inputs self;}; - modules = [ - inputs.disko.nixosModules.disko - inputs.sops-nix.nixosModules.sops - self.nixosModules.default - self.nixosModules.jubilife - self.nixosModules.intelGpu - self.nixosModules.disko - self.nixosModules.luksBtrfsSubvolumes - self.nixosModules.arr - self.nixosModules.b2Mounts - self.nixosModules.backups - self.nixosModules.btrfs - self.nixosModules.k3s - self.nixosModules.swap - self.nixosModules.wireguardK3s - self.nixosModules.lanzaboote - self.nixosModules.docker - self.nixosModules.dockerNetworks - self.nixosModules.alloy - self.nixosModules.atbbs - self.nixosModules.caddy - self.nixosModules.fail2ban - self.nixosModules.tautulli - self.nixosModules.prometheusNode - self.nixosModules.qbittorrent - self.nixosModules.syncthing - self.nixosModules.tailscale - self.nixosModules.aly - ]; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/disko.nix b/nix/modules/hosts/nixos/jubilife/disko.nix deleted file mode 100644 index 677c9ecc..00000000 --- a/nix/modules/hosts/nixos/jubilife/disko.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - myDisko.installDrive = "/dev/disk/by-id/nvme-PNY_CS2130_1TB_SSD_PNY211821050701050CC"; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/exporters.nix b/nix/modules/hosts/nixos/jubilife/exporters.nix deleted file mode 100644 index cbe74f44..00000000 --- a/nix/modules/hosts/nixos/jubilife/exporters.nix +++ /dev/null @@ -1,54 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - config, - lib, - self, - ... - }: let - tailnet = "narwhal-snapper.ts.net"; - exporters = { - bazarr = { - apiKey = "bazarr_api_key"; - port = 9708; - }; - lidarr = { - apiKey = "lidarr_api_key"; - port = 9709; - }; - prowlarr = { - apiKey = "prowlarr_api_key"; - port = 9710; - }; - radarr = { - apiKey = "radarr_api_key"; - port = 9711; - }; - sonarr = { - apiKey = "sonarr_api_key"; - port = 9712; - }; - }; - in { - sops.secrets = - lib.mapAttrs' (serviceName: service: { - name = "${serviceName}ApiKey"; - value = { - sopsFile = "${self}/secrets/arr.yaml"; - key = service.apiKey; - }; - }) - exporters; - services.prometheus.exporters = - (lib.mapAttrs' (serviceName: service: { - name = "exportarr-${serviceName}"; - value = { - enable = true; - apiKeyFile = config.sops.secrets."${serviceName}ApiKey".path; - inherit (service) port; - url = "https://${serviceName}.${tailnet}"; - }; - }) - exporters) - // {smartctl.enable = true;}; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/facter.json b/nix/modules/hosts/nixos/jubilife/facter.json deleted file mode 100644 index e2135738..00000000 --- a/nix/modules/hosts/nixos/jubilife/facter.json +++ /dev/null @@ -1,5203 +0,0 @@ -{ - "version": 1, - "system": "x86_64-linux", - "virtualisation": "none", - "uefi": { - "supported": true, - "platform_size": 64 - }, - "hardware": { - "bios": { - "apm_info": { - "supported": false, - "enabled": false, - "version": 0, - "sub_version": 0, - "bios_flags": 0 - }, - "vbe_info": { - "version": 0, - "video_memory": 0 - }, - "pnp": false, - "pnp_id": 0, - "lba_support": false, - "low_memory_size": 0, - "smbios_version": 771 - }, - "bridge": [ - { - "index": 17, - "attached_to": 42, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 6, - "number": 5 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1b21", - "value": 6945 - }, - "device": { - "hex": "43b4", - "value": 17332 - }, - "sub_device": { - "hex": "3306", - "value": 13062 - }, - "revision": { - "hex": "0002", - "value": 2 - }, - "model": "AMD PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:05:00.2/0000:06:05.0", - "sysfs_bus_id": "0000:06:05.0", - "detail": { - "function": 0, - "command": 1031, - "header_type": 1, - "secondary_bus": 12, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00001022d000043B4sv00001B21sd00003306bc06sc04i00" - }, - { - "index": 18, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 8 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0000", - "name": "Host bridge", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "1632", - "value": 5682 - }, - "model": "AMD Host bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:08.0", - "sysfs_bus_id": "0000:00:08.0", - "detail": { - "function": 0, - "command": 0, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00001022d00001632sv00000000sd00000000bc06sc00i00" - }, - { - "index": 20, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 24 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0000", - "name": "Host bridge", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "166d", - "value": 5741 - }, - "model": "AMD Host bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:18.3", - "sysfs_bus_id": "0000:00:18.3", - "detail": { - "function": 3, - "command": 0, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "zenpower", - "driver_module": "zenpower", - "drivers": ["zenpower"], - "driver_modules": ["zenpower"], - "module_alias": "pci:v00001022d0000166Dsv00000000sd00000000bc06sc00i00" - }, - { - "index": 23, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 24 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0000", - "name": "Host bridge", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "166b", - "value": 5739 - }, - "model": "AMD Host bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:18.1", - "sysfs_bus_id": "0000:00:18.1", - "detail": { - "function": 1, - "command": 0, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00001022d0000166Bsv00000000sd00000000bc06sc00i00" - }, - { - "index": 24, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 1 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0000", - "name": "Host bridge", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "1632", - "value": 5682 - }, - "model": "AMD Host bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:01.0", - "sysfs_bus_id": "0000:00:01.0", - "detail": { - "function": 0, - "command": 0, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00001022d00001632sv00000000sd00000000bc06sc00i00" - }, - { - "index": 27, - "attached_to": 42, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 6, - "number": 1 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1b21", - "value": 6945 - }, - "device": { - "hex": "43b4", - "value": 17332 - }, - "sub_device": { - "hex": "3306", - "value": 13062 - }, - "revision": { - "hex": "0002", - "value": 2 - }, - "model": "AMD PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:05:00.2/0000:06:01.0", - "sysfs_bus_id": "0000:06:01.0", - "detail": { - "function": 0, - "command": 1031, - "header_type": 1, - "secondary_bus": 8, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00001022d000043B4sv00001B21sd00003306bc06sc04i00" - }, - { - "index": 28, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 20 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0001", - "name": "ISA bridge", - "value": 1 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1565", - "value": 5477 - }, - "device": { - "hex": "790e", - "value": 30990 - }, - "sub_device": { - "hex": "370b", - "value": 14091 - }, - "revision": { - "hex": "0051", - "value": 81 - }, - "model": "AMD ISA bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:14.3", - "sysfs_bus_id": "0000:00:14.3", - "detail": { - "function": 3, - "command": 15, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00001022d0000790Esv00001565sd0000370Bbc06sc01i00" - }, - { - "index": 29, - "attached_to": 44, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 1, - "number": 0 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "device": { - "hex": "4fa1", - "value": 20385 - }, - "revision": { - "hex": "0001", - "value": 1 - }, - "model": "Intel PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:01.1/0000:01:00.0", - "sysfs_bus_id": "0000:01:00.0", - "detail": { - "function": 0, - "command": 7, - "header_type": 1, - "secondary_bus": 2, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00008086d00004FA1sv00000000sd00000000bc06sc04i00" - }, - { - "index": 30, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 2 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "1634", - "value": 5684 - }, - "sub_device": { - "hex": "1453", - "value": 5203 - }, - "model": "AMD PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:02.1", - "sysfs_bus_id": "0000:00:02.1", - "detail": { - "function": 1, - "command": 1031, - "header_type": 1, - "secondary_bus": 5, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00001022d00001634sv00001022sd00001453bc06sc04i00" - }, - { - "index": 31, - "attached_to": 42, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 6, - "number": 4 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1b21", - "value": 6945 - }, - "device": { - "hex": "43b4", - "value": 17332 - }, - "sub_device": { - "hex": "3306", - "value": 13062 - }, - "revision": { - "hex": "0002", - "value": 2 - }, - "model": "AMD PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:05:00.2/0000:06:04.0", - "sysfs_bus_id": "0000:06:04.0", - "detail": { - "function": 0, - "command": 1031, - "header_type": 1, - "secondary_bus": 11, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00001022d000043B4sv00001B21sd00003306bc06sc04i00" - }, - { - "index": 32, - "attached_to": 42, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 6, - "number": 7 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1b21", - "value": 6945 - }, - "device": { - "hex": "43b4", - "value": 17332 - }, - "sub_device": { - "hex": "3306", - "value": 13062 - }, - "revision": { - "hex": "0002", - "value": 2 - }, - "model": "AMD PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:05:00.2/0000:06:07.0", - "sysfs_bus_id": "0000:06:07.0", - "detail": { - "function": 0, - "command": 1031, - "header_type": 1, - "secondary_bus": 14, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00001022d000043B4sv00001B21sd00003306bc06sc04i00" - }, - { - "index": 33, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 24 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0000", - "name": "Host bridge", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "1670", - "value": 5744 - }, - "model": "AMD Host bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:18.6", - "sysfs_bus_id": "0000:00:18.6", - "detail": { - "function": 6, - "command": 0, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00001022d00001670sv00000000sd00000000bc06sc00i00" - }, - { - "index": 35, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0000", - "name": "Host bridge", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "1630", - "value": 5680 - }, - "sub_device": { - "hex": "1630", - "value": 5680 - }, - "model": "AMD Host bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:00.0", - "sysfs_bus_id": "0000:00:00.0", - "detail": { - "function": 0, - "command": 0, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00001022d00001630sv00001022sd00001630bc06sc00i00" - }, - { - "index": 36, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 8 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "1635", - "value": 5685 - }, - "sub_device": { - "hex": "1635", - "value": 5685 - }, - "model": "AMD PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:08.1", - "sysfs_bus_id": "0000:00:08.1", - "detail": { - "function": 1, - "command": 1031, - "header_type": 1, - "secondary_bus": 16, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00001022d00001635sv00001022sd00001635bc06sc04i00" - }, - { - "index": 37, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 24 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0000", - "name": "Host bridge", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "166e", - "value": 5742 - }, - "model": "AMD Host bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:18.4", - "sysfs_bus_id": "0000:00:18.4", - "detail": { - "function": 4, - "command": 0, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00001022d0000166Esv00000000sd00000000bc06sc00i00" - }, - { - "index": 38, - "attached_to": 42, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 6, - "number": 0 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1b21", - "value": 6945 - }, - "device": { - "hex": "43b4", - "value": 17332 - }, - "sub_device": { - "hex": "3306", - "value": 13062 - }, - "revision": { - "hex": "0002", - "value": 2 - }, - "model": "AMD PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:05:00.2/0000:06:00.0", - "sysfs_bus_id": "0000:06:00.0", - "detail": { - "function": 0, - "command": 1031, - "header_type": 1, - "secondary_bus": 7, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00001022d000043B4sv00001B21sd00003306bc06sc04i00" - }, - { - "index": 42, - "attached_to": 30, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 5, - "number": 0 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1b21", - "value": 6945 - }, - "device": { - "hex": "43b0", - "value": 17328 - }, - "sub_device": { - "hex": "0201", - "value": 513 - }, - "revision": { - "hex": "0002", - "value": 2 - }, - "model": "AMD PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:05:00.2", - "sysfs_bus_id": "0000:05:00.2", - "detail": { - "function": 2, - "command": 7, - "header_type": 1, - "secondary_bus": 6, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00001022d000043B0sv00001B21sd00000201bc06sc04i00" - }, - { - "index": 43, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 24 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0000", - "name": "Host bridge", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "166c", - "value": 5740 - }, - "model": "AMD Host bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:18.2", - "sysfs_bus_id": "0000:00:18.2", - "detail": { - "function": 2, - "command": 0, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00001022d0000166Csv00000000sd00000000bc06sc00i00" - }, - { - "index": 44, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 1 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "1633", - "value": 5683 - }, - "sub_device": { - "hex": "1453", - "value": 5203 - }, - "model": "AMD PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:01.1", - "sysfs_bus_id": "0000:00:01.1", - "detail": { - "function": 1, - "command": 1031, - "header_type": 1, - "secondary_bus": 1, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00001022d00001633sv00001022sd00001453bc06sc04i00" - }, - { - "index": 45, - "attached_to": 42, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 6, - "number": 3 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1b21", - "value": 6945 - }, - "device": { - "hex": "43b4", - "value": 17332 - }, - "sub_device": { - "hex": "3306", - "value": 13062 - }, - "revision": { - "hex": "0002", - "value": 2 - }, - "model": "AMD PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:05:00.2/0000:06:03.0", - "sysfs_bus_id": "0000:06:03.0", - "detail": { - "function": 0, - "command": 1031, - "header_type": 1, - "secondary_bus": 10, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00001022d000043B4sv00001B21sd00003306bc06sc04i00" - }, - { - "index": 48, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 24 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0000", - "name": "Host bridge", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "166a", - "value": 5738 - }, - "model": "AMD Host bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:18.0", - "sysfs_bus_id": "0000:00:18.0", - "detail": { - "function": 0, - "command": 0, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00001022d0000166Asv00000000sd00000000bc06sc00i00" - }, - { - "index": 49, - "attached_to": 42, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 6, - "number": 6 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1b21", - "value": 6945 - }, - "device": { - "hex": "43b4", - "value": 17332 - }, - "sub_device": { - "hex": "3306", - "value": 13062 - }, - "revision": { - "hex": "0002", - "value": 2 - }, - "model": "AMD PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:05:00.2/0000:06:06.0", - "sysfs_bus_id": "0000:06:06.0", - "detail": { - "function": 0, - "command": 1031, - "header_type": 1, - "secondary_bus": 13, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00001022d000043B4sv00001B21sd00003306bc06sc04i00" - }, - { - "index": 51, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 2 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "1634", - "value": 5684 - }, - "sub_device": { - "hex": "1453", - "value": 5203 - }, - "model": "AMD PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:02.2", - "sysfs_bus_id": "0000:00:02.2", - "detail": { - "function": 2, - "command": 1031, - "header_type": 1, - "secondary_bus": 15, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00001022d00001634sv00001022sd00001453bc06sc04i00" - }, - { - "index": 53, - "attached_to": 29, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 2, - "number": 1 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "sub_vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "device": { - "hex": "4fa4", - "value": 20388 - }, - "sub_device": { - "hex": "4fa4", - "value": 20388 - }, - "model": "Intel PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:01.1/0000:01:00.0/0000:02:01.0", - "sysfs_bus_id": "0000:02:01.0", - "detail": { - "function": 0, - "command": 7, - "header_type": 1, - "secondary_bus": 3, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00008086d00004FA4sv00008086sd00004FA4bc06sc04i00" - }, - { - "index": 54, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 2 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0000", - "name": "Host bridge", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "1632", - "value": 5682 - }, - "model": "AMD Host bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:02.0", - "sysfs_bus_id": "0000:00:02.0", - "detail": { - "function": 0, - "command": 0, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00001022d00001632sv00000000sd00000000bc06sc00i00" - }, - { - "index": 55, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 24 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0000", - "name": "Host bridge", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "1671", - "value": 5745 - }, - "model": "AMD Host bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:18.7", - "sysfs_bus_id": "0000:00:18.7", - "detail": { - "function": 7, - "command": 0, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00001022d00001671sv00000000sd00000000bc06sc00i00" - }, - { - "index": 57, - "attached_to": 42, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 6, - "number": 2 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1b21", - "value": 6945 - }, - "device": { - "hex": "43b4", - "value": 17332 - }, - "sub_device": { - "hex": "3306", - "value": 13062 - }, - "revision": { - "hex": "0002", - "value": 2 - }, - "model": "AMD PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:05:00.2/0000:06:02.0", - "sysfs_bus_id": "0000:06:02.0", - "detail": { - "function": 0, - "command": 1031, - "header_type": 1, - "secondary_bus": 9, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00001022d000043B4sv00001B21sd00003306bc06sc04i00" - }, - { - "index": 58, - "attached_to": 29, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 2, - "number": 4 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "sub_vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "device": { - "hex": "4fa4", - "value": 20388 - }, - "sub_device": { - "hex": "0000", - "value": 0 - }, - "model": "Intel PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:01.1/0000:01:00.0/0000:02:04.0", - "sysfs_bus_id": "0000:02:04.0", - "detail": { - "function": 0, - "command": 7, - "header_type": 1, - "secondary_bus": 4, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00008086d00004FA4sv00008086sd00000000bc06sc04i00" - }, - { - "index": 59, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 8 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0004", - "name": "PCI bridge", - "value": 4 - }, - "pci_interface": { - "hex": "0000", - "name": "Normal decode", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "1635", - "value": 5685 - }, - "sub_device": { - "hex": "1635", - "value": 5685 - }, - "model": "AMD PCI bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:08.2", - "sysfs_bus_id": "0000:00:08.2", - "detail": { - "function": 2, - "command": 1031, - "header_type": 1, - "secondary_bus": 17, - "prog_if": 0 - }, - "driver": "pcieport", - "driver_module": "pcieportdrv", - "drivers": ["pcieport"], - "driver_modules": ["pcieportdrv"], - "module_alias": "pci:v00001022d00001635sv00001022sd00001635bc06sc04i00" - }, - { - "index": 60, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 24 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0000", - "name": "Host bridge", - "value": 0 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "166f", - "value": 5743 - }, - "model": "AMD Host bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:18.5", - "sysfs_bus_id": "0000:00:18.5", - "detail": { - "function": 5, - "command": 0, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00001022d0000166Fsv00000000sd00000000bc06sc00i00" - } - ], - "cdrom": [ - { - "index": 70, - "attached_to": 22, - "class_list": ["cdrom", "scsi", "block_device"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 5, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0002", - "name": "CD-ROM", - "value": 2 - }, - "pci_interface": { - "hex": "0003", - "name": "DVD", - "value": 3 - }, - "vendor": { - "hex": "0000", - "name": "MATSHITA", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "BD-MLT UJ265", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "1.00", - "value": 0 - }, - "model": "MATSHITA BD-MLT UJ265", - "sysfs_id": "/class/block/sr0", - "sysfs_bus_id": "5:0:0:0", - "sysfs_device_link": "/devices/pci0000:00/0000:00:02.1/0000:05:00.1/ata6/host5/target5:0:0/5:0:0:0", - "unix_device_names": [ - "/dev/cdrom", - "/dev/disk/by-id/ata-MATSHITABD-MLT_UJ265_WP04_068497", - "/dev/disk/by-path/pci-0000:05:00.1-ata-6", - "/dev/disk/by-path/pci-0000:05:00.1-ata-6.0", - "/dev/sr0" - ], - "unix_device_name2": "/dev/sg3", - "driver": "ahci", - "driver_module": "ahci", - "drivers": ["ahci", "sr"], - "driver_modules": ["ahci", "sr_mod"] - } - ], - "cpu": [ - { - "architecture": "x86_64", - "vendor_name": "AuthenticAMD", - "model_name": "AMD Ryzen 5 5600GT with Radeon Graphics", - "family": 25, - "model": 80, - "stepping": 0, - "features": [ - "fpu", - "vme", - "de", - "pse", - "tsc", - "msr", - "pae", - "mce", - "cx8", - "apic", - "sep", - "mtrr", - "pge", - "mca", - "cmov", - "pat", - "pse36", - "clflush", - "mmx", - "fxsr", - "sse", - "sse2", - "ht", - "syscall", - "nx", - "mmxext", - "fxsr_opt", - "pdpe1gb", - "rdtscp", - "lm", - "constant_tsc", - "rep_good", - "nopl", - "xtopology", - "nonstop_tsc", - "cpuid", - "extd_apicid", - "aperfmperf", - "rapl", - "pni", - "pclmulqdq", - "monitor", - "ssse3", - "fma", - "cx16", - "sse4_1", - "sse4_2", - "x2apic", - "movbe", - "popcnt", - "aes", - "xsave", - "avx", - "f16c", - "rdrand", - "lahf_lm", - "cmp_legacy", - "svm", - "extapic", - "cr8_legacy", - "abm", - "sse4a", - "misalignsse", - "3dnowprefetch", - "osvw", - "ibs", - "skinit", - "wdt", - "tce", - "topoext", - "perfctr_core", - "perfctr_nb", - "bpext", - "perfctr_llc", - "mwaitx", - "cpb", - "cat_l3", - "cdp_l3", - "hw_pstate", - "ssbd", - "mba", - "ibrs", - "ibpb", - "stibp", - "vmmcall", - "fsgsbase", - "bmi1", - "avx2", - "smep", - "bmi2", - "erms", - "invpcid", - "cqm", - "rdt_a", - "rdseed", - "adx", - "smap", - "clflushopt", - "clwb", - "sha_ni", - "xsaveopt", - "xsavec", - "xgetbv1", - "xsaves", - "cqm_llc", - "cqm_occup_llc", - "cqm_mbm_total", - "cqm_mbm_local", - "user_shstk", - "clzero", - "irperf", - "xsaveerptr", - "rdpru", - "wbnoinvd", - "cppc", - "arat", - "npt", - "lbrv", - "svm_lock", - "nrip_save", - "tsc_scale", - "vmcb_clean", - "flushbyasid", - "decodeassists", - "pausefilter", - "pfthreshold", - "avic", - "v_vmsave_vmload", - "vgif", - "v_spec_ctrl", - "umip", - "pku", - "ospke", - "vaes", - "vpclmulqdq", - "rdpid", - "overflow_recov", - "succor", - "smca", - "fsrm", - "debug_swap" - ], - "bugs": [ - "sysret_ss_attrs", - "spectre_v1", - "spectre_v2", - "spec_store_bypass", - "srso", - "ibpb_no_ret", - "spectre_v2_user", - "tsa", - "vmscape" - ], - "power_management": [ - "ts", - "ttp", - "tm", - "hwpstate", - "cpb", - "eff_freq_ro", - "[13]", - "[14]" - ], - "bogo": 7186, - "cache": 512, - "units": 12, - "page_size": 4096, - "physical_id": 0, - "siblings": 12, - "cores": 6, - "fpu": false, - "fpu_exception": false, - "cpuid_level": 16, - "write_protect": false, - "tlb_size": 2560, - "clflush_size": 64, - "cache_alignment": 64, - "address_sizes": { - "physical": "0x30", - "virtual": "0x30" - } - } - ], - "disk": [ - { - "index": 66, - "attached_to": 63, - "class_list": ["disk", "scsi", "block_device"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 14, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "VIRTUAL-DISK", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "serial": "beaf31", - "model": "IET VIRTUAL-DISK", - "sysfs_id": "/class/block/sdf", - "sysfs_bus_id": "14:0:0:1", - "sysfs_device_link": "/devices/platform/host14/session9/target14:0:0/14:0:0:1", - "unix_device_names": [ - "/dev/disk/by-id/scsi-360000000000000000e00000000030001", - "/dev/disk/by-id/wwn-0x60000000000000000e00000000030001", - "/dev/disk/by-path/ip-10.42.3.71:3260-iscsi-iqn.2019-10.io.longhorn:pvc-9b96d92a-7810-4a40-96d1-b02dcd1e631f-lun-1", - "/dev/disk/by-uuid/9036d36e-097b-404e-b34b-bfb017efe762", - "/dev/sdf" - ], - "unix_device_name2": "/dev/sg9", - "resources": [ - { - "type": "disk_geo", - "cylinders": 1011, - "heads": 34, - "sectors": 61, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 2097152, - "value_2": 512 - } - ], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp", "sd"], - "driver_modules": ["iscsi-tcp", "sd_mod"] - }, - { - "index": 67, - "attached_to": 39, - "class_list": ["disk", "block_device", "nvme"], - "bus_type": { - "hex": "0096", - "name": "NVME", - "value": 150 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "vendor": { - "hex": "1987", - "value": 6535 - }, - "sub_vendor": { - "hex": "1987", - "value": 6535 - }, - "device": { - "hex": "5012", - "name": "PNY CS2130 1TB SSD", - "value": 20498 - }, - "sub_device": { - "hex": "5012", - "value": 20498 - }, - "serial": "PNY211821050701050CC", - "model": "PNY CS2130 1TB SSD", - "sysfs_id": "/class/block/nvme0n1", - "sysfs_bus_id": "nvme0", - "sysfs_device_link": "/devices/pci0000:00/0000:00:02.2/0000:0f:00.0/nvme/nvme0", - "unix_device_names": [ - "/dev/disk/by-id/nvme-PNY_CS2130_1TB_SSD_PNY211821050701050CC", - "/dev/disk/by-id/nvme-PNY_CS2130_1TB_SSD_PNY211821050701050CC_1", - "/dev/disk/by-id/nvme-nvme.1987-504e593231313832313035303730313035304343-504e59204353323133302031544220535344-00000001", - "/dev/disk/by-path/pci-0000:0f:00.0-nvme-1", - "/dev/nvme0n1" - ], - "resources": [ - { - "type": "disk_geo", - "cylinders": 953869, - "heads": 64, - "sectors": 32, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 1953525168, - "value_2": 512 - } - ], - "driver": "nvme", - "driver_module": "nvme", - "drivers": ["nvme"], - "driver_modules": ["nvme"] - }, - { - "index": 68, - "attached_to": 65, - "class_list": ["disk", "scsi", "block_device"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 12, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "VIRTUAL-DISK", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "serial": "beaf11", - "model": "IET VIRTUAL-DISK", - "sysfs_id": "/class/block/sdd", - "sysfs_bus_id": "12:0:0:1", - "sysfs_device_link": "/devices/platform/host12/session1/target12:0:0/12:0:0:1", - "unix_device_names": [ - "/dev/disk/by-id/scsi-360000000000000000e00000000010001", - "/dev/disk/by-id/wwn-0x60000000000000000e00000000010001", - "/dev/disk/by-path/ip-10.42.3.71:3260-iscsi-iqn.2019-10.io.longhorn:pvc-bacdfec1-ce17-4dbb-8bd3-aac1b2902335-lun-1", - "/dev/disk/by-uuid/f023c9c9-7fcf-4375-8ef4-e3bdd8a42cdf", - "/dev/sdd" - ], - "unix_device_name2": "/dev/sg5", - "resources": [ - { - "type": "disk_geo", - "cylinders": 20480, - "heads": 64, - "sectors": 32, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 41943040, - "value_2": 512 - } - ], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp", "sd"], - "driver_modules": ["iscsi-tcp", "sd_mod"] - }, - { - "index": 69, - "attached_to": 22, - "class_list": ["disk", "ide", "block_device"], - "bus_type": { - "hex": "0085", - "name": "IDE", - "value": 133 - }, - "slot": { - "bus": 1, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "ST14000NM001G-2K", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "SN03", - "value": 0 - }, - "serial": "ZL201G1C", - "model": "ST14000NM001G-2K", - "sysfs_id": "/class/block/sdb", - "sysfs_bus_id": "1:0:0:0", - "sysfs_device_link": "/devices/pci0000:00/0000:00:02.1/0000:05:00.1/ata2/host1/target1:0:0/1:0:0:0", - "unix_device_names": [ - "/dev/disk/by-id/ata-ST14000NM001G-2KJ103_ZL201G1C", - "/dev/disk/by-id/wwn-0x5000c500b50d5bbd", - "/dev/disk/by-path/pci-0000:05:00.1-ata-2", - "/dev/disk/by-path/pci-0000:05:00.1-ata-2.0", - "/dev/sdb" - ], - "resources": [ - { - "type": "disk_geo", - "cylinders": 1702132, - "heads": 255, - "sectors": 63, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 27344764928, - "value_2": 512 - } - ], - "driver": "ahci", - "driver_module": "ahci", - "drivers": ["ahci", "sd"], - "driver_modules": ["ahci", "sd_mod"] - }, - { - "index": 71, - "attached_to": 64, - "class_list": ["disk", "scsi", "block_device"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 15, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "VIRTUAL-DISK", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "serial": "beaf41", - "model": "IET VIRTUAL-DISK", - "sysfs_id": "/class/block/sdg", - "sysfs_bus_id": "15:0:0:1", - "sysfs_device_link": "/devices/platform/host15/session10/target15:0:0/15:0:0:1", - "unix_device_names": [ - "/dev/disk/by-id/scsi-360000000000000000e00000000040001", - "/dev/disk/by-id/wwn-0x60000000000000000e00000000040001", - "/dev/disk/by-path/ip-10.42.3.71:3260-iscsi-iqn.2019-10.io.longhorn:pvc-5ca7d829-c1c4-4b96-8a64-b3f9faab4365-lun-1", - "/dev/disk/by-uuid/2d4ff926-3fb1-4835-ae49-adbbf513999a", - "/dev/sdg" - ], - "unix_device_name2": "/dev/sg11", - "resources": [ - { - "type": "disk_geo", - "cylinders": 1011, - "heads": 34, - "sectors": 61, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 2097152, - "value_2": 512 - } - ], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp", "sd"], - "driver_modules": ["iscsi-tcp", "sd_mod"] - }, - { - "index": 72, - "attached_to": 61, - "class_list": ["disk", "scsi", "block_device"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 13, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "VIRTUAL-DISK", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "serial": "beaf21", - "model": "IET VIRTUAL-DISK", - "sysfs_id": "/class/block/sde", - "sysfs_bus_id": "13:0:0:1", - "sysfs_device_link": "/devices/platform/host13/session8/target13:0:0/13:0:0:1", - "unix_device_names": [ - "/dev/disk/by-id/scsi-360000000000000000e00000000020001", - "/dev/disk/by-id/wwn-0x60000000000000000e00000000020001", - "/dev/disk/by-path/ip-10.42.3.71:3260-iscsi-iqn.2019-10.io.longhorn:pvc-3fe903a2-08b4-476f-b7a7-629318d6bc7f-lun-1", - "/dev/disk/by-uuid/70d6f3fd-8413-41d3-87f6-6067c1ca3aaa", - "/dev/sde" - ], - "unix_device_name2": "/dev/sg7", - "resources": [ - { - "type": "disk_geo", - "cylinders": 10240, - "heads": 64, - "sectors": 32, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 20971520, - "value_2": 512 - } - ], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp", "sd"], - "driver_modules": ["iscsi-tcp", "sd_mod"] - }, - { - "index": 73, - "attached_to": 22, - "class_list": ["disk", "ide", "block_device"], - "bus_type": { - "hex": "0085", - "name": "IDE", - "value": 133 - }, - "slot": { - "bus": 4, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "CT4000BX500SSD1", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "082", - "value": 0 - }, - "serial": "2447E9959972", - "model": "CT4000BX500SSD1", - "sysfs_id": "/class/block/sdc", - "sysfs_bus_id": "4:0:0:0", - "sysfs_device_link": "/devices/pci0000:00/0000:00:02.1/0000:05:00.1/ata5/host4/target4:0:0/4:0:0:0", - "unix_device_names": [ - "/dev/disk/by-id/ata-CT4000BX500SSD1_2447E9959972", - "/dev/disk/by-id/wwn-0x500a0751e9959972", - "/dev/disk/by-label/Media", - "/dev/disk/by-path/pci-0000:05:00.1-ata-5", - "/dev/disk/by-path/pci-0000:05:00.1-ata-5.0", - "/dev/disk/by-uuid/a33e99f0-f87f-4d05-9ac1-409a0002e6ec", - "/dev/sdc" - ], - "resources": [ - { - "type": "disk_geo", - "cylinders": 486401, - "heads": 255, - "sectors": 63, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 7814037168, - "value_2": 512 - } - ], - "driver": "ahci", - "driver_module": "ahci", - "drivers": ["ahci", "sd"], - "driver_modules": ["ahci", "sd_mod"] - }, - { - "index": 74, - "attached_to": 22, - "class_list": ["disk", "ide", "block_device"], - "bus_type": { - "hex": "0085", - "name": "IDE", - "value": 133 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "ST14000NM001G-2K", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "SN03", - "value": 0 - }, - "serial": "ZL201XNJ", - "model": "ST14000NM001G-2K", - "sysfs_id": "/class/block/sda", - "sysfs_bus_id": "0:0:0:0", - "sysfs_device_link": "/devices/pci0000:00/0000:00:02.1/0000:05:00.1/ata1/host0/target0:0:0/0:0:0:0", - "unix_device_names": [ - "/dev/disk/by-id/ata-ST14000NM001G-2KJ103_ZL201XNJ", - "/dev/disk/by-id/wwn-0x5000c500b527b00d", - "/dev/disk/by-path/pci-0000:05:00.1-ata-1", - "/dev/disk/by-path/pci-0000:05:00.1-ata-1.0", - "/dev/sda" - ], - "resources": [ - { - "type": "disk_geo", - "cylinders": 1702132, - "heads": 255, - "sectors": 63, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 27344764928, - "value_2": 512 - } - ], - "driver": "ahci", - "driver_module": "ahci", - "drivers": ["ahci", "sd"], - "driver_modules": ["ahci", "sd_mod"] - }, - { - "index": 75, - "attached_to": 0, - "class_list": ["disk", "block_device"], - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "model": "Disk", - "sysfs_id": "/class/block/zram0", - "unix_device_names": [ - "/dev/disk/by-label/zram0", - "/dev/disk/by-uuid/7a49497f-74a3-4177-af17-f715ddb2e3a3", - "/dev/zram0" - ], - "resources": [ - { - "type": "size", - "unit": "sectors", - "value_1": 4029568, - "value_2": 4096 - } - ] - }, - { - "index": 76, - "attached_to": 62, - "class_list": ["disk", "scsi", "block_device"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 16, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "VIRTUAL-DISK", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "serial": "beaf51", - "model": "IET VIRTUAL-DISK", - "sysfs_id": "/class/block/sdh", - "sysfs_bus_id": "16:0:0:1", - "sysfs_device_link": "/devices/platform/host16/session11/target16:0:0/16:0:0:1", - "unix_device_names": [ - "/dev/disk/by-id/scsi-360000000000000000e00000000050001", - "/dev/disk/by-id/wwn-0x60000000000000000e00000000050001", - "/dev/disk/by-path/ip-10.42.3.71:3260-iscsi-iqn.2019-10.io.longhorn:pvc-11698a19-b886-455a-a722-c653a92d8a01-lun-1", - "/dev/disk/by-uuid/2e716247-7a5f-42b4-952f-65825611a0de", - "/dev/sdh" - ], - "unix_device_name2": "/dev/sg13", - "resources": [ - { - "type": "disk_geo", - "cylinders": 10240, - "heads": 64, - "sectors": 32, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 20971520, - "value_2": 512 - } - ], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp", "sd"], - "driver_modules": ["iscsi-tcp", "sd_mod"] - } - ], - "graphics_card": [ - { - "index": 16, - "attached_to": 53, - "class_list": ["graphics_card", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 3, - "number": 0 - }, - "base_class": { - "hex": "0003", - "name": "Display controller", - "value": 3 - }, - "sub_class": { - "hex": "0000", - "name": "VGA compatible controller", - "value": 0 - }, - "pci_interface": { - "hex": "0000", - "name": "VGA", - "value": 0 - }, - "vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "sub_vendor": { - "hex": "172f", - "value": 5935 - }, - "device": { - "hex": "56a6", - "value": 22182 - }, - "sub_device": { - "hex": "4240", - "value": 16960 - }, - "revision": { - "hex": "0005", - "value": 5 - }, - "model": "Intel VGA compatible controller", - "sysfs_id": "/devices/pci0000:00/0000:00:01.1/0000:01:00.0/0000:02:01.0/0000:03:00.0", - "sysfs_bus_id": "0000:03:00.0", - "detail": { - "function": 0, - "command": 7, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "i915", - "driver_module": "i915", - "drivers": ["i915"], - "driver_modules": ["i915"], - "module_alias": "pci:v00008086d000056A6sv0000172Fsd00004240bc03sc00i00" - } - ], - "hub": [ - { - "index": 82, - "attached_to": 40, - "class_list": ["usb", "hub"], - "bus_type": { - "hex": "0086", - "name": "USB", - "value": 134 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "010a", - "name": "Hub", - "value": 266 - }, - "vendor": { - "hex": "1d6b", - "name": "Linux 6.18.44 xhci-hcd", - "value": 7531 - }, - "device": { - "hex": "0003", - "name": "xHCI Host Controller", - "value": 3 - }, - "revision": { - "hex": "0000", - "name": "6.18", - "value": 0 - }, - "serial": "0000:10:00.4", - "model": "Linux 6.18.44 xhci-hcd xHCI Host Controller", - "sysfs_id": "/devices/pci0000:00/0000:00:08.1/0000:10:00.4/usb6/6-0:1.0", - "sysfs_bus_id": "6-0:1.0", - "detail": { - "device_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "device_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "device_protocol": 3, - "interface_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "interface_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "interface_protocol": 0, - "interface_number": 0, - "interface_alternate_setting": 0 - }, - "hotplug": "usb", - "driver": "hub", - "driver_module": "usbcore", - "drivers": ["hub"], - "driver_modules": ["usbcore"], - "module_alias": "usb:v1D6Bp0003d0618dc09dsc00dp03ic09isc00ip00in00" - }, - { - "index": 83, - "attached_to": 21, - "class_list": ["usb", "hub"], - "bus_type": { - "hex": "0086", - "name": "USB", - "value": 134 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "010a", - "name": "Hub", - "value": 266 - }, - "vendor": { - "hex": "1d6b", - "name": "Linux 6.18.44 xhci-hcd", - "value": 7531 - }, - "device": { - "hex": "0002", - "name": "xHCI Host Controller", - "value": 2 - }, - "revision": { - "hex": "0000", - "name": "6.18", - "value": 0 - }, - "serial": "0000:10:00.3", - "model": "Linux 6.18.44 xhci-hcd xHCI Host Controller", - "sysfs_id": "/devices/pci0000:00/0000:00:08.1/0000:10:00.3/usb3/3-0:1.0", - "sysfs_bus_id": "3-0:1.0", - "resources": [ - { - "type": "baud", - "speed": 480000000, - "bits": 0, - "stop_bits": 0, - "parity": 0, - "handshake": 0 - } - ], - "detail": { - "device_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "device_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "device_protocol": 1, - "interface_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "interface_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "interface_protocol": 0, - "interface_number": 0, - "interface_alternate_setting": 0 - }, - "hotplug": "usb", - "driver": "hub", - "driver_module": "usbcore", - "drivers": ["hub"], - "driver_modules": ["usbcore"], - "module_alias": "usb:v1D6Bp0002d0618dc09dsc00dp01ic09isc00ip00in00" - }, - { - "index": 85, - "attached_to": 21, - "class_list": ["usb", "hub"], - "bus_type": { - "hex": "0086", - "name": "USB", - "value": 134 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "010a", - "name": "Hub", - "value": 266 - }, - "vendor": { - "hex": "1d6b", - "name": "Linux 6.18.44 xhci-hcd", - "value": 7531 - }, - "device": { - "hex": "0003", - "name": "xHCI Host Controller", - "value": 3 - }, - "revision": { - "hex": "0000", - "name": "6.18", - "value": 0 - }, - "serial": "0000:10:00.3", - "model": "Linux 6.18.44 xhci-hcd xHCI Host Controller", - "sysfs_id": "/devices/pci0000:00/0000:00:08.1/0000:10:00.3/usb4/4-0:1.0", - "sysfs_bus_id": "4-0:1.0", - "detail": { - "device_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "device_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "device_protocol": 3, - "interface_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "interface_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "interface_protocol": 0, - "interface_number": 0, - "interface_alternate_setting": 0 - }, - "hotplug": "usb", - "driver": "hub", - "driver_module": "usbcore", - "drivers": ["hub"], - "driver_modules": ["usbcore"], - "module_alias": "usb:v1D6Bp0003d0618dc09dsc00dp03ic09isc00ip00in00" - }, - { - "index": 86, - "attached_to": 47, - "class_list": ["usb", "hub"], - "bus_type": { - "hex": "0086", - "name": "USB", - "value": 134 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "010a", - "name": "Hub", - "value": 266 - }, - "vendor": { - "hex": "1d6b", - "name": "Linux 6.18.44 xhci-hcd", - "value": 7531 - }, - "device": { - "hex": "0002", - "name": "xHCI Host Controller", - "value": 2 - }, - "revision": { - "hex": "0000", - "name": "6.18", - "value": 0 - }, - "serial": "0000:05:00.0", - "model": "Linux 6.18.44 xhci-hcd xHCI Host Controller", - "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:05:00.0/usb1/1-0:1.0", - "sysfs_bus_id": "1-0:1.0", - "resources": [ - { - "type": "baud", - "speed": 480000000, - "bits": 0, - "stop_bits": 0, - "parity": 0, - "handshake": 0 - } - ], - "detail": { - "device_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "device_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "device_protocol": 1, - "interface_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "interface_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "interface_protocol": 0, - "interface_number": 0, - "interface_alternate_setting": 0 - }, - "hotplug": "usb", - "driver": "hub", - "driver_module": "usbcore", - "drivers": ["hub"], - "driver_modules": ["usbcore"], - "module_alias": "usb:v1D6Bp0002d0618dc09dsc00dp01ic09isc00ip00in00" - }, - { - "index": 87, - "attached_to": 40, - "class_list": ["usb", "hub"], - "bus_type": { - "hex": "0086", - "name": "USB", - "value": 134 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "010a", - "name": "Hub", - "value": 266 - }, - "vendor": { - "hex": "1d6b", - "name": "Linux 6.18.44 xhci-hcd", - "value": 7531 - }, - "device": { - "hex": "0002", - "name": "xHCI Host Controller", - "value": 2 - }, - "revision": { - "hex": "0000", - "name": "6.18", - "value": 0 - }, - "serial": "0000:10:00.4", - "model": "Linux 6.18.44 xhci-hcd xHCI Host Controller", - "sysfs_id": "/devices/pci0000:00/0000:00:08.1/0000:10:00.4/usb5/5-0:1.0", - "sysfs_bus_id": "5-0:1.0", - "resources": [ - { - "type": "baud", - "speed": 480000000, - "bits": 0, - "stop_bits": 0, - "parity": 0, - "handshake": 0 - } - ], - "detail": { - "device_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "device_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "device_protocol": 1, - "interface_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "interface_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "interface_protocol": 0, - "interface_number": 0, - "interface_alternate_setting": 0 - }, - "hotplug": "usb", - "driver": "hub", - "driver_module": "usbcore", - "drivers": ["hub"], - "driver_modules": ["usbcore"], - "module_alias": "usb:v1D6Bp0002d0618dc09dsc00dp01ic09isc00ip00in00" - }, - { - "index": 88, - "attached_to": 47, - "class_list": ["usb", "hub"], - "bus_type": { - "hex": "0086", - "name": "USB", - "value": 134 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "010a", - "name": "Hub", - "value": 266 - }, - "vendor": { - "hex": "1d6b", - "name": "Linux 6.18.44 xhci-hcd", - "value": 7531 - }, - "device": { - "hex": "0003", - "name": "xHCI Host Controller", - "value": 3 - }, - "revision": { - "hex": "0000", - "name": "6.18", - "value": 0 - }, - "serial": "0000:05:00.0", - "model": "Linux 6.18.44 xhci-hcd xHCI Host Controller", - "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:05:00.0/usb2/2-0:1.0", - "sysfs_bus_id": "2-0:1.0", - "detail": { - "device_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "device_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "device_protocol": 3, - "interface_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "interface_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "interface_protocol": 0, - "interface_number": 0, - "interface_alternate_setting": 0 - }, - "hotplug": "usb", - "driver": "hub", - "driver_module": "usbcore", - "drivers": ["hub"], - "driver_modules": ["usbcore"], - "module_alias": "usb:v1D6Bp0003d0618dc09dsc00dp03ic09isc00ip00in00" - } - ], - "memory": [ - { - "index": 15, - "attached_to": 0, - "class_list": ["memory"], - "base_class": { - "hex": "0101", - "name": "Internally Used Class", - "value": 257 - }, - "sub_class": { - "hex": "0002", - "name": "Main Memory", - "value": 2 - }, - "model": "Main Memory", - "resources": [ - { - "type": "phys_mem", - "range": 32212254720 - } - ] - } - ], - "network_controller": [ - { - "index": 26, - "attached_to": 27, - "class_list": ["network_controller", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 8, - "number": 0 - }, - "base_class": { - "hex": "0002", - "name": "Network controller", - "value": 2 - }, - "sub_class": { - "hex": "0000", - "name": "Ethernet controller", - "value": 0 - }, - "vendor": { - "hex": "10ec", - "value": 4332 - }, - "sub_vendor": { - "hex": "1565", - "value": 5477 - }, - "device": { - "hex": "8168", - "value": 33128 - }, - "sub_device": { - "hex": "2313", - "value": 8979 - }, - "revision": { - "hex": "0016", - "value": 22 - }, - "model": "Ethernet controller", - "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:05:00.2/0000:06:01.0/0000:08:00.0", - "sysfs_bus_id": "0000:08:00.0", - "unix_device_names": ["enp8s0"], - "resources": [ - { - "type": "hwaddr", - "address": 98 - }, - { - "type": "io", - "base": 61440, - "range": 256, - "enabled": true, - "access": "read_write" - }, - { - "type": "phwaddr", - "address": 98 - } - ], - "detail": { - "function": 0, - "command": 1031, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "r8169", - "driver_module": "r8169", - "drivers": ["r8169"], - "driver_modules": ["r8169"], - "module_alias": "pci:v000010ECd00008168sv00001565sd00002313bc02sc00i00" - }, - { - "index": 84, - "attached_to": 82, - "class_list": ["network_controller", "usb"], - "bus_type": { - "hex": "0086", - "name": "USB", - "value": 134 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "0002", - "name": "Network controller", - "value": 2 - }, - "sub_class": { - "hex": "0000", - "name": "Ethernet controller", - "value": 0 - }, - "vendor": { - "hex": "0bda", - "name": "Realtek", - "value": 3034 - }, - "device": { - "hex": "8156", - "name": "USB 10/100/1G/2.5G LAN", - "value": 33110 - }, - "revision": { - "hex": "0000", - "name": "31.f4", - "value": 0 - }, - "serial": "4F13000001", - "model": "Realtek USB 10/100/1G/2.5G LAN", - "sysfs_id": "/devices/pci0000:00/0000:00:08.1/0000:10:00.4/usb6/6-1/6-1:1.0", - "sysfs_bus_id": "6-1:1.0", - "unix_device_names": ["enp16s0f4u1"], - "resources": [ - { - "type": "hwaddr", - "address": 54 - }, - { - "type": "phwaddr", - "address": 54 - } - ], - "detail": { - "device_class": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "device_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "device_protocol": 0, - "interface_class": { - "hex": "00ff", - "name": "vendor_spec", - "value": 255 - }, - "interface_subclass": { - "hex": "00ff", - "name": "vendor_spec", - "value": 255 - }, - "interface_protocol": 0, - "interface_number": 0, - "interface_alternate_setting": 0 - }, - "hotplug": "usb", - "driver": "r8152", - "driver_module": "r8152", - "drivers": ["r8152"], - "driver_modules": ["r8152"], - "module_alias": "usb:v0BDAp8156d31F4dc00dsc00dp00icFFiscFFip00in00" - } - ], - "network_interface": [ - { - "index": 103, - "attached_to": 84, - "class_list": ["network_interface"], - "base_class": { - "hex": "0107", - "name": "Network Interface", - "value": 263 - }, - "sub_class": { - "hex": "0001", - "name": "Ethernet", - "value": 1 - }, - "model": "Ethernet network interface", - "sysfs_id": "/class/net/enp16s0f4u1", - "sysfs_device_link": "/devices/pci0000:00/0000:00:08.1/0000:10:00.4/usb6/6-1/6-1:1.0", - "unix_device_names": ["enp16s0f4u1"], - "resources": [ - { - "type": "hwaddr", - "address": 54 - }, - { - "type": "phwaddr", - "address": 54 - } - ], - "driver": "r8152", - "driver_module": "r8152", - "drivers": ["r8152"], - "driver_modules": ["r8152"] - }, - { - "index": 108, - "attached_to": 26, - "class_list": ["network_interface"], - "base_class": { - "hex": "0107", - "name": "Network Interface", - "value": 263 - }, - "sub_class": { - "hex": "0001", - "name": "Ethernet", - "value": 1 - }, - "model": "Ethernet network interface", - "sysfs_id": "/class/net/enp8s0", - "sysfs_device_link": "/devices/pci0000:00/0000:00:02.1/0000:05:00.2/0000:06:01.0/0000:08:00.0", - "unix_device_names": ["enp8s0"], - "resources": [ - { - "type": "hwaddr", - "address": 98 - }, - { - "type": "phwaddr", - "address": 98 - } - ], - "driver": "r8169", - "driver_module": "r8169", - "drivers": ["r8169"], - "driver_modules": ["r8169"] - }, - { - "index": 132, - "attached_to": 0, - "class_list": ["network_interface"], - "base_class": { - "hex": "0107", - "name": "Network Interface", - "value": 263 - }, - "sub_class": { - "hex": "0000", - "name": "Loopback", - "value": 0 - }, - "model": "Loopback network interface", - "sysfs_id": "/class/net/lo", - "unix_device_names": ["lo"] - } - ], - "pci": [ - { - "index": 46, - "attached_to": 36, - "class_list": ["pci", "unknown"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 16, - "number": 0 - }, - "base_class": { - "hex": "0010", - "name": "Encryption controller", - "value": 16 - }, - "sub_class": { - "hex": "0080", - "name": "Encryption controller", - "value": 128 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "device": { - "hex": "15df", - "value": 5599 - }, - "sub_device": { - "hex": "15df", - "value": 5599 - }, - "model": "AMD Encryption controller", - "sysfs_id": "/devices/pci0000:00/0000:00:08.1/0000:10:00.2", - "sysfs_bus_id": "0000:10:00.2", - "detail": { - "function": 2, - "command": 1030, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "ccp", - "driver_module": "ccp", - "drivers": ["ccp"], - "driver_modules": ["ccp"], - "module_alias": "pci:v00001022d000015DFsv00001022sd000015DFbc10sc80i00" - }, - { - "index": 50, - "attached_to": 36, - "class_list": ["pci", "unknown"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 16, - "number": 0 - }, - "base_class": { - "hex": "0013", - "value": 19 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1565", - "value": 5477 - }, - "device": { - "hex": "145a", - "value": 5210 - }, - "sub_device": { - "hex": "170b", - "value": 5899 - }, - "revision": { - "hex": "00c9", - "value": 201 - }, - "model": "unknown unknown", - "sysfs_id": "/devices/pci0000:00/0000:00:08.1/0000:10:00.0", - "sysfs_bus_id": "0000:10:00.0", - "detail": { - "function": 0, - "command": 0, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00001022d0000145Asv00001565sd0000170Bbc13sc00i00" - }, - { - "index": 56, - "attached_to": 0, - "class_list": ["pci", "unknown"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 20 - }, - "base_class": { - "hex": "000c", - "name": "Serial bus controller", - "value": 12 - }, - "sub_class": { - "hex": "0005", - "name": "SMBus", - "value": 5 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1565", - "value": 5477 - }, - "device": { - "hex": "790b", - "value": 30987 - }, - "sub_device": { - "hex": "370b", - "value": 14091 - }, - "revision": { - "hex": "0051", - "value": 81 - }, - "model": "AMD SMBus", - "sysfs_id": "/devices/pci0000:00/0000:00:14.0", - "sysfs_bus_id": "0000:00:14.0", - "detail": { - "function": 0, - "command": 1027, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "piix4_smbus", - "driver_module": "i2c_piix4", - "drivers": ["piix4_smbus"], - "driver_modules": ["i2c_piix4"], - "module_alias": "pci:v00001022d0000790Bsv00001565sd0000370Bbc0Csc05i00" - } - ], - "scsi": [ - { - "index": 77, - "attached_to": 61, - "class_list": ["scsi", "block_device", "unknown"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 13, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0080", - "name": "Storage Device", - "value": 128 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "Controller", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "model": "IET Controller", - "sysfs_id": "/class/scsi_generic/sg6", - "sysfs_bus_id": "13:0:0:0", - "unix_device_names": ["/dev/sg6"], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"] - }, - { - "index": 78, - "attached_to": 65, - "class_list": ["scsi", "block_device", "unknown"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 12, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0080", - "name": "Storage Device", - "value": 128 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "Controller", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "model": "IET Controller", - "sysfs_id": "/class/scsi_generic/sg4", - "sysfs_bus_id": "12:0:0:0", - "unix_device_names": ["/dev/sg4"], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"] - }, - { - "index": 79, - "attached_to": 62, - "class_list": ["scsi", "block_device", "unknown"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 16, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0080", - "name": "Storage Device", - "value": 128 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "Controller", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "model": "IET Controller", - "sysfs_id": "/class/scsi_generic/sg12", - "sysfs_bus_id": "16:0:0:0", - "unix_device_names": ["/dev/sg12"], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"] - }, - { - "index": 80, - "attached_to": 64, - "class_list": ["scsi", "block_device", "unknown"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 15, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0080", - "name": "Storage Device", - "value": 128 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "Controller", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "model": "IET Controller", - "sysfs_id": "/class/scsi_generic/sg10", - "sysfs_bus_id": "15:0:0:0", - "unix_device_names": ["/dev/sg10"], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"] - }, - { - "index": 81, - "attached_to": 63, - "class_list": ["scsi", "block_device", "unknown"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 14, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0080", - "name": "Storage Device", - "value": 128 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "Controller", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "model": "IET Controller", - "sysfs_id": "/class/scsi_generic/sg8", - "sysfs_bus_id": "14:0:0:0", - "unix_device_names": ["/dev/sg8"], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"] - } - ], - "sound": [ - { - "index": 25, - "attached_to": 36, - "class_list": ["sound", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 16, - "number": 0 - }, - "base_class": { - "hex": "0004", - "name": "Multimedia controller", - "value": 4 - }, - "sub_class": { - "hex": "0003", - "value": 3 - }, - "vendor": { - "hex": "1002", - "name": "ATI Technologies Inc", - "value": 4098 - }, - "sub_vendor": { - "hex": "1002", - "name": "ATI Technologies Inc", - "value": 4098 - }, - "device": { - "hex": "1637", - "value": 5687 - }, - "sub_device": { - "hex": "1637", - "value": 5687 - }, - "model": "ATI Multimedia controller", - "sysfs_id": "/devices/pci0000:00/0000:00:08.1/0000:10:00.1", - "sysfs_bus_id": "0000:10:00.1", - "detail": { - "function": 1, - "command": 1030, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "snd_hda_intel", - "driver_module": "snd_hda_intel", - "drivers": ["snd_hda_intel"], - "driver_modules": ["snd_hda_intel"], - "module_alias": "pci:v00001002d00001637sv00001002sd00001637bc04sc03i00" - }, - { - "index": 34, - "attached_to": 36, - "class_list": ["sound", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 16, - "number": 0 - }, - "base_class": { - "hex": "0004", - "name": "Multimedia controller", - "value": 4 - }, - "sub_class": { - "hex": "0003", - "value": 3 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1565", - "value": 5477 - }, - "device": { - "hex": "15e3", - "value": 5603 - }, - "sub_device": { - "hex": "8240", - "value": 33344 - }, - "model": "AMD Multimedia controller", - "sysfs_id": "/devices/pci0000:00/0000:00:08.1/0000:10:00.6", - "sysfs_bus_id": "0000:10:00.6", - "detail": { - "function": 6, - "command": 1030, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "snd_hda_intel", - "driver_module": "snd_hda_intel", - "drivers": ["snd_hda_intel"], - "driver_modules": ["snd_hda_intel"], - "module_alias": "pci:v00001022d000015E3sv00001565sd00008240bc04sc03i00" - }, - { - "index": 52, - "attached_to": 58, - "class_list": ["sound", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 4, - "number": 0 - }, - "base_class": { - "hex": "0004", - "name": "Multimedia controller", - "value": 4 - }, - "sub_class": { - "hex": "0003", - "value": 3 - }, - "vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "sub_vendor": { - "hex": "172f", - "value": 5935 - }, - "device": { - "hex": "4f92", - "value": 20370 - }, - "sub_device": { - "hex": "4240", - "value": 16960 - }, - "model": "Intel Multimedia controller", - "sysfs_id": "/devices/pci0000:00/0000:00:01.1/0000:01:00.0/0000:02:04.0/0000:04:00.0", - "sysfs_bus_id": "0000:04:00.0", - "detail": { - "function": 0, - "command": 1030, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "snd_hda_intel", - "driver_module": "snd_hda_intel", - "drivers": ["snd_hda_intel"], - "driver_modules": ["snd_hda_intel"], - "module_alias": "pci:v00008086d00004F92sv0000172Fsd00004240bc04sc03i00" - } - ], - "storage_controller": [ - { - "index": 19, - "attached_to": 59, - "class_list": ["storage_controller", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 17, - "number": 0 - }, - "base_class": { - "hex": "0001", - "name": "Mass storage controller", - "value": 1 - }, - "sub_class": { - "hex": "0006", - "value": 6 - }, - "pci_interface": { - "hex": "0001", - "value": 1 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1565", - "value": 5477 - }, - "device": { - "hex": "7901", - "value": 30977 - }, - "sub_device": { - "hex": "550d", - "value": 21773 - }, - "revision": { - "hex": "0081", - "value": 129 - }, - "model": "AMD Mass storage controller", - "sysfs_id": "/devices/pci0000:00/0000:00:08.2/0000:11:00.1", - "sysfs_bus_id": "0000:11:00.1", - "detail": { - "function": 1, - "command": 1031, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 1 - }, - "driver": "ahci", - "driver_module": "ahci", - "drivers": ["ahci"], - "driver_modules": ["ahci"], - "module_alias": "pci:v00001022d00007901sv00001565sd0000550Dbc01sc06i01" - }, - { - "index": 22, - "attached_to": 30, - "class_list": ["storage_controller", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 5, - "number": 0 - }, - "base_class": { - "hex": "0001", - "name": "Mass storage controller", - "value": 1 - }, - "sub_class": { - "hex": "0006", - "value": 6 - }, - "pci_interface": { - "hex": "0001", - "value": 1 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1b21", - "value": 6945 - }, - "device": { - "hex": "43b5", - "value": 17333 - }, - "sub_device": { - "hex": "1062", - "value": 4194 - }, - "revision": { - "hex": "0002", - "value": 2 - }, - "model": "AMD Mass storage controller", - "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:05:00.1", - "sysfs_bus_id": "0000:05:00.1", - "detail": { - "function": 1, - "command": 1030, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 1 - }, - "driver": "ahci", - "driver_module": "ahci", - "drivers": ["ahci"], - "driver_modules": ["ahci"], - "module_alias": "pci:v00001022d000043B5sv00001B21sd00001062bc01sc06i01" - }, - { - "index": 39, - "attached_to": 51, - "class_list": ["storage_controller", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 15, - "number": 0 - }, - "base_class": { - "hex": "0001", - "name": "Mass storage controller", - "value": 1 - }, - "sub_class": { - "hex": "0008", - "value": 8 - }, - "pci_interface": { - "hex": "0002", - "value": 2 - }, - "vendor": { - "hex": "1987", - "value": 6535 - }, - "sub_vendor": { - "hex": "1987", - "value": 6535 - }, - "device": { - "hex": "5012", - "value": 20498 - }, - "sub_device": { - "hex": "5012", - "value": 20498 - }, - "revision": { - "hex": "0001", - "value": 1 - }, - "model": "Mass storage controller", - "sysfs_id": "/devices/pci0000:00/0000:00:02.2/0000:0f:00.0", - "sysfs_bus_id": "0000:0f:00.0", - "detail": { - "function": 0, - "command": 1030, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 2 - }, - "driver": "nvme", - "driver_module": "nvme", - "drivers": ["nvme"], - "driver_modules": ["nvme"], - "module_alias": "pci:v00001987d00005012sv00001987sd00005012bc01sc08i02" - }, - { - "index": 41, - "attached_to": 59, - "class_list": ["storage_controller", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 17, - "number": 0 - }, - "base_class": { - "hex": "0001", - "name": "Mass storage controller", - "value": 1 - }, - "sub_class": { - "hex": "0006", - "value": 6 - }, - "pci_interface": { - "hex": "0001", - "value": 1 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1565", - "value": 5477 - }, - "device": { - "hex": "7901", - "value": 30977 - }, - "sub_device": { - "hex": "550d", - "value": 21773 - }, - "revision": { - "hex": "0081", - "value": 129 - }, - "model": "AMD Mass storage controller", - "sysfs_id": "/devices/pci0000:00/0000:00:08.2/0000:11:00.0", - "sysfs_bus_id": "0000:11:00.0", - "detail": { - "function": 0, - "command": 1031, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 1 - }, - "driver": "ahci", - "driver_module": "ahci", - "drivers": ["ahci"], - "driver_modules": ["ahci"], - "module_alias": "pci:v00001022d00007901sv00001565sd0000550Dbc01sc06i01" - }, - { - "index": 61, - "attached_to": 0, - "class_list": ["storage_controller"], - "base_class": { - "hex": "011a", - "name": "iSCSI controller", - "value": 282 - }, - "vendor": "", - "device": "iSCSI controller", - "model": "iSCSI controller", - "sysfs_id": "/devices/platform/host13/session8", - "sysfs_bus_id": "session8", - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"], - "driver_info": { - "type": "module", - "db_entry_0": ["iscsi-tcp"], - "active": true, - "modprobe": true, - "names": ["iscsi-tcp"], - "module_args": [""], - "conf": "" - } - }, - { - "index": 62, - "attached_to": 0, - "class_list": ["storage_controller"], - "base_class": { - "hex": "011a", - "name": "iSCSI controller", - "value": 282 - }, - "vendor": "", - "device": "iSCSI controller", - "model": "iSCSI controller", - "sysfs_id": "/devices/platform/host16/session11", - "sysfs_bus_id": "session11", - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"], - "driver_info": { - "type": "module", - "db_entry_0": ["iscsi-tcp"], - "active": true, - "modprobe": true, - "names": ["iscsi-tcp"], - "module_args": [""], - "conf": "" - } - }, - { - "index": 63, - "attached_to": 0, - "class_list": ["storage_controller"], - "base_class": { - "hex": "011a", - "name": "iSCSI controller", - "value": 282 - }, - "vendor": "", - "device": "iSCSI controller", - "model": "iSCSI controller", - "sysfs_id": "/devices/platform/host14/session9", - "sysfs_bus_id": "session9", - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"], - "driver_info": { - "type": "module", - "db_entry_0": ["iscsi-tcp"], - "active": true, - "modprobe": true, - "names": ["iscsi-tcp"], - "module_args": [""], - "conf": "" - } - }, - { - "index": 64, - "attached_to": 0, - "class_list": ["storage_controller"], - "base_class": { - "hex": "011a", - "name": "iSCSI controller", - "value": 282 - }, - "vendor": "", - "device": "iSCSI controller", - "model": "iSCSI controller", - "sysfs_id": "/devices/platform/host15/session10", - "sysfs_bus_id": "session10", - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"], - "driver_info": { - "type": "module", - "db_entry_0": ["iscsi-tcp"], - "active": true, - "modprobe": true, - "names": ["iscsi-tcp"], - "module_args": [""], - "conf": "" - } - }, - { - "index": 65, - "attached_to": 0, - "class_list": ["storage_controller"], - "base_class": { - "hex": "011a", - "name": "iSCSI controller", - "value": 282 - }, - "vendor": "", - "device": "iSCSI controller", - "model": "iSCSI controller", - "sysfs_id": "/devices/platform/host12/session1", - "sysfs_bus_id": "session1", - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"], - "driver_info": { - "type": "module", - "db_entry_0": ["iscsi-tcp"], - "active": true, - "modprobe": true, - "names": ["iscsi-tcp"], - "module_args": [""], - "conf": "" - } - } - ], - "system": { - "form_factor": "desktop" - }, - "usb_controller": [ - { - "index": 21, - "attached_to": 36, - "class_list": ["usb_controller", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 16, - "number": 0 - }, - "base_class": { - "hex": "000c", - "name": "Serial bus controller", - "value": 12 - }, - "sub_class": { - "hex": "0003", - "name": "USB Controller", - "value": 3 - }, - "pci_interface": { - "hex": "0030", - "value": 48 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1565", - "value": 5477 - }, - "device": { - "hex": "1639", - "value": 5689 - }, - "sub_device": { - "hex": "370b", - "value": 14091 - }, - "model": "AMD USB Controller", - "sysfs_id": "/devices/pci0000:00/0000:00:08.1/0000:10:00.3", - "sysfs_bus_id": "0000:10:00.3", - "detail": { - "function": 3, - "command": 1031, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 48 - }, - "driver": "xhci_hcd", - "driver_module": "xhci_pci", - "drivers": ["xhci_hcd"], - "driver_modules": ["xhci_pci"], - "module_alias": "pci:v00001022d00001639sv00001565sd0000370Bbc0Csc03i30" - }, - { - "index": 40, - "attached_to": 36, - "class_list": ["usb_controller", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 16, - "number": 0 - }, - "base_class": { - "hex": "000c", - "name": "Serial bus controller", - "value": 12 - }, - "sub_class": { - "hex": "0003", - "name": "USB Controller", - "value": 3 - }, - "pci_interface": { - "hex": "0030", - "value": 48 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1565", - "value": 5477 - }, - "device": { - "hex": "1639", - "value": 5689 - }, - "sub_device": { - "hex": "370b", - "value": 14091 - }, - "model": "AMD USB Controller", - "sysfs_id": "/devices/pci0000:00/0000:00:08.1/0000:10:00.4", - "sysfs_bus_id": "0000:10:00.4", - "detail": { - "function": 4, - "command": 1031, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 48 - }, - "driver": "xhci_hcd", - "driver_module": "xhci_pci", - "drivers": ["xhci_hcd"], - "driver_modules": ["xhci_pci"], - "module_alias": "pci:v00001022d00001639sv00001565sd0000370Bbc0Csc03i30" - }, - { - "index": 47, - "attached_to": 30, - "class_list": ["usb_controller", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 5, - "number": 0 - }, - "base_class": { - "hex": "000c", - "name": "Serial bus controller", - "value": 12 - }, - "sub_class": { - "hex": "0003", - "name": "USB Controller", - "value": 3 - }, - "pci_interface": { - "hex": "0030", - "value": 48 - }, - "vendor": { - "hex": "1022", - "name": "AMD", - "value": 4130 - }, - "sub_vendor": { - "hex": "1b21", - "value": 6945 - }, - "device": { - "hex": "43b9", - "value": 17337 - }, - "sub_device": { - "hex": "1142", - "value": 4418 - }, - "revision": { - "hex": "0002", - "value": 2 - }, - "model": "AMD USB Controller", - "sysfs_id": "/devices/pci0000:00/0000:00:02.1/0000:05:00.0", - "sysfs_bus_id": "0000:05:00.0", - "detail": { - "function": 0, - "command": 1030, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 48 - }, - "driver": "xhci_hcd", - "driver_module": "xhci_pci", - "drivers": ["xhci_hcd"], - "driver_modules": ["xhci_pci"], - "module_alias": "pci:v00001022d000043B9sv00001B21sd00001142bc0Csc03i30" - } - ] - }, - "smbios": { - "bios": { - "handle": 0, - "vendor": "American Megatrends International, LLC.", - "version": "5.17", - "date": "05/23/2022", - "features": [ - "PCI supported", - "BIOS flashable", - "BIOS shadowing allowed", - "CD boot supported", - "Selectable boot supported", - "BIOS ROM socketed", - "EDD spec supported", - "1.2MB NEC 9800 Japanese Floppy supported", - "1.2MB Toshiba Japanese Floppy supported", - "360kB Floppy supported", - "1.2MB Floppy supported", - "720kB Floppy supported", - "2.88MB Floppy supported", - "Print Screen supported", - "8042 Keyboard Services supported", - "Serial Services supported", - "Printer Services supported", - "CGA/Mono Video supported", - "ACPI supported", - "USB Legacy supported", - "BIOS Boot Spec supported" - ], - "start_address": "0xf0000", - "rom_size": 16777216 - }, - "board": { - "handle": 2, - "manufacturer": "BIOSTAR Group", - "product": "X370GTN", - "version": "", - "board_type": { - "hex": "000a", - "name": "Motherboard", - "value": 10 - }, - "features": ["Hosting Board", "Replaceable"], - "location": "None", - "chassis": 3 - }, - "cache": [ - { - "handle": 18, - "socket": "L1 - Cache", - "size_max": 384, - "size_current": 384, - "speed": 1, - "mode": { - "hex": "0001", - "name": "Write Back", - "value": 1 - }, - "enabled": true, - "location": { - "hex": "0000", - "name": "Internal", - "value": 0 - }, - "socketed": false, - "level": 0, - "ecc": { - "hex": "0006", - "name": "Multi-bit", - "value": 6 - }, - "cache_type": { - "hex": "0005", - "name": "Unified", - "value": 5 - }, - "associativity": { - "hex": "0007", - "name": "8-way Set-Associative", - "value": 7 - }, - "sram_type_current": ["Pipeline Burst"], - "sram_type_supported": ["Pipeline Burst"] - }, - { - "handle": 19, - "socket": "L2 - Cache", - "size_max": 3072, - "size_current": 3072, - "speed": 1, - "mode": { - "hex": "0001", - "name": "Write Back", - "value": 1 - }, - "enabled": true, - "location": { - "hex": "0000", - "name": "Internal", - "value": 0 - }, - "socketed": false, - "level": 1, - "ecc": { - "hex": "0006", - "name": "Multi-bit", - "value": 6 - }, - "cache_type": { - "hex": "0005", - "name": "Unified", - "value": 5 - }, - "associativity": { - "hex": "0007", - "name": "8-way Set-Associative", - "value": 7 - }, - "sram_type_current": ["Pipeline Burst"], - "sram_type_supported": ["Pipeline Burst"] - }, - { - "handle": 20, - "socket": "L3 - Cache", - "size_max": 16384, - "size_current": 16384, - "speed": 1, - "mode": { - "hex": "0001", - "name": "Write Back", - "value": 1 - }, - "enabled": true, - "location": { - "hex": "0000", - "name": "Internal", - "value": 0 - }, - "socketed": false, - "level": 2, - "ecc": { - "hex": "0006", - "name": "Multi-bit", - "value": 6 - }, - "cache_type": { - "hex": "0005", - "name": "Unified", - "value": 5 - }, - "associativity": { - "hex": "0008", - "name": "16-way Set-Associative", - "value": 8 - }, - "sram_type_current": ["Pipeline Burst"], - "sram_type_supported": ["Pipeline Burst"] - } - ], - "chassis": [ - { - "handle": 3, - "manufacturer": "BIOSTAR Group", - "version": "", - "chassis_type": { - "hex": "0003", - "name": "Desktop", - "value": 3 - }, - "lock_present": false, - "bootup_state": { - "hex": "0003", - "name": "Safe", - "value": 3 - }, - "power_state": { - "hex": "0003", - "name": "Safe", - "value": 3 - }, - "thermal_state": { - "hex": "0003", - "name": "Safe", - "value": 3 - }, - "security_state": { - "hex": "0003", - "name": "None", - "value": 3 - }, - "oem": "0x0" - } - ], - "language": [ - { - "handle": 28, - "languages": ["en|US|iso8859-1", "zh|CN|unicode"] - } - ], - "memory_array": [ - { - "handle": 16, - "location": { - "hex": "0003", - "name": "Motherboard", - "value": 3 - }, - "usage": { - "hex": "0003", - "name": "System memory", - "value": 3 - }, - "ecc": { - "hex": "0003", - "name": "None", - "value": 3 - }, - "max_size": "0x8000000", - "error_handle": 15, - "slots": 2 - } - ], - "memory_array_mapped_address": [ - { - "handle": 17, - "array_handle": 16, - "start_address": "0x0", - "end_address": "0x800000000", - "part_width": 2 - } - ], - "memory_device": [ - { - "handle": 23, - "location": "DIMM 0", - "bank_location": "P0 CHANNEL A", - "manufacturer": "Crucial Technology", - "part_number": "CP16G4DFRA32A.C8FF", - "array_handle": 16, - "error_handle": 22, - "width": 64, - "ecc_bits": 0, - "size": 16777216, - "form_factor": { - "hex": "0009", - "name": "DIMM", - "value": 9 - }, - "set": 0, - "memory_type": { - "hex": "001a", - "name": "Other", - "value": 26 - }, - "memory_type_details": ["Synchronous"], - "speed": 3200 - }, - { - "handle": 26, - "location": "DIMM 0", - "bank_location": "P0 CHANNEL B", - "manufacturer": "Crucial Technology", - "part_number": "CP16G4DFRA32A.C8FF", - "array_handle": 16, - "error_handle": 25, - "width": 64, - "ecc_bits": 0, - "size": 16777216, - "form_factor": { - "hex": "0009", - "name": "DIMM", - "value": 9 - }, - "set": 0, - "memory_type": { - "hex": "001a", - "name": "Other", - "value": 26 - }, - "memory_type_details": ["Synchronous"], - "speed": 3200 - } - ], - "memory_device_mapped_address": [ - { - "handle": 24, - "memory_device_handle": 23, - "array_map_handle": 17, - "start_address": "0x0", - "end_address": "0x800000000", - "row_position": 255, - "interleave_position": 255, - "interleave_depth": 255 - }, - { - "handle": 27, - "memory_device_handle": 26, - "array_map_handle": 17, - "start_address": "0x0", - "end_address": "0x800000000", - "row_position": 255, - "interleave_position": 255, - "interleave_depth": 255 - } - ], - "memory_error": [ - { - "handle": 15, - "error_type": { - "hex": "0003", - "name": "OK", - "value": 3 - }, - "granularity": { - "hex": "0002", - "name": "Unknown", - "value": 2 - }, - "operation": { - "hex": "0002", - "name": "Unknown", - "value": 2 - }, - "syndrome": 0, - "array_address": "0x80000000", - "device_address": "0x80000000", - "range": 2147483648 - }, - { - "handle": 22, - "error_type": { - "hex": "0003", - "name": "OK", - "value": 3 - }, - "granularity": { - "hex": "0002", - "name": "Unknown", - "value": 2 - }, - "operation": { - "hex": "0002", - "name": "Unknown", - "value": 2 - }, - "syndrome": 0, - "array_address": "0x80000000", - "device_address": "0x80000000", - "range": 2147483648 - }, - { - "handle": 25, - "error_type": { - "hex": "0003", - "name": "OK", - "value": 3 - }, - "granularity": { - "hex": "0002", - "name": "Unknown", - "value": 2 - }, - "operation": { - "hex": "0002", - "name": "Unknown", - "value": 2 - }, - "syndrome": 0, - "array_address": "0x80000000", - "device_address": "0x80000000", - "range": 2147483648 - } - ], - "processor": [ - { - "handle": 21, - "socket": "AM4", - "socket_type": { - "hex": "0031", - "name": "Other", - "value": 49 - }, - "socket_populated": true, - "manufacturer": "Advanced Micro Devices, Inc.", - "version": "AMD Ryzen 5 5600GT with Radeon Graphics", - "part": "Unknown", - "processor_type": { - "hex": "0003", - "name": "CPU", - "value": 3 - }, - "processor_family": { - "hex": "006b", - "name": "Other", - "value": 107 - }, - "processor_status": { - "hex": "0001", - "name": "Enabled", - "value": 1 - }, - "clock_ext": 100, - "clock_max": 4650, - "cache_handle_l1": 18, - "cache_handle_l2": 19, - "cache_handle_l3": 20 - } - ], - "slot": [ - { - "handle": 4, - "designation": "J6B2", - "slot_type": { - "hex": "00a5", - "name": "Other", - "value": 165 - }, - "bus_width": { - "hex": "000d", - "name": "Other", - "value": 13 - }, - "usage": { - "hex": "0004", - "name": "In Use", - "value": 4 - }, - "length": { - "hex": "0004", - "name": "Long", - "value": 4 - }, - "id": 0, - "features": ["3.3 V", "Shared", "PME#"] - }, - { - "handle": 5, - "designation": "J6B1", - "slot_type": { - "hex": "00a5", - "name": "Other", - "value": 165 - }, - "bus_width": { - "hex": "0008", - "name": "Other", - "value": 8 - }, - "usage": { - "hex": "0004", - "name": "In Use", - "value": 4 - }, - "length": { - "hex": "0003", - "name": "Short", - "value": 3 - }, - "id": 1, - "features": ["3.3 V", "Shared", "PME#"] - }, - { - "handle": 6, - "designation": "J6D1", - "slot_type": { - "hex": "00a5", - "name": "Other", - "value": 165 - }, - "bus_width": { - "hex": "0008", - "name": "Other", - "value": 8 - }, - "usage": { - "hex": "0004", - "name": "In Use", - "value": 4 - }, - "length": { - "hex": "0003", - "name": "Short", - "value": 3 - }, - "id": 2, - "features": ["3.3 V", "Shared", "PME#"] - }, - { - "handle": 7, - "designation": "J7B1", - "slot_type": { - "hex": "00a5", - "name": "Other", - "value": 165 - }, - "bus_width": { - "hex": "0008", - "name": "Other", - "value": 8 - }, - "usage": { - "hex": "0004", - "name": "In Use", - "value": 4 - }, - "length": { - "hex": "0003", - "name": "Short", - "value": 3 - }, - "id": 3, - "features": ["3.3 V", "Shared", "PME#"] - }, - { - "handle": 8, - "designation": "J8B4", - "slot_type": { - "hex": "00a5", - "name": "Other", - "value": 165 - }, - "bus_width": { - "hex": "0008", - "name": "Other", - "value": 8 - }, - "usage": { - "hex": "0004", - "name": "In Use", - "value": 4 - }, - "length": { - "hex": "0003", - "name": "Short", - "value": 3 - }, - "id": 4, - "features": ["3.3 V", "Shared", "PME#"] - }, - { - "handle": 9, - "designation": "J8D1", - "slot_type": { - "hex": "00a5", - "name": "Other", - "value": 165 - }, - "bus_width": { - "hex": "0008", - "name": "Other", - "value": 8 - }, - "usage": { - "hex": "0004", - "name": "In Use", - "value": 4 - }, - "length": { - "hex": "0003", - "name": "Short", - "value": 3 - }, - "id": 5, - "features": ["3.3 V", "Shared", "PME#"] - }, - { - "handle": 10, - "designation": "J8B3", - "slot_type": { - "hex": "0006", - "name": "PCI", - "value": 6 - }, - "bus_width": { - "hex": "0005", - "name": "32 bit", - "value": 5 - }, - "usage": { - "hex": "0004", - "name": "In Use", - "value": 4 - }, - "length": { - "hex": "0003", - "name": "Short", - "value": 3 - }, - "id": 6, - "features": ["3.3 V", "Shared", "PME#"] - }, - { - "handle": 11, - "designation": "J9B1", - "slot_type": { - "hex": "0006", - "name": "PCI", - "value": 6 - }, - "bus_width": { - "hex": "0005", - "name": "32 bit", - "value": 5 - }, - "usage": { - "hex": "0004", - "name": "In Use", - "value": 4 - }, - "length": { - "hex": "0003", - "name": "Short", - "value": 3 - }, - "id": 7, - "features": ["3.3 V", "Shared", "PME#"] - } - ], - "system": { - "handle": 1, - "manufacturer": "BIOSTAR Group", - "product": "X370GTN", - "version": "", - "wake_up": { - "hex": "0006", - "name": "Power Switch", - "value": 6 - } - } - } -} diff --git a/nix/modules/hosts/nixos/jubilife/facter.nix b/nix/modules/hosts/nixos/jubilife/facter.nix deleted file mode 100644 index ce357a84..00000000 --- a/nix/modules/hosts/nixos/jubilife/facter.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.jubilife = {self, ...}: { - hardware.facter.reportPath = self + "/nix/modules/hosts/nixos/jubilife/facter.json"; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/firewall.nix b/nix/modules/hosts/nixos/jubilife/firewall.nix deleted file mode 100644 index 3574e037..00000000 --- a/nix/modules/hosts/nixos/jubilife/firewall.nix +++ /dev/null @@ -1,13 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - networking.firewall = { - allowedTCPPorts = [2342 5143 6881 32400 8324 32443]; - allowedUDPPorts = [1900 32410 32412 32413 32414]; - extraInputRules = '' - -s 10.42.0.0/16 -p tcp --dport 3900 -j ACCEPT - -s 10.42.0.0/16 -p tcp --dport 2049 -j ACCEPT - -s 10.42.0.0/16 -p udp --dport 2049 -j ACCEPT - ''; - }; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/garage.nix b/nix/modules/hosts/nixos/jubilife/garage.nix deleted file mode 100644 index 43209d8a..00000000 --- a/nix/modules/hosts/nixos/jubilife/garage.nix +++ /dev/null @@ -1,89 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - config, - pkgs, - self, - ... - }: let - dataDirectory = "/mnt/Data"; - in { - sops.secrets = { - garageNextcloudAccessKey = { - sopsFile = "${self}/secrets/garage.yaml"; - key = "nextcloud_access_key"; - owner = "garage"; - group = "garage"; - }; - garageNextcloudSecretKey = { - sopsFile = "${self}/secrets/garage.yaml"; - key = "nextcloud_secret_key"; - owner = "garage"; - group = "garage"; - }; - garageRpcSecret = { - sopsFile = "${self}/secrets/garage.yaml"; - key = "rpc_secret"; - owner = "garage"; - group = "garage"; - }; - }; - sops.templates = { - garage-config = { - owner = "garage"; - group = "garage"; - mode = "0400"; - restartUnits = ["garage.service"]; - content = '' - metadata_dir = "${dataDirectory}/garage/meta" - data_dir = "${dataDirectory}/garage/data" - db_engine = "sqlite" - replication_factor = 1 - rpc_bind_addr = "[::]:3901" - rpc_public_addr = "10.254.0.1:3901" - rpc_secret = "${config.sops.placeholder.garageRpcSecret}" - - [s3_api] - # The firewall limits S3 access to k3s and the local Nextcloud network. - api_bind_addr = "[::]:3900" - s3_region = "garage" - ''; - }; - garage-environment = { - owner = "garage"; - group = "garage"; - mode = "0400"; - content = '' - GARAGE_CONFIG_FILE=${config.sops.templates.garage-config.path} - GARAGE_DEFAULT_ACCESS_KEY=${config.sops.placeholder.garageNextcloudAccessKey} - GARAGE_DEFAULT_SECRET_KEY=${config.sops.placeholder.garageNextcloudSecretKey} - GARAGE_DEFAULT_BUCKET=aly-nextcloud - ''; - }; - }; - users = { - groups.garage = {}; - users.garage = { - isSystemUser = true; - group = "garage"; - }; - }; - services.garage = { - enable = true; - package = pkgs.garage_2; - environmentFile = config.sops.templates.garage-environment.path; - settings = { - metadata_dir = "${dataDirectory}/garage/meta"; - data_dir = "${dataDirectory}/garage/data"; - }; - }; - systemd.services.garage = { - after = ["mnt-Data.mount"]; - requires = ["mnt-Data.mount"]; - serviceConfig = { - DynamicUser = false; - User = "garage"; - Group = "garage"; - }; - }; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/hostname.nix b/nix/modules/hosts/nixos/jubilife/hostname.nix deleted file mode 100644 index f715880e..00000000 --- a/nix/modules/hosts/nixos/jubilife/hostname.nix +++ /dev/null @@ -1,6 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - networking.hostName = "jubilife"; - system.stateVersion = "25.11"; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/k3s.nix b/nix/modules/hosts/nixos/jubilife/k3s.nix deleted file mode 100644 index 184cb092..00000000 --- a/nix/modules/hosts/nixos/jubilife/k3s.nix +++ /dev/null @@ -1,11 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - myNixOs.profile.k3s = { - role = "server"; - clusterInit = true; - transportInterface = "wg-k3s"; - nodeIP = "10.254.0.1"; - zone = "home"; - }; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/nfs.nix b/nix/modules/hosts/nixos/jubilife/nfs.nix deleted file mode 100644 index e8ebb215..00000000 --- a/nix/modules/hosts/nixos/jubilife/nfs.nix +++ /dev/null @@ -1,11 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - services.nfs.server = { - enable = true; - exports = '' - /mnt/Data 100.64.0.0/10(rw,sync,no_subtree_check,no_root_squash,fsid=0) 10.42.0.0/16(rw,sync,no_subtree_check,no_root_squash,fsid=0) - /mnt/Media 100.64.0.0/10(rw,sync,no_subtree_check,no_root_squash,fsid=1) 10.42.0.0/16(rw,sync,no_subtree_check,no_root_squash,fsid=1) - ''; - }; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/packages.nix b/nix/modules/hosts/nixos/jubilife/packages.nix deleted file mode 100644 index 187a7ee1..00000000 --- a/nix/modules/hosts/nixos/jubilife/packages.nix +++ /dev/null @@ -1,28 +0,0 @@ -_: { - flake.nixosModules.jubilife = {pkgs, ...}: { - environment.systemPackages = with pkgs; [ - abcde - age - chezmoi - claude-code - codex - curl - delta - eza - ffmpeg-full - flac - fzf - gh - handbrake - lazygit - mediainfo - mkvtoolnix - opencode - rclone - restic - ripgrep - starship - zoxide - ]; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/samba.nix b/nix/modules/hosts/nixos/jubilife/samba.nix deleted file mode 100644 index d7aa8384..00000000 --- a/nix/modules/hosts/nixos/jubilife/samba.nix +++ /dev/null @@ -1,53 +0,0 @@ -_: { - flake.nixosModules.jubilife = {config, ...}: { - services = { - samba = { - enable = true; - openFirewall = true; - settings = { - global = { - security = "user"; - "map to guest" = "Bad User"; - "server min protocol" = "SMB3"; - "server max protocol" = "SMB3_11"; - "socket options" = "TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=262144 SO_SNDBUF=262144"; - "use sendfile" = "no"; - "aio read size" = "1"; - "aio write size" = "1"; - "min receivefile size" = "131072"; - "max xmit" = "65535"; - "strict locking" = "no"; - oplocks = "yes"; - "level2 oplocks" = "yes"; - }; - Data = { - "create mask" = "0755"; - "directory mask" = "0755"; - "force group" = "users"; - "force user" = "aly"; - "guest ok" = "yes"; - "read only" = "no"; - browseable = "yes"; - comment = "Data @ ${config.networking.hostName}"; - path = "/mnt/Data"; - }; - Media = { - "create mask" = "0755"; - "directory mask" = "0755"; - "force group" = "users"; - "force user" = "aly"; - "guest ok" = "yes"; - "read only" = "no"; - browseable = "yes"; - comment = "Media @ ${config.networking.hostName}"; - path = "/mnt/Media"; - }; - }; - }; - samba-wsdd = { - enable = true; - openFirewall = true; - }; - }; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/scsi.nix b/nix/modules/hosts/nixos/jubilife/scsi.nix deleted file mode 100644 index 54400163..00000000 --- a/nix/modules/hosts/nixos/jubilife/scsi.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - boot.kernelModules = ["sg"]; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/smartd.nix b/nix/modules/hosts/nixos/jubilife/smartd.nix deleted file mode 100644 index 3021a0a0..00000000 --- a/nix/modules/hosts/nixos/jubilife/smartd.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - services.smartd.enable = true; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/snapper.nix b/nix/modules/hosts/nixos/jubilife/snapper.nix deleted file mode 100644 index 331def70..00000000 --- a/nix/modules/hosts/nixos/jubilife/snapper.nix +++ /dev/null @@ -1,11 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - services.snapper.configs.media = { - ALLOW_GROUPS = ["users"]; - FSTYPE = "btrfs"; - SUBVOLUME = "/mnt/Media"; - TIMELINE_CLEANUP = true; - TIMELINE_CREATE = true; - }; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/storage.nix b/nix/modules/hosts/nixos/jubilife/storage.nix deleted file mode 100644 index 5de44dad..00000000 --- a/nix/modules/hosts/nixos/jubilife/storage.nix +++ /dev/null @@ -1,26 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - fileSystems = { - "/mnt/Data" = { - device = "/dev/disk/by-id/ata-CT4000BX500SSD1_2447E9959972"; - fsType = "btrfs"; - options = ["compress=zstd" "noatime" "nofail"]; - }; - "/mnt/Media" = { - device = "/dev/disk/by-id/ata-ST14000NM001G-2KJ103_ZL201XNJ-part1"; - fsType = "btrfs"; - options = ["subvol=@media" "compress=zstd" "noatime" "nofail"]; - }; - }; - myNixOs = { - profile.arr.dataDir = "/mnt/Data"; - profile.b2Mounts = { - cacheDir = "/mnt/Data/.rclone-cache"; - audioCacheSize = "50G"; - audioReadAhead = "3G"; - videoCacheSize = "300G"; - videoReadAhead = "5G"; - }; - }; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/syncthing.nix b/nix/modules/hosts/nixos/jubilife/syncthing.nix deleted file mode 100644 index 467d57df..00000000 --- a/nix/modules/hosts/nixos/jubilife/syncthing.nix +++ /dev/null @@ -1,28 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - config, - self, - ... - }: { - myNixOs = { - service.syncthing = { - certFile = config.sops.secrets.syncthingCert.path; - keyFile = config.sops.secrets.syncthingKey.path; - romsPath = "/mnt/Data/syncthing/ROMs"; - syncROMs = true; - user = "aly"; - }; - users.aly.password = "$6$JTk2qi27OpA2fOAY$ZgTDg0wbmbwHUD..0xT4xYX.AR5hWQFCMVmn8G88yi3IAY7015AupovTpfy0arkI7nl/IDu5L09bzLKeXGvJC1"; - }; - sops.secrets = { - syncthingCert = { - sopsFile = "${self}/secrets/syncthing.yaml"; - key = "jubilife_cert"; - }; - syncthingKey = { - sopsFile = "${self}/secrets/syncthing.yaml"; - key = "jubilife_key"; - }; - }; - }; -} diff --git a/nix/modules/hosts/nixos/jubilife/tuned.nix b/nix/modules/hosts/nixos/jubilife/tuned.nix deleted file mode 100644 index 87695acc..00000000 --- a/nix/modules/hosts/nixos/jubilife/tuned.nix +++ /dev/null @@ -1,8 +0,0 @@ -_: { - flake.nixosModules.jubilife = { - services.tuned = { - enable = true; - settings.dynamic_tuning = true; - }; - }; -} diff --git a/nix/modules/hosts/nixos/pastoria/atbbs.nix b/nix/modules/hosts/nixos/pastoria/atbbs.nix deleted file mode 100644 index b712bf2e..00000000 --- a/nix/modules/hosts/nixos/pastoria/atbbs.nix +++ /dev/null @@ -1,15 +0,0 @@ -_: { - flake.nixosModules.pastoria = {pkgs, ...}: { - networking.firewall.allowedTCPPorts = [23]; - - systemd.services.atbbs-telnet = { - description = "TCP proxy for atbbs telnet"; - wantedBy = ["multi-user.target"]; - after = ["network.target"]; - serviceConfig = { - ExecStart = "${pkgs.socat}/bin/socat TCP-LISTEN:23,fork,reuseaddr TCP:jubilife:2323"; - Restart = "always"; - }; - }; - }; -} diff --git a/nix/modules/hosts/nixos/pastoria/auto-upgrade.nix b/nix/modules/hosts/nixos/pastoria/auto-upgrade.nix deleted file mode 100644 index c4a11fd6..00000000 --- a/nix/modules/hosts/nixos/pastoria/auto-upgrade.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.pastoria = { - system.autoUpgrade.dates = "01:45"; - }; -} diff --git a/nix/modules/hosts/nixos/pastoria/boot.nix b/nix/modules/hosts/nixos/pastoria/boot.nix deleted file mode 100644 index 798bf40f..00000000 --- a/nix/modules/hosts/nixos/pastoria/boot.nix +++ /dev/null @@ -1,8 +0,0 @@ -_: { - flake.nixosModules.pastoria = { - boot.loader.grub = { - efiSupport = true; - efiInstallAsRemovable = true; - }; - }; -} diff --git a/nix/modules/hosts/nixos/pastoria/default.nix b/nix/modules/hosts/nixos/pastoria/default.nix deleted file mode 100644 index 12edd4dc..00000000 --- a/nix/modules/hosts/nixos/pastoria/default.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ - inputs, - self, - ... -}: { - config.flake.nixosConfigurations.pastoria = inputs.nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - specialArgs = {inherit inputs self;}; - modules = [ - inputs.disko.nixosModules.disko - inputs.sops-nix.nixosModules.sops - self.nixosModules.default - self.nixosModules.pastoria - self.nixosModules.disko - self.nixosModules.lvmExt4 - self.nixosModules.backups - self.nixosModules.k3s - self.nixosModules.swap - self.nixosModules.wireguardK3s - self.nixosModules.wireguardHoenn - self.nixosModules.docker - self.nixosModules.alloy - self.nixosModules.fail2ban - self.nixosModules.prometheusNode - self.nixosModules.tailscale - ]; - }; -} diff --git a/nix/modules/hosts/nixos/pastoria/disko.nix b/nix/modules/hosts/nixos/pastoria/disko.nix deleted file mode 100644 index 0a6a800b..00000000 --- a/nix/modules/hosts/nixos/pastoria/disko.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.pastoria = { - myDisko.installDrive = "/dev/sda"; - }; -} diff --git a/nix/modules/hosts/nixos/pastoria/facter.json b/nix/modules/hosts/nixos/pastoria/facter.json deleted file mode 100644 index deb1e119..00000000 --- a/nix/modules/hosts/nixos/pastoria/facter.json +++ /dev/null @@ -1,2233 +0,0 @@ -{ - "version": 1, - "system": "x86_64-linux", - "virtualisation": "kvm", - "uefi": { - "supported": false - }, - "hardware": { - "bios": { - "apm_info": { - "supported": false, - "enabled": false, - "version": 0, - "sub_version": 0, - "bios_flags": 0 - }, - "vbe_info": { - "version": 0, - "video_memory": 0 - }, - "pnp": true, - "pnp_id": 0, - "lba_support": false, - "low_memory_size": 654336, - "smbios_version": 520 - }, - "bridge": [ - { - "index": 11, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 1 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0001", - "name": "ISA bridge", - "value": 1 - }, - "vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "7000", - "value": 28672 - }, - "sub_device": { - "hex": "1100", - "value": 4352 - }, - "model": "Intel ISA bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:01.0", - "sysfs_bus_id": "0000:00:01.0", - "detail": { - "function": 0, - "command": 259, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00008086d00007000sv00001AF4sd00001100bc06sc01i00" - }, - { - "index": 13, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0000", - "name": "Host bridge", - "value": 0 - }, - "vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "1237", - "value": 4663 - }, - "sub_device": { - "hex": "1100", - "value": 4352 - }, - "revision": { - "hex": "0002", - "value": 2 - }, - "model": "Intel Host bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:00.0", - "sysfs_bus_id": "0000:00:00.0", - "detail": { - "function": 0, - "command": 259, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00008086d00001237sv00001AF4sd00001100bc06sc00i00" - }, - { - "index": 14, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 1 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0080", - "name": "Bridge", - "value": 128 - }, - "vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "7113", - "value": 28947 - }, - "sub_device": { - "hex": "1100", - "value": 4352 - }, - "revision": { - "hex": "0003", - "value": 3 - }, - "model": "Intel Bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:01.3", - "sysfs_bus_id": "0000:00:01.3", - "detail": { - "function": 3, - "command": 259, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "piix4_smbus", - "driver_module": "i2c_piix4", - "drivers": ["piix4_smbus"], - "driver_modules": ["i2c_piix4"], - "module_alias": "pci:v00008086d00007113sv00001AF4sd00001100bc06sc80i00" - } - ], - "cpu": [ - { - "architecture": "x86_64", - "vendor_name": "GenuineIntel", - "model_name": "Intel Core Processor (Haswell, no TSX)", - "family": 6, - "model": 60, - "stepping": 1, - "features": [ - "fpu", - "vme", - "de", - "pse", - "tsc", - "msr", - "pae", - "mce", - "cx8", - "apic", - "sep", - "mtrr", - "pge", - "mca", - "cmov", - "pat", - "pse36", - "clflush", - "mmx", - "fxsr", - "sse", - "sse2", - "syscall", - "nx", - "rdtscp", - "lm", - "rep_good", - "nopl", - "xtopology", - "cpuid", - "tsc_known_freq", - "pni", - "pclmulqdq", - "vmx", - "ssse3", - "fma", - "cx16", - "pcid", - "sse4_1", - "sse4_2", - "x2apic", - "movbe", - "popcnt", - "tsc_deadline_timer", - "aes", - "xsave", - "avx", - "f16c", - "rdrand", - "hypervisor", - "lahf_lm", - "abm", - "cpuid_fault", - "pti", - "tpr_shadow", - "flexpriority", - "ept", - "vpid", - "ept_ad", - "fsgsbase", - "bmi1", - "avx2", - "smep", - "bmi2", - "erms", - "invpcid", - "xsaveopt", - "arat", - "vnmi", - "md_clear" - ], - "bugs": [ - "cpu_meltdown", - "spectre_v1", - "spectre_v2", - "spec_store_bypass", - "l1tf", - "mds", - "swapgs", - "itlb_multihit", - "srbds", - "bhi", - "spectre_v2_user", - "its" - ], - "power_management": [""], - "bogo": 4799, - "cache": 16384, - "page_size": 4096, - "physical_id": 0, - "siblings": 1, - "cores": 1, - "fpu": false, - "fpu_exception": false, - "cpuid_level": 13, - "write_protect": false, - "tlb_size": 32147, - "clflush_size": 64, - "cache_alignment": 64, - "address_sizes": { - "physical": "0x28", - "virtual": "0x30" - } - }, - { - "architecture": "x86_64", - "vendor_name": "GenuineIntel", - "model_name": "Intel Core Processor (Haswell, no TSX)", - "family": 6, - "model": 60, - "stepping": 1, - "features": [ - "fpu", - "vme", - "de", - "pse", - "tsc", - "msr", - "pae", - "mce", - "cx8", - "apic", - "sep", - "mtrr", - "pge", - "mca", - "cmov", - "pat", - "pse36", - "clflush", - "mmx", - "fxsr", - "sse", - "sse2", - "syscall", - "nx", - "rdtscp", - "lm", - "rep_good", - "nopl", - "xtopology", - "cpuid", - "tsc_known_freq", - "pni", - "pclmulqdq", - "vmx", - "ssse3", - "fma", - "cx16", - "pcid", - "sse4_1", - "sse4_2", - "x2apic", - "movbe", - "popcnt", - "tsc_deadline_timer", - "aes", - "xsave", - "avx", - "f16c", - "rdrand", - "hypervisor", - "lahf_lm", - "abm", - "cpuid_fault", - "pti", - "tpr_shadow", - "flexpriority", - "ept", - "vpid", - "ept_ad", - "fsgsbase", - "bmi1", - "avx2", - "smep", - "bmi2", - "erms", - "invpcid", - "xsaveopt", - "arat", - "vnmi", - "md_clear" - ], - "bugs": [ - "cpu_meltdown", - "spectre_v1", - "spectre_v2", - "spec_store_bypass", - "l1tf", - "mds", - "swapgs", - "itlb_multihit", - "srbds", - "bhi", - "spectre_v2_user", - "its" - ], - "power_management": [""], - "bogo": 4799, - "cache": 16384, - "page_size": 4096, - "physical_id": 1, - "siblings": 1, - "cores": 1, - "fpu": false, - "fpu_exception": false, - "cpuid_level": 13, - "write_protect": false, - "tlb_size": 32147, - "clflush_size": 64, - "cache_alignment": 64, - "address_sizes": { - "physical": "0x28", - "virtual": "0x30" - } - }, - { - "architecture": "x86_64", - "vendor_name": "GenuineIntel", - "model_name": "Intel Core Processor (Haswell, no TSX)", - "family": 6, - "model": 60, - "stepping": 1, - "features": [ - "fpu", - "vme", - "de", - "pse", - "tsc", - "msr", - "pae", - "mce", - "cx8", - "apic", - "sep", - "mtrr", - "pge", - "mca", - "cmov", - "pat", - "pse36", - "clflush", - "mmx", - "fxsr", - "sse", - "sse2", - "syscall", - "nx", - "rdtscp", - "lm", - "rep_good", - "nopl", - "xtopology", - "cpuid", - "tsc_known_freq", - "pni", - "pclmulqdq", - "vmx", - "ssse3", - "fma", - "cx16", - "pcid", - "sse4_1", - "sse4_2", - "x2apic", - "movbe", - "popcnt", - "tsc_deadline_timer", - "aes", - "xsave", - "avx", - "f16c", - "rdrand", - "hypervisor", - "lahf_lm", - "abm", - "cpuid_fault", - "pti", - "tpr_shadow", - "flexpriority", - "ept", - "vpid", - "ept_ad", - "fsgsbase", - "bmi1", - "avx2", - "smep", - "bmi2", - "erms", - "invpcid", - "xsaveopt", - "arat", - "vnmi", - "md_clear" - ], - "bugs": [ - "cpu_meltdown", - "spectre_v1", - "spectre_v2", - "spec_store_bypass", - "l1tf", - "mds", - "swapgs", - "itlb_multihit", - "srbds", - "bhi", - "spectre_v2_user", - "its" - ], - "power_management": [""], - "bogo": 4799, - "cache": 16384, - "page_size": 4096, - "physical_id": 2, - "siblings": 1, - "cores": 1, - "fpu": false, - "fpu_exception": false, - "cpuid_level": 13, - "write_protect": false, - "tlb_size": 32147, - "clflush_size": 64, - "cache_alignment": 64, - "address_sizes": { - "physical": "0x28", - "virtual": "0x30" - } - }, - { - "architecture": "x86_64", - "vendor_name": "GenuineIntel", - "model_name": "Intel Core Processor (Haswell, no TSX)", - "family": 6, - "model": 60, - "stepping": 1, - "features": [ - "fpu", - "vme", - "de", - "pse", - "tsc", - "msr", - "pae", - "mce", - "cx8", - "apic", - "sep", - "mtrr", - "pge", - "mca", - "cmov", - "pat", - "pse36", - "clflush", - "mmx", - "fxsr", - "sse", - "sse2", - "syscall", - "nx", - "rdtscp", - "lm", - "rep_good", - "nopl", - "xtopology", - "cpuid", - "tsc_known_freq", - "pni", - "pclmulqdq", - "vmx", - "ssse3", - "fma", - "cx16", - "pcid", - "sse4_1", - "sse4_2", - "x2apic", - "movbe", - "popcnt", - "tsc_deadline_timer", - "aes", - "xsave", - "avx", - "f16c", - "rdrand", - "hypervisor", - "lahf_lm", - "abm", - "cpuid_fault", - "pti", - "tpr_shadow", - "flexpriority", - "ept", - "vpid", - "ept_ad", - "fsgsbase", - "bmi1", - "avx2", - "smep", - "bmi2", - "erms", - "invpcid", - "xsaveopt", - "arat", - "vnmi", - "md_clear" - ], - "bugs": [ - "cpu_meltdown", - "spectre_v1", - "spectre_v2", - "spec_store_bypass", - "l1tf", - "mds", - "swapgs", - "itlb_multihit", - "srbds", - "bhi", - "spectre_v2_user", - "its" - ], - "power_management": [""], - "bogo": 4799, - "cache": 16384, - "page_size": 4096, - "physical_id": 3, - "siblings": 1, - "cores": 1, - "fpu": false, - "fpu_exception": false, - "cpuid_level": 13, - "write_protect": false, - "tlb_size": 32147, - "clflush_size": 64, - "cache_alignment": 64, - "address_sizes": { - "physical": "0x28", - "virtual": "0x30" - } - }, - { - "architecture": "x86_64", - "vendor_name": "GenuineIntel", - "model_name": "Intel Core Processor (Haswell, no TSX)", - "family": 6, - "model": 60, - "stepping": 1, - "features": [ - "fpu", - "vme", - "de", - "pse", - "tsc", - "msr", - "pae", - "mce", - "cx8", - "apic", - "sep", - "mtrr", - "pge", - "mca", - "cmov", - "pat", - "pse36", - "clflush", - "mmx", - "fxsr", - "sse", - "sse2", - "syscall", - "nx", - "rdtscp", - "lm", - "rep_good", - "nopl", - "xtopology", - "cpuid", - "tsc_known_freq", - "pni", - "pclmulqdq", - "vmx", - "ssse3", - "fma", - "cx16", - "pcid", - "sse4_1", - "sse4_2", - "x2apic", - "movbe", - "popcnt", - "tsc_deadline_timer", - "aes", - "xsave", - "avx", - "f16c", - "rdrand", - "hypervisor", - "lahf_lm", - "abm", - "cpuid_fault", - "pti", - "tpr_shadow", - "flexpriority", - "ept", - "vpid", - "ept_ad", - "fsgsbase", - "bmi1", - "avx2", - "smep", - "bmi2", - "erms", - "invpcid", - "xsaveopt", - "arat", - "vnmi", - "md_clear" - ], - "bugs": [ - "cpu_meltdown", - "spectre_v1", - "spectre_v2", - "spec_store_bypass", - "l1tf", - "mds", - "swapgs", - "itlb_multihit", - "srbds", - "bhi", - "spectre_v2_user", - "its" - ], - "power_management": [""], - "bogo": 4799, - "cache": 16384, - "page_size": 4096, - "physical_id": 4, - "siblings": 1, - "cores": 1, - "fpu": false, - "fpu_exception": false, - "cpuid_level": 13, - "write_protect": false, - "tlb_size": 32147, - "clflush_size": 64, - "cache_alignment": 64, - "address_sizes": { - "physical": "0x28", - "virtual": "0x30" - } - }, - { - "architecture": "x86_64", - "vendor_name": "GenuineIntel", - "model_name": "Intel Core Processor (Haswell, no TSX)", - "family": 6, - "model": 60, - "stepping": 1, - "features": [ - "fpu", - "vme", - "de", - "pse", - "tsc", - "msr", - "pae", - "mce", - "cx8", - "apic", - "sep", - "mtrr", - "pge", - "mca", - "cmov", - "pat", - "pse36", - "clflush", - "mmx", - "fxsr", - "sse", - "sse2", - "syscall", - "nx", - "rdtscp", - "lm", - "rep_good", - "nopl", - "xtopology", - "cpuid", - "tsc_known_freq", - "pni", - "pclmulqdq", - "vmx", - "ssse3", - "fma", - "cx16", - "pcid", - "sse4_1", - "sse4_2", - "x2apic", - "movbe", - "popcnt", - "tsc_deadline_timer", - "aes", - "xsave", - "avx", - "f16c", - "rdrand", - "hypervisor", - "lahf_lm", - "abm", - "cpuid_fault", - "pti", - "tpr_shadow", - "flexpriority", - "ept", - "vpid", - "ept_ad", - "fsgsbase", - "bmi1", - "avx2", - "smep", - "bmi2", - "erms", - "invpcid", - "xsaveopt", - "arat", - "vnmi", - "md_clear" - ], - "bugs": [ - "cpu_meltdown", - "spectre_v1", - "spectre_v2", - "spec_store_bypass", - "l1tf", - "mds", - "swapgs", - "itlb_multihit", - "srbds", - "bhi", - "spectre_v2_user", - "its" - ], - "power_management": [""], - "bogo": 4799, - "cache": 16384, - "page_size": 4096, - "physical_id": 5, - "siblings": 1, - "cores": 1, - "fpu": false, - "fpu_exception": false, - "cpuid_level": 13, - "write_protect": false, - "tlb_size": 32147, - "clflush_size": 64, - "cache_alignment": 64, - "address_sizes": { - "physical": "0x28", - "virtual": "0x30" - } - } - ], - "disk": [ - { - "index": 25, - "attached_to": 20, - "class_list": ["disk", "scsi", "block_device"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "vendor": { - "hex": "0000", - "name": "QEMU", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "QEMU HARDDISK", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "2.5+", - "value": 0 - }, - "model": "QEMU HARDDISK", - "sysfs_id": "/class/block/sda", - "sysfs_bus_id": "0:0:0:0", - "sysfs_device_link": "/devices/pci0000:00/0000:00:04.0/virtio1/host0/target0:0:0/0:0:0:0", - "unix_device_names": [ - "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0-0-0-0", - "/dev/disk/by-path/pci-0000:00:04.0-scsi-0:0:0:0", - "/dev/sda" - ], - "unix_device_name2": "/dev/sg0", - "resources": [ - { - "type": "disk_geo", - "cylinders": 13054, - "heads": 255, - "sectors": 63, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 209715200, - "value_2": 512 - } - ], - "driver": "virtio_scsi", - "driver_module": "virtio_scsi", - "drivers": ["sd", "virtio_scsi"], - "driver_modules": ["sd_mod", "virtio_scsi"] - }, - { - "index": 26, - "attached_to": 0, - "class_list": ["disk", "block_device"], - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "model": "Disk", - "sysfs_id": "/class/block/zram0", - "unix_device_names": [ - "/dev/disk/by-label/zram0", - "/dev/disk/by-uuid/5fe020c7-ba26-491a-8486-d370d1d649a8", - "/dev/zram0" - ], - "resources": [ - { - "type": "size", - "unit": "sectors", - "value_1": 1494784, - "value_2": 4096 - } - ] - } - ], - "graphics_card": [ - { - "index": 18, - "attached_to": 0, - "class_list": ["graphics_card", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 2 - }, - "base_class": { - "hex": "0003", - "name": "Display controller", - "value": 3 - }, - "sub_class": { - "hex": "0000", - "name": "VGA compatible controller", - "value": 0 - }, - "pci_interface": { - "hex": "0000", - "name": "VGA", - "value": 0 - }, - "vendor": { - "hex": "1013", - "name": "Cirrus Logic", - "value": 4115 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "00b8", - "name": "GD 5446", - "value": 184 - }, - "sub_device": { - "hex": "1100", - "value": 4352 - }, - "model": "Cirrus Logic GD 5446", - "sysfs_id": "/devices/pci0000:00/0000:00:02.0", - "sysfs_bus_id": "0000:00:02.0", - "detail": { - "function": 0, - "command": 259, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "cirrus-qemu", - "driver_module": "cirrus_qemu", - "drivers": ["cirrus-qemu"], - "driver_modules": ["cirrus_qemu"], - "driver_info": { - "type": "x11", - "db_entry_0": ["4", "cirrus"], - "server": "cirrus", - "xf86_version": "4", - "supports_3d": false, - "Colors": { - "all": 0, - "c8": 0, - "c15": 0, - "c16": 0, - "c24": 0, - "c32": 0 - }, - "dac_speed": 0, - "script": "" - }, - "module_alias": "pci:v00001013d000000B8sv00001AF4sd00001100bc03sc00i00" - } - ], - "hub": [ - { - "index": 27, - "attached_to": 10, - "class_list": ["usb", "hub"], - "bus_type": { - "hex": "0086", - "name": "USB", - "value": 134 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "010a", - "name": "Hub", - "value": 266 - }, - "vendor": { - "hex": "1d6b", - "name": "Linux 6.18.44 uhci_hcd", - "value": 7531 - }, - "device": { - "hex": "0001", - "name": "UHCI Host Controller", - "value": 1 - }, - "revision": { - "hex": "0000", - "name": "6.18", - "value": 0 - }, - "serial": "0000:00:01.2", - "model": "Linux 6.18.44 uhci_hcd UHCI Host Controller", - "sysfs_id": "/devices/pci0000:00/0000:00:01.2/usb1/1-0:1.0", - "sysfs_bus_id": "1-0:1.0", - "resources": [ - { - "type": "baud", - "speed": 12000000, - "bits": 0, - "stop_bits": 0, - "parity": 0, - "handshake": 0 - } - ], - "detail": { - "device_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "device_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "device_protocol": 0, - "interface_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "interface_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "interface_protocol": 0, - "interface_number": 0, - "interface_alternate_setting": 0 - }, - "hotplug": "usb", - "driver": "hub", - "driver_module": "usbcore", - "drivers": ["hub"], - "driver_modules": ["usbcore"], - "module_alias": "usb:v1D6Bp0001d0618dc09dsc00dp00ic09isc00ip00in00" - } - ], - "memory": [ - { - "index": 9, - "attached_to": 0, - "class_list": ["memory"], - "base_class": { - "hex": "0101", - "name": "Internally Used Class", - "value": 257 - }, - "sub_class": { - "hex": "0002", - "name": "Main Memory", - "value": 2 - }, - "model": "Main Memory", - "resources": [ - { - "type": "phys_mem", - "range": 11811160064 - } - ] - } - ], - "mouse": [ - { - "index": 28, - "attached_to": 27, - "class_list": ["mouse", "usb"], - "bus_type": { - "hex": "0086", - "name": "USB", - "value": 134 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "0105", - "name": "Mouse", - "value": 261 - }, - "sub_class": { - "hex": "0003", - "name": "USB Mouse", - "value": 3 - }, - "vendor": { - "hex": "0627", - "name": "QEMU", - "value": 1575 - }, - "device": { - "hex": "0001", - "name": "QEMU USB Tablet", - "value": 1 - }, - "serial": "28754-0000:00:01.2-1", - "compat_vendor": "Unknown", - "compat_device": "Generic USB Mouse", - "model": "QEMU USB Tablet", - "sysfs_id": "/devices/pci0000:00/0000:00:01.2/usb1/1-1/1-1:1.0", - "sysfs_bus_id": "1-1:1.0", - "unix_device_names": ["/dev/input/mice"], - "unix_device_name2": "/dev/input/mouse0", - "resources": [ - { - "type": "baud", - "speed": 12000000, - "bits": 0, - "stop_bits": 0, - "parity": 0, - "handshake": 0 - } - ], - "detail": { - "device_class": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "device_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "device_protocol": 0, - "interface_class": { - "hex": "0003", - "name": "hid", - "value": 3 - }, - "interface_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "interface_protocol": 0, - "interface_number": 0, - "interface_alternate_setting": 0 - }, - "hotplug": "usb", - "driver": "usbhid", - "driver_module": "usbhid", - "drivers": ["usbhid"], - "driver_modules": ["usbhid"], - "driver_info": { - "type": "mouse", - "db_entry_0": ["explorerps/2", "exps2"], - "xf86": "explorerps/2", - "gpm": "exps2", - "buttons": -1, - "wheels": -1 - }, - "module_alias": "usb:v0627p0001d0000dc00dsc00dp00ic03isc00ip00in00" - } - ], - "network_controller": [ - { - "index": 22, - "attached_to": 15, - "class_list": ["network_controller"], - "bus_type": { - "hex": "008f", - "name": "Virtio", - "value": 143 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "0002", - "name": "Network controller", - "value": 2 - }, - "sub_class": { - "hex": "0000", - "name": "Ethernet controller", - "value": 0 - }, - "vendor": "Virtio", - "device": "Ethernet Card 0", - "model": "Virtio Ethernet Card 0", - "sysfs_id": "/devices/pci0000:00/0000:00:03.0/virtio0", - "sysfs_bus_id": "virtio0", - "unix_device_names": ["ens3"], - "resources": [ - { - "type": "hwaddr", - "address": 102 - }, - { - "type": "phwaddr", - "address": 102 - } - ], - "driver": "virtio_net", - "driver_module": "virtio_net", - "drivers": ["virtio_net"], - "driver_modules": ["virtio_net"], - "module_alias": "virtio:d00000001v00001AF4" - } - ], - "network_interface": [ - { - "index": 34, - "attached_to": 0, - "class_list": ["network_interface"], - "base_class": { - "hex": "0107", - "name": "Network Interface", - "value": 263 - }, - "sub_class": { - "hex": "0000", - "name": "Loopback", - "value": 0 - }, - "model": "Loopback network interface", - "sysfs_id": "/class/net/lo", - "unix_device_names": ["lo"] - }, - { - "index": 39, - "attached_to": 22, - "class_list": ["network_interface"], - "base_class": { - "hex": "0107", - "name": "Network Interface", - "value": 263 - }, - "sub_class": { - "hex": "0001", - "name": "Ethernet", - "value": 1 - }, - "model": "Ethernet network interface", - "sysfs_id": "/class/net/ens3", - "sysfs_device_link": "/devices/pci0000:00/0000:00:03.0/virtio0", - "unix_device_names": ["ens3"], - "resources": [ - { - "type": "hwaddr", - "address": 102 - }, - { - "type": "phwaddr", - "address": 102 - } - ], - "driver": "virtio_net", - "driver_module": "virtio_net", - "drivers": ["virtio_net"], - "driver_modules": ["virtio_net"] - } - ], - "pci": [ - { - "index": 15, - "attached_to": 0, - "class_list": ["pci", "unknown"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 3 - }, - "base_class": { - "hex": "0002", - "name": "Network controller", - "value": 2 - }, - "sub_class": { - "hex": "0000", - "name": "Ethernet controller", - "value": 0 - }, - "vendor": { - "hex": "1af4", - "value": 6900 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "1000", - "value": 4096 - }, - "sub_device": { - "hex": "0001", - "value": 1 - }, - "model": "Ethernet controller", - "sysfs_id": "/devices/pci0000:00/0000:00:03.0", - "sysfs_bus_id": "0000:00:03.0", - "resources": [ - { - "type": "io", - "base": 49152, - "range": 64, - "enabled": true, - "access": "read_write" - } - ], - "detail": { - "function": 0, - "command": 1287, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "virtio-pci", - "driver_module": "virtio_pci", - "drivers": ["virtio-pci"], - "driver_modules": ["virtio_pci"], - "module_alias": "pci:v00001AF4d00001000sv00001AF4sd00000001bc02sc00i00" - }, - { - "index": 17, - "attached_to": 0, - "class_list": ["pci", "unknown"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 6 - }, - "base_class": { - "hex": "0000", - "name": "Unclassified device", - "value": 0 - }, - "sub_class": { - "hex": "00ff", - "value": 255 - }, - "vendor": { - "hex": "1af4", - "value": 6900 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "1002", - "value": 4098 - }, - "sub_device": { - "hex": "0005", - "value": 5 - }, - "model": "Unclassified device", - "sysfs_id": "/devices/pci0000:00/0000:00:06.0", - "sysfs_bus_id": "0000:00:06.0", - "resources": [ - { - "type": "io", - "base": 49344, - "range": 64, - "enabled": true, - "access": "read_write" - } - ], - "detail": { - "function": 0, - "command": 263, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "virtio-pci", - "driver_module": "virtio_pci", - "drivers": ["virtio-pci"], - "driver_modules": ["virtio_pci"], - "module_alias": "pci:v00001AF4d00001002sv00001AF4sd00000005bc00scFFi00" - }, - { - "index": 19, - "attached_to": 0, - "class_list": ["pci", "unknown"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 5 - }, - "base_class": { - "hex": "0007", - "name": "Communication controller", - "value": 7 - }, - "sub_class": { - "hex": "0080", - "name": "Communication controller", - "value": 128 - }, - "vendor": { - "hex": "1af4", - "value": 6900 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "1003", - "value": 4099 - }, - "sub_device": { - "hex": "0003", - "value": 3 - }, - "model": "Communication controller", - "sysfs_id": "/devices/pci0000:00/0000:00:05.0", - "sysfs_bus_id": "0000:00:05.0", - "resources": [ - { - "type": "io", - "base": 49280, - "range": 64, - "enabled": true, - "access": "read_write" - } - ], - "detail": { - "function": 0, - "command": 1287, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "virtio-pci", - "driver_module": "virtio_pci", - "drivers": ["virtio-pci"], - "driver_modules": ["virtio_pci"], - "module_alias": "pci:v00001AF4d00001003sv00001AF4sd00000003bc07sc80i00" - } - ], - "storage_controller": [ - { - "index": 12, - "attached_to": 0, - "class_list": ["storage_controller", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 4 - }, - "base_class": { - "hex": "0001", - "name": "Mass storage controller", - "value": 1 - }, - "sub_class": { - "hex": "0000", - "name": "SCSI storage controller", - "value": 0 - }, - "vendor": { - "hex": "1af4", - "value": 6900 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "1004", - "value": 4100 - }, - "sub_device": { - "hex": "0008", - "value": 8 - }, - "model": "SCSI storage controller", - "sysfs_id": "/devices/pci0000:00/0000:00:04.0", - "sysfs_bus_id": "0000:00:04.0", - "resources": [ - { - "type": "io", - "base": 49216, - "range": 64, - "enabled": true, - "access": "read_write" - } - ], - "detail": { - "function": 0, - "command": 1287, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "virtio-pci", - "driver_module": "virtio_pci", - "drivers": ["virtio-pci"], - "driver_modules": ["virtio_pci"], - "module_alias": "pci:v00001AF4d00001004sv00001AF4sd00000008bc01sc00i00" - }, - { - "index": 16, - "attached_to": 0, - "class_list": ["storage_controller", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 1 - }, - "base_class": { - "hex": "0001", - "name": "Mass storage controller", - "value": 1 - }, - "sub_class": { - "hex": "0001", - "name": "IDE interface", - "value": 1 - }, - "pci_interface": { - "hex": "0080", - "value": 128 - }, - "vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "7010", - "value": 28688 - }, - "sub_device": { - "hex": "1100", - "value": 4352 - }, - "model": "Intel IDE interface", - "sysfs_id": "/devices/pci0000:00/0000:00:01.1", - "sysfs_bus_id": "0000:00:01.1", - "resources": [ - { - "type": "io", - "base": 1014, - "range": 1, - "enabled": true, - "access": "read_write" - }, - { - "type": "io", - "base": 368, - "range": 8, - "enabled": true, - "access": "read_write" - }, - { - "type": "io", - "base": 49440, - "range": 16, - "enabled": true, - "access": "read_write" - }, - { - "type": "io", - "base": 496, - "range": 8, - "enabled": true, - "access": "read_write" - }, - { - "type": "io", - "base": 886, - "range": 1, - "enabled": true, - "access": "read_write" - } - ], - "detail": { - "function": 1, - "command": 263, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 128 - }, - "driver": "ata_piix", - "driver_module": "ata_piix", - "drivers": ["ata_piix"], - "driver_modules": ["ata_piix"], - "module_alias": "pci:v00008086d00007010sv00001AF4sd00001100bc01sc01i80" - } - ], - "system": { - "form_factor": "desktop" - }, - "unknown": [ - { - "index": 20, - "attached_to": 12, - "class_list": ["unknown"], - "base_class": { - "hex": "0000", - "name": "Unclassified device", - "value": 0 - }, - "sub_class": { - "hex": "0000", - "name": "Unclassified device", - "value": 0 - }, - "vendor": "Virtio", - "device": "", - "model": "Virtio Unclassified device", - "sysfs_id": "/devices/pci0000:00/0000:00:04.0/virtio1", - "sysfs_bus_id": "virtio1", - "driver": "virtio_scsi", - "driver_module": "virtio_scsi", - "drivers": ["virtio_scsi"], - "driver_modules": ["virtio_scsi"], - "module_alias": "virtio:d00000008v00001AF4" - }, - { - "index": 21, - "attached_to": 19, - "class_list": ["unknown"], - "base_class": { - "hex": "0000", - "name": "Unclassified device", - "value": 0 - }, - "sub_class": { - "hex": "0000", - "name": "Unclassified device", - "value": 0 - }, - "vendor": "Virtio", - "device": "", - "model": "Virtio Unclassified device", - "sysfs_id": "/devices/pci0000:00/0000:00:05.0/virtio2", - "sysfs_bus_id": "virtio2", - "driver": "virtio_console", - "driver_module": "virtio_console", - "drivers": ["virtio_console"], - "driver_modules": ["virtio_console"], - "module_alias": "virtio:d00000003v00001AF4" - }, - { - "index": 23, - "attached_to": 17, - "class_list": ["unknown"], - "base_class": { - "hex": "0000", - "name": "Unclassified device", - "value": 0 - }, - "sub_class": { - "hex": "0000", - "name": "Unclassified device", - "value": 0 - }, - "vendor": "Virtio", - "device": "", - "model": "Virtio Unclassified device", - "sysfs_id": "/devices/pci0000:00/0000:00:06.0/virtio3", - "sysfs_bus_id": "virtio3", - "driver": "virtio_balloon", - "driver_module": "virtio_balloon", - "drivers": ["virtio_balloon"], - "driver_modules": ["virtio_balloon"], - "module_alias": "virtio:d00000005v00001AF4" - }, - { - "index": 24, - "attached_to": 0, - "class_list": ["unknown"], - "base_class": { - "hex": "0007", - "name": "Communication controller", - "value": 7 - }, - "sub_class": { - "hex": "0000", - "name": "Serial controller", - "value": 0 - }, - "pci_interface": { - "hex": "0002", - "name": "16550", - "value": 2 - }, - "device": { - "hex": "0000", - "name": "16550A", - "value": 0 - }, - "model": "16550A", - "unix_device_names": ["/dev/ttyS0"], - "resources": [ - { - "type": "io", - "base": 1016, - "range": 0, - "enabled": true, - "access": "read_write" - } - ] - } - ], - "usb_controller": [ - { - "index": 10, - "attached_to": 0, - "class_list": ["usb_controller", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 1 - }, - "base_class": { - "hex": "000c", - "name": "Serial bus controller", - "value": 12 - }, - "sub_class": { - "hex": "0003", - "name": "USB Controller", - "value": 3 - }, - "pci_interface": { - "hex": "0000", - "name": "UHCI", - "value": 0 - }, - "vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "7020", - "value": 28704 - }, - "sub_device": { - "hex": "1100", - "value": 4352 - }, - "revision": { - "hex": "0001", - "value": 1 - }, - "model": "Intel USB Controller", - "sysfs_id": "/devices/pci0000:00/0000:00:01.2", - "sysfs_bus_id": "0000:00:01.2", - "resources": [ - { - "type": "io", - "base": 49408, - "range": 32, - "enabled": true, - "access": "read_write" - } - ], - "detail": { - "function": 2, - "command": 263, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "uhci_hcd", - "driver_module": "uhci_hcd", - "drivers": ["uhci_hcd"], - "driver_modules": ["uhci_hcd"], - "driver_info": { - "type": "module", - "db_entry_0": ["uhci-hcd"], - "active": true, - "modprobe": true, - "names": ["uhci-hcd"], - "module_args": [""], - "conf": "" - }, - "module_alias": "pci:v00008086d00007020sv00001AF4sd00001100bc0Csc03i00" - } - ] - }, - "smbios": { - "bios": { - "handle": 0, - "vendor": "SeaBIOS", - "version": "1.16.3-debian-1.16.3-2~bpo12+1", - "date": "04/01/2014", - "features": null, - "start_address": "0xe8000", - "rom_size": 65536 - }, - "chassis": [ - { - "handle": 768, - "manufacturer": "QEMU", - "version": "pc-i440fx-9.2", - "chassis_type": { - "hex": "0001", - "name": "Other", - "value": 1 - }, - "lock_present": false, - "bootup_state": { - "hex": "0003", - "name": "Safe", - "value": 3 - }, - "power_state": { - "hex": "0003", - "name": "Safe", - "value": 3 - }, - "thermal_state": { - "hex": "0003", - "name": "Safe", - "value": 3 - }, - "security_state": { - "hex": "0002", - "name": "Unknown", - "value": 2 - }, - "oem": "0x0" - } - ], - "memory_array": [ - { - "handle": 4096, - "location": { - "hex": "0001", - "name": "Other", - "value": 1 - }, - "usage": { - "hex": "0003", - "name": "System memory", - "value": 3 - }, - "ecc": { - "hex": "0006", - "name": "Multi-bit", - "value": 6 - }, - "max_size": "0xbb8000", - "error_handle": 65534, - "slots": 1 - } - ], - "memory_array_mapped_address": [ - { - "handle": 4864, - "array_handle": 4096, - "start_address": "0x0", - "end_address": "0xc0000000", - "part_width": 1 - }, - { - "handle": 4865, - "array_handle": 4096, - "start_address": "0x100000000", - "end_address": "0x32e000000", - "part_width": 1 - } - ], - "memory_device": [ - { - "handle": 4352, - "location": "DIMM 0", - "bank_location": "", - "manufacturer": "QEMU", - "part_number": "", - "array_handle": 4096, - "error_handle": 65534, - "width": 0, - "ecc_bits": 0, - "size": 12288000, - "form_factor": { - "hex": "0009", - "name": "DIMM", - "value": 9 - }, - "set": 0, - "memory_type": { - "hex": "0007", - "name": "RAM", - "value": 7 - }, - "memory_type_details": ["Other"], - "speed": 0 - } - ], - "processor": [ - { - "handle": 1024, - "socket": "CPU 0", - "socket_type": { - "hex": "0001", - "name": "Other", - "value": 1 - }, - "socket_populated": true, - "manufacturer": "QEMU", - "version": "pc-i440fx-9.2", - "part": "", - "processor_type": { - "hex": "0003", - "name": "CPU", - "value": 3 - }, - "processor_family": { - "hex": "00fe", - "name": "Other", - "value": 254 - }, - "processor_status": { - "hex": "0001", - "name": "Enabled", - "value": 1 - }, - "clock_ext": 0, - "clock_max": 2000, - "cache_handle_l1": 0, - "cache_handle_l2": 0, - "cache_handle_l3": 0 - }, - { - "handle": 1025, - "socket": "CPU 1", - "socket_type": { - "hex": "0001", - "name": "Other", - "value": 1 - }, - "socket_populated": true, - "manufacturer": "QEMU", - "version": "pc-i440fx-9.2", - "part": "", - "processor_type": { - "hex": "0003", - "name": "CPU", - "value": 3 - }, - "processor_family": { - "hex": "00fe", - "name": "Other", - "value": 254 - }, - "processor_status": { - "hex": "0001", - "name": "Enabled", - "value": 1 - }, - "clock_ext": 0, - "clock_max": 2000, - "cache_handle_l1": 0, - "cache_handle_l2": 0, - "cache_handle_l3": 0 - }, - { - "handle": 1026, - "socket": "CPU 2", - "socket_type": { - "hex": "0001", - "name": "Other", - "value": 1 - }, - "socket_populated": true, - "manufacturer": "QEMU", - "version": "pc-i440fx-9.2", - "part": "", - "processor_type": { - "hex": "0003", - "name": "CPU", - "value": 3 - }, - "processor_family": { - "hex": "00fe", - "name": "Other", - "value": 254 - }, - "processor_status": { - "hex": "0001", - "name": "Enabled", - "value": 1 - }, - "clock_ext": 0, - "clock_max": 2000, - "cache_handle_l1": 0, - "cache_handle_l2": 0, - "cache_handle_l3": 0 - }, - { - "handle": 1027, - "socket": "CPU 3", - "socket_type": { - "hex": "0001", - "name": "Other", - "value": 1 - }, - "socket_populated": true, - "manufacturer": "QEMU", - "version": "pc-i440fx-9.2", - "part": "", - "processor_type": { - "hex": "0003", - "name": "CPU", - "value": 3 - }, - "processor_family": { - "hex": "00fe", - "name": "Other", - "value": 254 - }, - "processor_status": { - "hex": "0001", - "name": "Enabled", - "value": 1 - }, - "clock_ext": 0, - "clock_max": 2000, - "cache_handle_l1": 0, - "cache_handle_l2": 0, - "cache_handle_l3": 0 - }, - { - "handle": 1028, - "socket": "CPU 4", - "socket_type": { - "hex": "0001", - "name": "Other", - "value": 1 - }, - "socket_populated": true, - "manufacturer": "QEMU", - "version": "pc-i440fx-9.2", - "part": "", - "processor_type": { - "hex": "0003", - "name": "CPU", - "value": 3 - }, - "processor_family": { - "hex": "00fe", - "name": "Other", - "value": 254 - }, - "processor_status": { - "hex": "0001", - "name": "Enabled", - "value": 1 - }, - "clock_ext": 0, - "clock_max": 2000, - "cache_handle_l1": 0, - "cache_handle_l2": 0, - "cache_handle_l3": 0 - }, - { - "handle": 1029, - "socket": "CPU 5", - "socket_type": { - "hex": "0001", - "name": "Other", - "value": 1 - }, - "socket_populated": true, - "manufacturer": "QEMU", - "version": "pc-i440fx-9.2", - "part": "", - "processor_type": { - "hex": "0003", - "name": "CPU", - "value": 3 - }, - "processor_family": { - "hex": "00fe", - "name": "Other", - "value": 254 - }, - "processor_status": { - "hex": "0001", - "name": "Enabled", - "value": 1 - }, - "clock_ext": 0, - "clock_max": 2000, - "cache_handle_l1": 0, - "cache_handle_l2": 0, - "cache_handle_l3": 0 - } - ], - "system": { - "handle": 256, - "manufacturer": "OpenStack Foundation", - "product": "OpenStack Nova", - "version": "19.3.2", - "wake_up": { - "hex": "0006", - "name": "Power Switch", - "value": 6 - } - } - } -} diff --git a/nix/modules/hosts/nixos/pastoria/facter.nix b/nix/modules/hosts/nixos/pastoria/facter.nix deleted file mode 100644 index da7664c3..00000000 --- a/nix/modules/hosts/nixos/pastoria/facter.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.pastoria = {self, ...}: { - hardware.facter.reportPath = self + "/nix/modules/hosts/nixos/pastoria/facter.json"; - }; -} diff --git a/nix/modules/hosts/nixos/pastoria/hostname.nix b/nix/modules/hosts/nixos/pastoria/hostname.nix deleted file mode 100644 index ad0502de..00000000 --- a/nix/modules/hosts/nixos/pastoria/hostname.nix +++ /dev/null @@ -1,6 +0,0 @@ -_: { - flake.nixosModules.pastoria = { - networking.hostName = "pastoria"; - system.stateVersion = "26.05"; - }; -} diff --git a/nix/modules/hosts/nixos/pastoria/k3s.nix b/nix/modules/hosts/nixos/pastoria/k3s.nix deleted file mode 100644 index 575b776c..00000000 --- a/nix/modules/hosts/nixos/pastoria/k3s.nix +++ /dev/null @@ -1,15 +0,0 @@ -_: { - flake.nixosModules.pastoria = { - myNixOs.profile = { - k3s = { - role = "server"; - serverAddr = "https://snowpoint.cute:6443"; - transportInterface = "wg-k3s"; - nodeIP = "10.254.0.2"; - zone = "cloud"; - ingress = true; - }; - swap.size = 4096; - }; - }; -} diff --git a/nix/modules/hosts/nixos/snowpoint/auto-upgrade.nix b/nix/modules/hosts/nixos/snowpoint/auto-upgrade.nix deleted file mode 100644 index b2fec59a..00000000 --- a/nix/modules/hosts/nixos/snowpoint/auto-upgrade.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.snowpoint = { - system.autoUpgrade.dates = "03:30"; - }; -} diff --git a/nix/modules/hosts/nixos/snowpoint/boot.nix b/nix/modules/hosts/nixos/snowpoint/boot.nix deleted file mode 100644 index 71dab561..00000000 --- a/nix/modules/hosts/nixos/snowpoint/boot.nix +++ /dev/null @@ -1,8 +0,0 @@ -_: { - flake.nixosModules.snowpoint = { - boot.loader.grub = { - efiSupport = true; - efiInstallAsRemovable = true; - }; - }; -} diff --git a/nix/modules/hosts/nixos/snowpoint/default.nix b/nix/modules/hosts/nixos/snowpoint/default.nix deleted file mode 100644 index 2026297a..00000000 --- a/nix/modules/hosts/nixos/snowpoint/default.nix +++ /dev/null @@ -1,33 +0,0 @@ -{ - inputs, - self, - ... -}: { - config.flake.nixosConfigurations.snowpoint = inputs.nixpkgs.lib.nixosSystem { - system = "x86_64-linux"; - specialArgs = {inherit inputs self;}; - modules = [ - inputs.disko.nixosModules.disko - inputs.sops-nix.nixosModules.sops - self.nixosModules.default - self.nixosModules.snowpoint - self.nixosModules.disko - self.nixosModules.lvmExt4 - self.nixosModules.backups - self.nixosModules.dataShare - self.nixosModules.k3s - self.nixosModules.mediaShare - self.nixosModules.observability - self.nixosModules.swap - self.nixosModules.wireguardK3s - self.nixosModules.alloy - self.nixosModules.cachefilesd - self.nixosModules.caddy - self.nixosModules.fail2ban - self.nixosModules.prometheusNode - self.nixosModules.syncthing - self.nixosModules.tailscale - self.nixosModules.aly - ]; - }; -} diff --git a/nix/modules/hosts/nixos/snowpoint/disko.nix b/nix/modules/hosts/nixos/snowpoint/disko.nix deleted file mode 100644 index b14afde2..00000000 --- a/nix/modules/hosts/nixos/snowpoint/disko.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.snowpoint = { - myDisko.installDrive = "/dev/vda"; - }; -} diff --git a/nix/modules/hosts/nixos/snowpoint/facter.json b/nix/modules/hosts/nixos/snowpoint/facter.json deleted file mode 100644 index 9633dc45..00000000 --- a/nix/modules/hosts/nixos/snowpoint/facter.json +++ /dev/null @@ -1,2989 +0,0 @@ -{ - "version": 1, - "system": "x86_64-linux", - "virtualisation": "kvm", - "uefi": { - "supported": false - }, - "hardware": { - "bios": { - "apm_info": { - "supported": false, - "enabled": false, - "version": 0, - "sub_version": 0, - "bios_flags": 0 - }, - "vbe_info": { - "version": 0, - "video_memory": 0 - }, - "pnp": true, - "pnp_id": 0, - "lba_support": false, - "low_memory_size": 654336, - "smbios_version": 520 - }, - "bridge": [ - { - "index": 11, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 1 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0001", - "name": "ISA bridge", - "value": 1 - }, - "vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "7000", - "value": 28672 - }, - "sub_device": { - "hex": "1100", - "value": 4352 - }, - "model": "Intel ISA bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:01.0", - "sysfs_bus_id": "0000:00:01.0", - "detail": { - "function": 0, - "command": 259, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00008086d00007000sv00001AF4sd00001100bc06sc01i00" - }, - { - "index": 13, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0000", - "name": "Host bridge", - "value": 0 - }, - "vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "1237", - "value": 4663 - }, - "sub_device": { - "hex": "1100", - "value": 4352 - }, - "revision": { - "hex": "0002", - "value": 2 - }, - "model": "Intel Host bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:00.0", - "sysfs_bus_id": "0000:00:00.0", - "detail": { - "function": 0, - "command": 259, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "module_alias": "pci:v00008086d00001237sv00001AF4sd00001100bc06sc00i00" - }, - { - "index": 14, - "attached_to": 0, - "class_list": ["pci", "bridge"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 1 - }, - "base_class": { - "hex": "0006", - "name": "Bridge", - "value": 6 - }, - "sub_class": { - "hex": "0080", - "name": "Bridge", - "value": 128 - }, - "vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "7113", - "value": 28947 - }, - "sub_device": { - "hex": "1100", - "value": 4352 - }, - "revision": { - "hex": "0003", - "value": 3 - }, - "model": "Intel Bridge", - "sysfs_id": "/devices/pci0000:00/0000:00:01.3", - "sysfs_bus_id": "0000:00:01.3", - "detail": { - "function": 3, - "command": 259, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "piix4_smbus", - "driver_module": "i2c_piix4", - "drivers": ["piix4_smbus"], - "driver_modules": ["i2c_piix4"], - "module_alias": "pci:v00008086d00007113sv00001AF4sd00001100bc06sc80i00" - } - ], - "cdrom": [ - { - "index": 30, - "attached_to": 16, - "class_list": ["cdrom", "scsi", "block_device"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0002", - "name": "CD-ROM", - "value": 2 - }, - "pci_interface": { - "hex": "0003", - "name": "DVD", - "value": 3 - }, - "vendor": { - "hex": "0000", - "name": "QEMU", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "QEMU DVD-ROM", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "2.5+", - "value": 0 - }, - "model": "QEMU DVD-ROM", - "sysfs_id": "/class/block/sr0", - "sysfs_bus_id": "0:0:0:0", - "sysfs_device_link": "/devices/pci0000:00/0000:00:01.1/ata1/host0/target0:0:0/0:0:0:0", - "unix_device_names": [ - "/dev/cdrom", - "/dev/disk/by-id/ata-QEMU_DVD-ROM_QM00001", - "/dev/disk/by-path/pci-0000:00:01.1-ata-1", - "/dev/disk/by-path/pci-0000:00:01.1-ata-1.0", - "/dev/sr0" - ], - "unix_device_name2": "/dev/sg0", - "driver": "ata_piix", - "driver_module": "ata_piix", - "drivers": ["ata_piix", "sr"], - "driver_modules": ["ata_piix", "sr_mod"] - } - ], - "cpu": [ - { - "architecture": "x86_64", - "vendor_name": "AuthenticAMD", - "model_name": "AMD EPYC 9634 84-Core Processor", - "family": 25, - "model": 17, - "stepping": 1, - "features": [ - "fpu", - "vme", - "de", - "pse", - "tsc", - "msr", - "pae", - "mce", - "cx8", - "apic", - "sep", - "mtrr", - "pge", - "mca", - "cmov", - "pat", - "pse36", - "clflush", - "mmx", - "fxsr", - "sse", - "sse2", - "syscall", - "nx", - "mmxext", - "fxsr_opt", - "pdpe1gb", - "rdtscp", - "lm", - "rep_good", - "nopl", - "xtopology", - "cpuid", - "extd_apicid", - "tsc_known_freq", - "pni", - "pclmulqdq", - "ssse3", - "fma", - "cx16", - "pcid", - "sse4_1", - "sse4_2", - "x2apic", - "movbe", - "popcnt", - "tsc_deadline_timer", - "aes", - "xsave", - "avx", - "f16c", - "rdrand", - "hypervisor", - "lahf_lm", - "cmp_legacy", - "cr8_legacy", - "abm", - "sse4a", - "misalignsse", - "3dnowprefetch", - "osvw", - "perfctr_core", - "ssbd", - "perfmon_v2", - "ibrs", - "ibpb", - "stibp", - "ibrs_enhanced", - "vmmcall", - "fsgsbase", - "tsc_adjust", - "bmi1", - "avx2", - "smep", - "bmi2", - "erms", - "invpcid", - "avx512f", - "avx512dq", - "rdseed", - "adx", - "smap", - "avx512ifma", - "clflushopt", - "clwb", - "avx512cd", - "sha_ni", - "avx512bw", - "avx512vl", - "xsaveopt", - "xsavec", - "xgetbv1", - "xsaves", - "avx512_bf16", - "clzero", - "xsaveerptr", - "wbnoinvd", - "arat", - "avx512vbmi", - "umip", - "pku", - "ospke", - "avx512_vbmi2", - "gfni", - "vaes", - "vpclmulqdq", - "avx512_vnni", - "avx512_bitalg", - "avx512_vpopcntdq", - "la57", - "rdpid", - "overflow_recov", - "succor", - "fsrm", - "flush_l1d", - "arch_capabilities" - ], - "bugs": [ - "sysret_ss_attrs", - "spectre_v1", - "spectre_v2", - "spec_store_bypass", - "srso", - "ibpb_no_ret", - "spectre_v2_user", - "tsa" - ], - "power_management": [""], - "bogo": 4493, - "cache": 512, - "page_size": 4096, - "physical_id": 0, - "siblings": 1, - "cores": 1, - "fpu": false, - "fpu_exception": false, - "cpuid_level": 16, - "write_protect": false, - "tlb_size": 1024, - "clflush_size": 64, - "cache_alignment": 64, - "address_sizes": { - "physical": "0x34", - "virtual": "0x39" - } - }, - { - "architecture": "x86_64", - "vendor_name": "AuthenticAMD", - "model_name": "AMD EPYC 9634 84-Core Processor", - "family": 25, - "model": 17, - "stepping": 1, - "features": [ - "fpu", - "vme", - "de", - "pse", - "tsc", - "msr", - "pae", - "mce", - "cx8", - "apic", - "sep", - "mtrr", - "pge", - "mca", - "cmov", - "pat", - "pse36", - "clflush", - "mmx", - "fxsr", - "sse", - "sse2", - "syscall", - "nx", - "mmxext", - "fxsr_opt", - "pdpe1gb", - "rdtscp", - "lm", - "rep_good", - "nopl", - "xtopology", - "cpuid", - "extd_apicid", - "tsc_known_freq", - "pni", - "pclmulqdq", - "ssse3", - "fma", - "cx16", - "pcid", - "sse4_1", - "sse4_2", - "x2apic", - "movbe", - "popcnt", - "tsc_deadline_timer", - "aes", - "xsave", - "avx", - "f16c", - "rdrand", - "hypervisor", - "lahf_lm", - "cmp_legacy", - "cr8_legacy", - "abm", - "sse4a", - "misalignsse", - "3dnowprefetch", - "osvw", - "perfctr_core", - "ssbd", - "perfmon_v2", - "ibrs", - "ibpb", - "stibp", - "ibrs_enhanced", - "vmmcall", - "fsgsbase", - "tsc_adjust", - "bmi1", - "avx2", - "smep", - "bmi2", - "erms", - "invpcid", - "avx512f", - "avx512dq", - "rdseed", - "adx", - "smap", - "avx512ifma", - "clflushopt", - "clwb", - "avx512cd", - "sha_ni", - "avx512bw", - "avx512vl", - "xsaveopt", - "xsavec", - "xgetbv1", - "xsaves", - "avx512_bf16", - "clzero", - "xsaveerptr", - "wbnoinvd", - "arat", - "avx512vbmi", - "umip", - "pku", - "ospke", - "avx512_vbmi2", - "gfni", - "vaes", - "vpclmulqdq", - "avx512_vnni", - "avx512_bitalg", - "avx512_vpopcntdq", - "la57", - "rdpid", - "overflow_recov", - "succor", - "fsrm", - "flush_l1d", - "arch_capabilities" - ], - "bugs": [ - "sysret_ss_attrs", - "spectre_v1", - "spectre_v2", - "spec_store_bypass", - "srso", - "ibpb_no_ret", - "spectre_v2_user", - "tsa" - ], - "power_management": [""], - "bogo": 4493, - "cache": 512, - "page_size": 4096, - "physical_id": 1, - "siblings": 1, - "cores": 1, - "fpu": false, - "fpu_exception": false, - "cpuid_level": 16, - "write_protect": false, - "tlb_size": 1024, - "clflush_size": 64, - "cache_alignment": 64, - "address_sizes": { - "physical": "0x34", - "virtual": "0x39" - } - }, - { - "architecture": "x86_64", - "vendor_name": "AuthenticAMD", - "model_name": "AMD EPYC 9634 84-Core Processor", - "family": 25, - "model": 17, - "stepping": 1, - "features": [ - "fpu", - "vme", - "de", - "pse", - "tsc", - "msr", - "pae", - "mce", - "cx8", - "apic", - "sep", - "mtrr", - "pge", - "mca", - "cmov", - "pat", - "pse36", - "clflush", - "mmx", - "fxsr", - "sse", - "sse2", - "syscall", - "nx", - "mmxext", - "fxsr_opt", - "pdpe1gb", - "rdtscp", - "lm", - "rep_good", - "nopl", - "xtopology", - "cpuid", - "extd_apicid", - "tsc_known_freq", - "pni", - "pclmulqdq", - "ssse3", - "fma", - "cx16", - "pcid", - "sse4_1", - "sse4_2", - "x2apic", - "movbe", - "popcnt", - "tsc_deadline_timer", - "aes", - "xsave", - "avx", - "f16c", - "rdrand", - "hypervisor", - "lahf_lm", - "cmp_legacy", - "cr8_legacy", - "abm", - "sse4a", - "misalignsse", - "3dnowprefetch", - "osvw", - "perfctr_core", - "ssbd", - "perfmon_v2", - "ibrs", - "ibpb", - "stibp", - "ibrs_enhanced", - "vmmcall", - "fsgsbase", - "tsc_adjust", - "bmi1", - "avx2", - "smep", - "bmi2", - "erms", - "invpcid", - "avx512f", - "avx512dq", - "rdseed", - "adx", - "smap", - "avx512ifma", - "clflushopt", - "clwb", - "avx512cd", - "sha_ni", - "avx512bw", - "avx512vl", - "xsaveopt", - "xsavec", - "xgetbv1", - "xsaves", - "avx512_bf16", - "clzero", - "xsaveerptr", - "wbnoinvd", - "arat", - "avx512vbmi", - "umip", - "pku", - "ospke", - "avx512_vbmi2", - "gfni", - "vaes", - "vpclmulqdq", - "avx512_vnni", - "avx512_bitalg", - "avx512_vpopcntdq", - "la57", - "rdpid", - "overflow_recov", - "succor", - "fsrm", - "flush_l1d", - "arch_capabilities" - ], - "bugs": [ - "sysret_ss_attrs", - "spectre_v1", - "spectre_v2", - "spec_store_bypass", - "srso", - "ibpb_no_ret", - "spectre_v2_user", - "tsa" - ], - "power_management": [""], - "bogo": 4493, - "cache": 512, - "page_size": 4096, - "physical_id": 2, - "siblings": 1, - "cores": 1, - "fpu": false, - "fpu_exception": false, - "cpuid_level": 16, - "write_protect": false, - "tlb_size": 1024, - "clflush_size": 64, - "cache_alignment": 64, - "address_sizes": { - "physical": "0x34", - "virtual": "0x39" - } - }, - { - "architecture": "x86_64", - "vendor_name": "AuthenticAMD", - "model_name": "AMD EPYC 9634 84-Core Processor", - "family": 25, - "model": 17, - "stepping": 1, - "features": [ - "fpu", - "vme", - "de", - "pse", - "tsc", - "msr", - "pae", - "mce", - "cx8", - "apic", - "sep", - "mtrr", - "pge", - "mca", - "cmov", - "pat", - "pse36", - "clflush", - "mmx", - "fxsr", - "sse", - "sse2", - "syscall", - "nx", - "mmxext", - "fxsr_opt", - "pdpe1gb", - "rdtscp", - "lm", - "rep_good", - "nopl", - "xtopology", - "cpuid", - "extd_apicid", - "tsc_known_freq", - "pni", - "pclmulqdq", - "ssse3", - "fma", - "cx16", - "pcid", - "sse4_1", - "sse4_2", - "x2apic", - "movbe", - "popcnt", - "tsc_deadline_timer", - "aes", - "xsave", - "avx", - "f16c", - "rdrand", - "hypervisor", - "lahf_lm", - "cmp_legacy", - "cr8_legacy", - "abm", - "sse4a", - "misalignsse", - "3dnowprefetch", - "osvw", - "perfctr_core", - "ssbd", - "perfmon_v2", - "ibrs", - "ibpb", - "stibp", - "ibrs_enhanced", - "vmmcall", - "fsgsbase", - "tsc_adjust", - "bmi1", - "avx2", - "smep", - "bmi2", - "erms", - "invpcid", - "avx512f", - "avx512dq", - "rdseed", - "adx", - "smap", - "avx512ifma", - "clflushopt", - "clwb", - "avx512cd", - "sha_ni", - "avx512bw", - "avx512vl", - "xsaveopt", - "xsavec", - "xgetbv1", - "xsaves", - "avx512_bf16", - "clzero", - "xsaveerptr", - "wbnoinvd", - "arat", - "avx512vbmi", - "umip", - "pku", - "ospke", - "avx512_vbmi2", - "gfni", - "vaes", - "vpclmulqdq", - "avx512_vnni", - "avx512_bitalg", - "avx512_vpopcntdq", - "la57", - "rdpid", - "overflow_recov", - "succor", - "fsrm", - "flush_l1d", - "arch_capabilities" - ], - "bugs": [ - "sysret_ss_attrs", - "spectre_v1", - "spectre_v2", - "spec_store_bypass", - "srso", - "ibpb_no_ret", - "spectre_v2_user", - "tsa" - ], - "power_management": [""], - "bogo": 4493, - "cache": 512, - "page_size": 4096, - "physical_id": 3, - "siblings": 1, - "cores": 1, - "fpu": false, - "fpu_exception": false, - "cpuid_level": 16, - "write_protect": false, - "tlb_size": 1024, - "clflush_size": 64, - "cache_alignment": 64, - "address_sizes": { - "physical": "0x34", - "virtual": "0x39" - } - } - ], - "disk": [ - { - "index": 28, - "attached_to": 22, - "class_list": ["disk", "scsi", "block_device"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 5, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "VIRTUAL-DISK", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "serial": "beaf41", - "model": "IET VIRTUAL-DISK", - "sysfs_id": "/class/block/sdd", - "sysfs_bus_id": "5:0:0:1", - "sysfs_device_link": "/devices/platform/host5/session4/target5:0:0/5:0:0:1", - "unix_device_names": [ - "/dev/disk/by-id/scsi-360000000000000000e00000000040001", - "/dev/disk/by-id/wwn-0x60000000000000000e00000000040001", - "/dev/disk/by-path/ip-10.42.4.226:3260-iscsi-iqn.2019-10.io.longhorn:pvc-0802a8cb-8cd4-48c0-b61f-0b8825c97ea1-lun-1", - "/dev/disk/by-uuid/9ecc1c30-912a-4e4f-b107-01edc8dcdeaa", - "/dev/sdd" - ], - "unix_device_name2": "/dev/sg8", - "resources": [ - { - "type": "disk_geo", - "cylinders": 1022, - "heads": 9, - "sectors": 57, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 524288, - "value_2": 512 - } - ], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp", "sd"], - "driver_modules": ["iscsi-tcp", "sd_mod"] - }, - { - "index": 29, - "attached_to": 23, - "class_list": ["disk", "scsi", "block_device"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 3, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "VIRTUAL-DISK", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "serial": "beaf21", - "model": "IET VIRTUAL-DISK", - "sysfs_id": "/class/block/sdb", - "sysfs_bus_id": "3:0:0:1", - "sysfs_device_link": "/devices/platform/host3/session2/target3:0:0/3:0:0:1", - "unix_device_names": [ - "/dev/disk/by-id/scsi-360000000000000000e00000000020001", - "/dev/disk/by-id/wwn-0x60000000000000000e00000000020001", - "/dev/disk/by-path/ip-10.42.4.226:3260-iscsi-iqn.2019-10.io.longhorn:pvc-ab067438-616c-445e-a28e-ce14bf7213b7-lun-1", - "/dev/disk/by-uuid/ae52a7cd-a915-4367-8881-4180de2167b3", - "/dev/sdb" - ], - "unix_device_name2": "/dev/sg4", - "resources": [ - { - "type": "disk_geo", - "cylinders": 1011, - "heads": 34, - "sectors": 61, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 2097152, - "value_2": 512 - } - ], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp", "sd"], - "driver_modules": ["iscsi-tcp", "sd_mod"] - }, - { - "index": 31, - "attached_to": 24, - "class_list": ["disk", "scsi", "block_device"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 6, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "VIRTUAL-DISK", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "serial": "beaf51", - "model": "IET VIRTUAL-DISK", - "sysfs_id": "/class/block/sde", - "sysfs_bus_id": "6:0:0:1", - "sysfs_device_link": "/devices/platform/host6/session5/target6:0:0/6:0:0:1", - "unix_device_names": [ - "/dev/disk/by-id/scsi-360000000000000000e00000000050001", - "/dev/disk/by-id/wwn-0x60000000000000000e00000000050001", - "/dev/disk/by-path/ip-10.42.4.226:3260-iscsi-iqn.2019-10.io.longhorn:pvc-8b48176d-922e-405a-aa05-ebfcad013516-lun-1", - "/dev/disk/by-uuid/8211890d-2f1f-46af-abad-7428f02cc9e6", - "/dev/sde" - ], - "unix_device_name2": "/dev/sg10", - "resources": [ - { - "type": "disk_geo", - "cylinders": 1009, - "heads": 67, - "sectors": 62, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 4194304, - "value_2": 512 - } - ], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp", "sd"], - "driver_modules": ["iscsi-tcp", "sd_mod"] - }, - { - "index": 32, - "attached_to": 25, - "class_list": ["disk", "scsi", "block_device"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 4, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "VIRTUAL-DISK", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "serial": "beaf31", - "model": "IET VIRTUAL-DISK", - "sysfs_id": "/class/block/sdc", - "sysfs_bus_id": "4:0:0:1", - "sysfs_device_link": "/devices/platform/host4/session3/target4:0:0/4:0:0:1", - "unix_device_names": [ - "/dev/disk/by-id/scsi-360000000000000000e00000000030001", - "/dev/disk/by-id/wwn-0x60000000000000000e00000000030001", - "/dev/disk/by-path/ip-10.42.4.226:3260-iscsi-iqn.2019-10.io.longhorn:pvc-113fa385-29f3-4122-8825-d55983bf7cd9-lun-1", - "/dev/disk/by-uuid/9a322a77-71c7-4b2e-9041-281896e3ddc6", - "/dev/sdc" - ], - "unix_device_name2": "/dev/sg6", - "resources": [ - { - "type": "disk_geo", - "cylinders": 1009, - "heads": 67, - "sectors": 62, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 4194304, - "value_2": 512 - } - ], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp", "sd"], - "driver_modules": ["iscsi-tcp", "sd_mod"] - }, - { - "index": 33, - "attached_to": 26, - "class_list": ["disk", "scsi", "block_device"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 2, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "VIRTUAL-DISK", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "serial": "beaf11", - "model": "IET VIRTUAL-DISK", - "sysfs_id": "/class/block/sda", - "sysfs_bus_id": "2:0:0:1", - "sysfs_device_link": "/devices/platform/host2/session1/target2:0:0/2:0:0:1", - "unix_device_names": [ - "/dev/disk/by-id/scsi-360000000000000000e00000000010001", - "/dev/disk/by-id/wwn-0x60000000000000000e00000000010001", - "/dev/disk/by-path/ip-10.42.4.226:3260-iscsi-iqn.2019-10.io.longhorn:pvc-043020b2-9bf3-4547-8751-74972661051f-lun-1", - "/dev/disk/by-uuid/bf8e2874-f54e-4242-959d-9cf0bcced14b", - "/dev/sda" - ], - "unix_device_name2": "/dev/sg2", - "resources": [ - { - "type": "disk_geo", - "cylinders": 1011, - "heads": 34, - "sectors": 61, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 2097152, - "value_2": 512 - } - ], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp", "sd"], - "driver_modules": ["iscsi-tcp", "sd_mod"] - }, - { - "index": 34, - "attached_to": 0, - "class_list": ["disk", "block_device"], - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "model": "Disk", - "sysfs_id": "/class/block/zram0", - "unix_device_names": [ - "/dev/disk/by-label/zram0", - "/dev/disk/by-uuid/6d4a842a-2e5e-49b8-972d-159e27b4646a", - "/dev/zram0" - ], - "resources": [ - { - "type": "size", - "unit": "sectors", - "value_1": 1016448, - "value_2": 4096 - } - ] - }, - { - "index": 35, - "attached_to": 18, - "class_list": ["disk", "block_device"], - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0000", - "name": "Disk", - "value": 0 - }, - "model": "Disk", - "sysfs_id": "/class/block/vda", - "sysfs_bus_id": "virtio1", - "sysfs_device_link": "/devices/pci0000:00/0000:00:10.0/virtio1", - "unix_device_names": [ - "/dev/disk/by-path/pci-0000:00:10.0", - "/dev/disk/by-path/virtio-pci-0000:00:10.0", - "/dev/vda" - ], - "resources": [ - { - "type": "disk_geo", - "cylinders": 532610, - "heads": 16, - "sectors": 63, - "size": "0x0", - "geo_type": "logical" - }, - { - "type": "size", - "unit": "sectors", - "value_1": 536870912, - "value_2": 512 - } - ], - "driver": "virtio-pci", - "driver_module": "virtio_pci", - "drivers": ["virtio-pci", "virtio_blk"], - "driver_modules": ["virtio_blk", "virtio_pci"] - } - ], - "graphics_card": [ - { - "index": 17, - "attached_to": 0, - "class_list": ["graphics_card", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 2 - }, - "base_class": { - "hex": "0003", - "name": "Display controller", - "value": 3 - }, - "sub_class": { - "hex": "0000", - "name": "VGA compatible controller", - "value": 0 - }, - "pci_interface": { - "hex": "0000", - "name": "VGA", - "value": 0 - }, - "vendor": { - "hex": "1234", - "value": 4660 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "1111", - "value": 4369 - }, - "sub_device": { - "hex": "1100", - "value": 4352 - }, - "revision": { - "hex": "0002", - "value": 2 - }, - "model": "VGA compatible controller", - "sysfs_id": "/devices/pci0000:00/0000:00:02.0", - "sysfs_bus_id": "0000:00:02.0", - "detail": { - "function": 0, - "command": 259, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "bochs-drm", - "driver_module": "bochs", - "drivers": ["bochs-drm"], - "driver_modules": ["bochs"], - "module_alias": "pci:v00001234d00001111sv00001AF4sd00001100bc03sc00i00" - } - ], - "hub": [ - { - "index": 41, - "attached_to": 9, - "class_list": ["usb", "hub"], - "bus_type": { - "hex": "0086", - "name": "USB", - "value": 134 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "010a", - "name": "Hub", - "value": 266 - }, - "vendor": { - "hex": "1d6b", - "name": "Linux 6.18.44 uhci_hcd", - "value": 7531 - }, - "device": { - "hex": "0001", - "name": "UHCI Host Controller", - "value": 1 - }, - "revision": { - "hex": "0000", - "name": "6.18", - "value": 0 - }, - "serial": "0000:00:01.2", - "model": "Linux 6.18.44 uhci_hcd UHCI Host Controller", - "sysfs_id": "/devices/pci0000:00/0000:00:01.2/usb1/1-0:1.0", - "sysfs_bus_id": "1-0:1.0", - "resources": [ - { - "type": "baud", - "speed": 12000000, - "bits": 0, - "stop_bits": 0, - "parity": 0, - "handshake": 0 - } - ], - "detail": { - "device_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "device_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "device_protocol": 0, - "interface_class": { - "hex": "0009", - "name": "hub", - "value": 9 - }, - "interface_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "interface_protocol": 0, - "interface_number": 0, - "interface_alternate_setting": 0 - }, - "hotplug": "usb", - "driver": "hub", - "driver_module": "usbcore", - "drivers": ["hub"], - "driver_modules": ["usbcore"], - "module_alias": "usb:v1D6Bp0001d0618dc09dsc00dp00ic09isc00ip00in00" - } - ], - "memory": [ - { - "index": 7, - "attached_to": 0, - "class_list": ["memory"], - "base_class": { - "hex": "0101", - "name": "Internally Used Class", - "value": 257 - }, - "sub_class": { - "hex": "0002", - "name": "Main Memory", - "value": 2 - }, - "model": "Main Memory", - "resources": [ - { - "type": "phys_mem", - "range": 8589934592 - } - ] - } - ], - "monitor": [ - { - "index": 27, - "attached_to": 17, - "class_list": ["monitor"], - "base_class": { - "hex": "0100", - "name": "Monitor", - "value": 256 - }, - "sub_class": { - "hex": "0002", - "name": "LCD Monitor", - "value": 2 - }, - "vendor": { - "hex": "4914", - "value": 18708 - }, - "device": { - "hex": "1234", - "name": "QEMU Monitor", - "value": 4660 - }, - "serial": "0", - "model": "QEMU Monitor", - "resources": [ - { - "type": "monitor", - "width": 1024, - "height": 768, - "vertical_frequency": 60, - "interlaced": false - }, - { - "type": "monitor", - "width": 1280, - "height": 800, - "vertical_frequency": 60, - "interlaced": false - }, - { - "type": "monitor", - "width": 1600, - "height": 1200, - "vertical_frequency": 60, - "interlaced": false - }, - { - "type": "monitor", - "width": 1920, - "height": 1080, - "vertical_frequency": 60, - "interlaced": false - }, - { - "type": "monitor", - "width": 2048, - "height": 1152, - "vertical_frequency": 60, - "interlaced": false - }, - { - "type": "monitor", - "width": 640, - "height": 480, - "vertical_frequency": 60, - "interlaced": false - }, - { - "type": "monitor", - "width": 800, - "height": 600, - "vertical_frequency": 60, - "interlaced": false - }, - { - "type": "size", - "unit": "mm", - "value_1": 325, - "value_2": 203 - } - ], - "detail": { - "manufacture_year": 2014, - "manufacture_week": 42, - "vertical_sync": { - "min": 50, - "max": 125 - }, - "horizontal_sync": { - "min": 30, - "max": 160 - }, - "horizontal_sync_timings": { - "disp": 1280, - "sync_start": 1600, - "sync_end": 1638, - "total": 1728 - }, - "vertical_sync_timings": { - "disp": 800, - "sync_start": 804, - "sync_end": 808, - "total": 828 - }, - "clock": 107300, - "width": 1280, - "height": 800, - "width_millimetres": 325, - "height_millimetres": 203, - "horizontal_flag": 45, - "vertical_flag": 45, - "vendor": "", - "name": "QEMU Monitor" - }, - "driver_info": { - "type": "display", - "width": 2048, - "height": 1152, - "vertical_sync": { - "min": 50, - "max": 125 - }, - "horizontal_sync": { - "min": 30, - "max": 160 - }, - "bandwidth": 0, - "horizontal_sync_timings": { - "disp": 1280, - "sync_start": 1600, - "sync_end": 1638, - "total": 1728 - }, - "vertical_sync_timings": { - "disp": 800, - "sync_start": 804, - "sync_end": 808, - "total": 828 - }, - "horizontal_flag": 45, - "vertical_flag": 45 - } - } - ], - "mouse": [ - { - "index": 42, - "attached_to": 41, - "class_list": ["mouse", "usb"], - "bus_type": { - "hex": "0086", - "name": "USB", - "value": 134 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "0105", - "name": "Mouse", - "value": 261 - }, - "sub_class": { - "hex": "0003", - "name": "USB Mouse", - "value": 3 - }, - "vendor": { - "hex": "0627", - "name": "QEMU", - "value": 1575 - }, - "device": { - "hex": "0001", - "name": "QEMU USB Tablet", - "value": 1 - }, - "serial": "28754-0000:00:01.2-1", - "compat_vendor": "Unknown", - "compat_device": "Generic USB Mouse", - "model": "QEMU USB Tablet", - "sysfs_id": "/devices/pci0000:00/0000:00:01.2/usb1/1-1/1-1:1.0", - "sysfs_bus_id": "1-1:1.0", - "unix_device_names": ["/dev/input/mice"], - "unix_device_name2": "/dev/input/mouse0", - "resources": [ - { - "type": "baud", - "speed": 12000000, - "bits": 0, - "stop_bits": 0, - "parity": 0, - "handshake": 0 - } - ], - "detail": { - "device_class": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "device_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "device_protocol": 0, - "interface_class": { - "hex": "0003", - "name": "hid", - "value": 3 - }, - "interface_subclass": { - "hex": "0000", - "name": "per_interface", - "value": 0 - }, - "interface_protocol": 0, - "interface_number": 0, - "interface_alternate_setting": 0 - }, - "hotplug": "usb", - "driver": "usbhid", - "driver_module": "usbhid", - "drivers": ["usbhid"], - "driver_modules": ["usbhid"], - "driver_info": { - "type": "mouse", - "db_entry_0": ["explorerps/2", "exps2"], - "xf86": "explorerps/2", - "gpm": "exps2", - "buttons": -1, - "wheels": -1 - }, - "module_alias": "usb:v0627p0001d0000dc00dsc00dp00ic03isc00ip00in00" - } - ], - "network_controller": [ - { - "index": 20, - "attached_to": 15, - "class_list": ["network_controller"], - "bus_type": { - "hex": "008f", - "name": "Virtio", - "value": 143 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "0002", - "name": "Network controller", - "value": 2 - }, - "sub_class": { - "hex": "0000", - "name": "Ethernet controller", - "value": 0 - }, - "vendor": "Virtio", - "device": "Ethernet Card 0", - "model": "Virtio Ethernet Card 0", - "sysfs_id": "/devices/pci0000:00/0000:00:03.0/virtio0", - "sysfs_bus_id": "virtio0", - "unix_device_names": ["ens3"], - "resources": [ - { - "type": "hwaddr", - "address": 100 - }, - { - "type": "phwaddr", - "address": 100 - } - ], - "driver": "virtio_net", - "driver_module": "virtio_net", - "drivers": ["virtio_net"], - "driver_modules": ["virtio_net"], - "module_alias": "virtio:d00000001v00001AF4" - } - ], - "network_interface": [ - { - "index": 73, - "attached_to": 20, - "class_list": ["network_interface"], - "base_class": { - "hex": "0107", - "name": "Network Interface", - "value": 263 - }, - "sub_class": { - "hex": "0001", - "name": "Ethernet", - "value": 1 - }, - "model": "Ethernet network interface", - "sysfs_id": "/class/net/ens3", - "sysfs_device_link": "/devices/pci0000:00/0000:00:03.0/virtio0", - "unix_device_names": ["ens3"], - "resources": [ - { - "type": "hwaddr", - "address": 100 - }, - { - "type": "phwaddr", - "address": 100 - } - ], - "driver": "virtio_net", - "driver_module": "virtio_net", - "drivers": ["virtio_net"], - "driver_modules": ["virtio_net"] - }, - { - "index": 74, - "attached_to": 0, - "class_list": ["network_interface"], - "base_class": { - "hex": "0107", - "name": "Network Interface", - "value": 263 - }, - "sub_class": { - "hex": "0000", - "name": "Loopback", - "value": 0 - }, - "model": "Loopback network interface", - "sysfs_id": "/class/net/lo", - "unix_device_names": ["lo"] - } - ], - "pci": [ - { - "index": 8, - "attached_to": 0, - "class_list": ["pci", "unknown"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 28 - }, - "base_class": { - "hex": "0007", - "name": "Communication controller", - "value": 7 - }, - "sub_class": { - "hex": "0080", - "name": "Communication controller", - "value": 128 - }, - "vendor": { - "hex": "1af4", - "value": 6900 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "1003", - "value": 4099 - }, - "sub_device": { - "hex": "0003", - "value": 3 - }, - "model": "Communication controller", - "sysfs_id": "/devices/pci0000:00/0000:00:1c.0", - "sysfs_bus_id": "0000:00:1c.0", - "resources": [ - { - "type": "io", - "base": 49344, - "range": 64, - "enabled": true, - "access": "read_write" - } - ], - "detail": { - "function": 0, - "command": 1287, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "virtio-pci", - "driver_module": "virtio_pci", - "drivers": ["virtio-pci"], - "driver_modules": ["virtio_pci"], - "module_alias": "pci:v00001AF4d00001003sv00001AF4sd00000003bc07sc80i00" - }, - { - "index": 10, - "attached_to": 0, - "class_list": ["pci", "unknown"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 16 - }, - "base_class": { - "hex": "0001", - "name": "Mass storage controller", - "value": 1 - }, - "sub_class": { - "hex": "0000", - "name": "SCSI storage controller", - "value": 0 - }, - "vendor": { - "hex": "1af4", - "value": 6900 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "1001", - "value": 4097 - }, - "sub_device": { - "hex": "0002", - "value": 2 - }, - "model": "SCSI storage controller", - "sysfs_id": "/devices/pci0000:00/0000:00:10.0", - "sysfs_bus_id": "0000:00:10.0", - "resources": [ - { - "type": "io", - "base": 49152, - "range": 128, - "enabled": true, - "access": "read_write" - } - ], - "detail": { - "function": 0, - "command": 1287, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "virtio-pci", - "driver_module": "virtio_pci", - "drivers": ["virtio-pci"], - "driver_modules": ["virtio_pci"], - "module_alias": "pci:v00001AF4d00001001sv00001AF4sd00000002bc01sc00i00" - }, - { - "index": 12, - "attached_to": 0, - "class_list": ["pci", "unknown"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 30 - }, - "base_class": { - "hex": "0000", - "name": "Unclassified device", - "value": 0 - }, - "sub_class": { - "hex": "00ff", - "value": 255 - }, - "vendor": { - "hex": "1af4", - "value": 6900 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "1002", - "value": 4098 - }, - "sub_device": { - "hex": "0005", - "value": 5 - }, - "model": "Unclassified device", - "sysfs_id": "/devices/pci0000:00/0000:00:1e.0", - "sysfs_bus_id": "0000:00:1e.0", - "resources": [ - { - "type": "io", - "base": 49408, - "range": 64, - "enabled": true, - "access": "read_write" - } - ], - "detail": { - "function": 0, - "command": 263, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "virtio-pci", - "driver_module": "virtio_pci", - "drivers": ["virtio-pci"], - "driver_modules": ["virtio_pci"], - "module_alias": "pci:v00001AF4d00001002sv00001AF4sd00000005bc00scFFi00" - }, - { - "index": 15, - "attached_to": 0, - "class_list": ["pci", "unknown"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 3 - }, - "base_class": { - "hex": "0002", - "name": "Network controller", - "value": 2 - }, - "sub_class": { - "hex": "0000", - "name": "Ethernet controller", - "value": 0 - }, - "vendor": { - "hex": "1af4", - "value": 6900 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "1000", - "value": 4096 - }, - "sub_device": { - "hex": "0001", - "value": 1 - }, - "model": "Ethernet controller", - "sysfs_id": "/devices/pci0000:00/0000:00:03.0", - "sysfs_bus_id": "0000:00:03.0", - "resources": [ - { - "type": "io", - "base": 49280, - "range": 64, - "enabled": true, - "access": "read_write" - } - ], - "detail": { - "function": 0, - "command": 1287, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "virtio-pci", - "driver_module": "virtio_pci", - "drivers": ["virtio-pci"], - "driver_modules": ["virtio_pci"], - "module_alias": "pci:v00001AF4d00001000sv00001AF4sd00000001bc02sc00i00" - } - ], - "scsi": [ - { - "index": 36, - "attached_to": 24, - "class_list": ["scsi", "block_device", "unknown"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 6, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0080", - "name": "Storage Device", - "value": 128 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "Controller", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "model": "IET Controller", - "sysfs_id": "/class/scsi_generic/sg9", - "sysfs_bus_id": "6:0:0:0", - "unix_device_names": ["/dev/sg9"], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"] - }, - { - "index": 37, - "attached_to": 22, - "class_list": ["scsi", "block_device", "unknown"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 5, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0080", - "name": "Storage Device", - "value": 128 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "Controller", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "model": "IET Controller", - "sysfs_id": "/class/scsi_generic/sg7", - "sysfs_bus_id": "5:0:0:0", - "unix_device_names": ["/dev/sg7"], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"] - }, - { - "index": 38, - "attached_to": 25, - "class_list": ["scsi", "block_device", "unknown"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 4, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0080", - "name": "Storage Device", - "value": 128 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "Controller", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "model": "IET Controller", - "sysfs_id": "/class/scsi_generic/sg5", - "sysfs_bus_id": "4:0:0:0", - "unix_device_names": ["/dev/sg5"], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"] - }, - { - "index": 39, - "attached_to": 23, - "class_list": ["scsi", "block_device", "unknown"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 3, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0080", - "name": "Storage Device", - "value": 128 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "Controller", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "model": "IET Controller", - "sysfs_id": "/class/scsi_generic/sg3", - "sysfs_bus_id": "3:0:0:0", - "unix_device_names": ["/dev/sg3"], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"] - }, - { - "index": 40, - "attached_to": 26, - "class_list": ["scsi", "block_device", "unknown"], - "bus_type": { - "hex": "0084", - "name": "SCSI", - "value": 132 - }, - "slot": { - "bus": 2, - "number": 0 - }, - "base_class": { - "hex": "0106", - "name": "Mass Storage Device", - "value": 262 - }, - "sub_class": { - "hex": "0080", - "name": "Storage Device", - "value": 128 - }, - "vendor": { - "hex": "0000", - "name": "IET", - "value": 0 - }, - "device": { - "hex": "0000", - "name": "Controller", - "value": 0 - }, - "revision": { - "hex": "0000", - "name": "0001", - "value": 0 - }, - "model": "IET Controller", - "sysfs_id": "/class/scsi_generic/sg1", - "sysfs_bus_id": "2:0:0:0", - "unix_device_names": ["/dev/sg1"], - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"] - } - ], - "storage_controller": [ - { - "index": 16, - "attached_to": 0, - "class_list": ["storage_controller", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 1 - }, - "base_class": { - "hex": "0001", - "name": "Mass storage controller", - "value": 1 - }, - "sub_class": { - "hex": "0001", - "name": "IDE interface", - "value": 1 - }, - "pci_interface": { - "hex": "0080", - "value": 128 - }, - "vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "7010", - "value": 28688 - }, - "sub_device": { - "hex": "1100", - "value": 4352 - }, - "model": "Intel IDE interface", - "sysfs_id": "/devices/pci0000:00/0000:00:01.1", - "sysfs_bus_id": "0000:00:01.1", - "resources": [ - { - "type": "io", - "base": 1014, - "range": 1, - "enabled": true, - "access": "read_write" - }, - { - "type": "io", - "base": 368, - "range": 8, - "enabled": true, - "access": "read_write" - }, - { - "type": "io", - "base": 49504, - "range": 16, - "enabled": true, - "access": "read_write" - }, - { - "type": "io", - "base": 496, - "range": 8, - "enabled": true, - "access": "read_write" - }, - { - "type": "io", - "base": 886, - "range": 1, - "enabled": true, - "access": "read_write" - } - ], - "detail": { - "function": 1, - "command": 263, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 128 - }, - "driver": "ata_piix", - "driver_module": "ata_piix", - "drivers": ["ata_piix"], - "driver_modules": ["ata_piix"], - "module_alias": "pci:v00008086d00007010sv00001AF4sd00001100bc01sc01i80" - }, - { - "index": 18, - "attached_to": 10, - "class_list": ["storage_controller"], - "bus_type": { - "hex": "008f", - "name": "Virtio", - "value": 143 - }, - "slot": { - "bus": 0, - "number": 0 - }, - "base_class": { - "hex": "0001", - "name": "Mass storage controller", - "value": 1 - }, - "sub_class": { - "hex": "0080", - "name": "Storage controller", - "value": 128 - }, - "vendor": "Virtio", - "device": "Storage 0", - "model": "Virtio Storage 0", - "sysfs_id": "/devices/pci0000:00/0000:00:10.0/virtio1", - "sysfs_bus_id": "virtio1", - "driver": "virtio_blk", - "driver_module": "virtio_blk", - "drivers": ["virtio_blk"], - "driver_modules": ["virtio_blk"], - "module_alias": "virtio:d00000002v00001AF4" - }, - { - "index": 22, - "attached_to": 0, - "class_list": ["storage_controller"], - "base_class": { - "hex": "011a", - "name": "iSCSI controller", - "value": 282 - }, - "vendor": "", - "device": "iSCSI controller", - "model": "iSCSI controller", - "sysfs_id": "/devices/platform/host5/session4", - "sysfs_bus_id": "session4", - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"], - "driver_info": { - "type": "module", - "db_entry_0": ["iscsi-tcp"], - "active": true, - "modprobe": true, - "names": ["iscsi-tcp"], - "module_args": [""], - "conf": "" - } - }, - { - "index": 23, - "attached_to": 0, - "class_list": ["storage_controller"], - "base_class": { - "hex": "011a", - "name": "iSCSI controller", - "value": 282 - }, - "vendor": "", - "device": "iSCSI controller", - "model": "iSCSI controller", - "sysfs_id": "/devices/platform/host3/session2", - "sysfs_bus_id": "session2", - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"], - "driver_info": { - "type": "module", - "db_entry_0": ["iscsi-tcp"], - "active": true, - "modprobe": true, - "names": ["iscsi-tcp"], - "module_args": [""], - "conf": "" - } - }, - { - "index": 24, - "attached_to": 0, - "class_list": ["storage_controller"], - "base_class": { - "hex": "011a", - "name": "iSCSI controller", - "value": 282 - }, - "vendor": "", - "device": "iSCSI controller", - "model": "iSCSI controller", - "sysfs_id": "/devices/platform/host6/session5", - "sysfs_bus_id": "session5", - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"], - "driver_info": { - "type": "module", - "db_entry_0": ["iscsi-tcp"], - "active": true, - "modprobe": true, - "names": ["iscsi-tcp"], - "module_args": [""], - "conf": "" - } - }, - { - "index": 25, - "attached_to": 0, - "class_list": ["storage_controller"], - "base_class": { - "hex": "011a", - "name": "iSCSI controller", - "value": 282 - }, - "vendor": "", - "device": "iSCSI controller", - "model": "iSCSI controller", - "sysfs_id": "/devices/platform/host4/session3", - "sysfs_bus_id": "session3", - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"], - "driver_info": { - "type": "module", - "db_entry_0": ["iscsi-tcp"], - "active": true, - "modprobe": true, - "names": ["iscsi-tcp"], - "module_args": [""], - "conf": "" - } - }, - { - "index": 26, - "attached_to": 0, - "class_list": ["storage_controller"], - "base_class": { - "hex": "011a", - "name": "iSCSI controller", - "value": 282 - }, - "vendor": "", - "device": "iSCSI controller", - "model": "iSCSI controller", - "sysfs_id": "/devices/platform/host2/session1", - "sysfs_bus_id": "session1", - "driver": "iscsi_tcp", - "driver_module": "iscsi-tcp", - "drivers": ["iscsi_tcp"], - "driver_modules": ["iscsi-tcp"], - "driver_info": { - "type": "module", - "db_entry_0": ["iscsi-tcp"], - "active": true, - "modprobe": true, - "names": ["iscsi-tcp"], - "module_args": [""], - "conf": "" - } - } - ], - "system": { - "form_factor": "desktop" - }, - "unknown": [ - { - "index": 19, - "attached_to": 8, - "class_list": ["unknown"], - "base_class": { - "hex": "0000", - "name": "Unclassified device", - "value": 0 - }, - "sub_class": { - "hex": "0000", - "name": "Unclassified device", - "value": 0 - }, - "vendor": "Virtio", - "device": "", - "model": "Virtio Unclassified device", - "sysfs_id": "/devices/pci0000:00/0000:00:1c.0/virtio2", - "sysfs_bus_id": "virtio2", - "driver": "virtio_console", - "driver_module": "virtio_console", - "drivers": ["virtio_console"], - "driver_modules": ["virtio_console"], - "module_alias": "virtio:d00000003v00001AF4" - }, - { - "index": 21, - "attached_to": 12, - "class_list": ["unknown"], - "base_class": { - "hex": "0000", - "name": "Unclassified device", - "value": 0 - }, - "sub_class": { - "hex": "0000", - "name": "Unclassified device", - "value": 0 - }, - "vendor": "Virtio", - "device": "", - "model": "Virtio Unclassified device", - "sysfs_id": "/devices/pci0000:00/0000:00:1e.0/virtio3", - "sysfs_bus_id": "virtio3", - "driver": "virtio_balloon", - "driver_module": "virtio_balloon", - "drivers": ["virtio_balloon"], - "driver_modules": ["virtio_balloon"], - "module_alias": "virtio:d00000005v00001AF4" - } - ], - "usb_controller": [ - { - "index": 9, - "attached_to": 0, - "class_list": ["usb_controller", "pci"], - "bus_type": { - "hex": "0004", - "name": "PCI", - "value": 4 - }, - "slot": { - "bus": 0, - "number": 1 - }, - "base_class": { - "hex": "000c", - "name": "Serial bus controller", - "value": 12 - }, - "sub_class": { - "hex": "0003", - "name": "USB Controller", - "value": 3 - }, - "pci_interface": { - "hex": "0000", - "name": "UHCI", - "value": 0 - }, - "vendor": { - "hex": "8086", - "name": "Intel Corporation", - "value": 32902 - }, - "sub_vendor": { - "hex": "1af4", - "value": 6900 - }, - "device": { - "hex": "7020", - "value": 28704 - }, - "sub_device": { - "hex": "1100", - "value": 4352 - }, - "revision": { - "hex": "0001", - "value": 1 - }, - "model": "Intel USB Controller", - "sysfs_id": "/devices/pci0000:00/0000:00:01.2", - "sysfs_bus_id": "0000:00:01.2", - "resources": [ - { - "type": "io", - "base": 49472, - "range": 32, - "enabled": true, - "access": "read_write" - } - ], - "detail": { - "function": 2, - "command": 263, - "header_type": 0, - "secondary_bus": 0, - "prog_if": 0 - }, - "driver": "uhci_hcd", - "driver_module": "uhci_hcd", - "drivers": ["uhci_hcd"], - "driver_modules": ["uhci_hcd"], - "driver_info": { - "type": "module", - "db_entry_0": ["uhci-hcd"], - "active": true, - "modprobe": true, - "names": ["uhci-hcd"], - "module_args": [""], - "conf": "" - }, - "module_alias": "pci:v00008086d00007020sv00001AF4sd00001100bc0Csc03i00" - } - ] - }, - "smbios": { - "bios": { - "handle": 0, - "vendor": "netcup", - "version": "RS 1000 G11", - "date": "07/07/2025", - "features": null, - "start_address": "0xe8000", - "rom_size": 65536 - }, - "chassis": [ - { - "handle": 768, - "manufacturer": "QEMU", - "version": "pc-i440fx-9.2", - "chassis_type": { - "hex": "0001", - "name": "Other", - "value": 1 - }, - "lock_present": false, - "bootup_state": { - "hex": "0003", - "name": "Safe", - "value": 3 - }, - "power_state": { - "hex": "0003", - "name": "Safe", - "value": 3 - }, - "thermal_state": { - "hex": "0003", - "name": "Safe", - "value": 3 - }, - "security_state": { - "hex": "0002", - "name": "Unknown", - "value": 2 - }, - "oem": "0x0" - } - ], - "memory_array": [ - { - "handle": 4096, - "location": { - "hex": "0001", - "name": "Other", - "value": 1 - }, - "usage": { - "hex": "0003", - "name": "System memory", - "value": 3 - }, - "ecc": { - "hex": "0006", - "name": "Multi-bit", - "value": 6 - }, - "max_size": "0x800000", - "error_handle": 65534, - "slots": 1 - } - ], - "memory_array_mapped_address": [ - { - "handle": 4864, - "array_handle": 4096, - "start_address": "0x0", - "end_address": "0xc0000000", - "part_width": 1 - }, - { - "handle": 4865, - "array_handle": 4096, - "start_address": "0x100000000", - "end_address": "0x240000000", - "part_width": 1 - } - ], - "memory_device": [ - { - "handle": 4352, - "location": "DIMM 0", - "bank_location": "", - "manufacturer": "QEMU", - "part_number": "", - "array_handle": 4096, - "error_handle": 65534, - "width": 0, - "ecc_bits": 0, - "size": 8388608, - "form_factor": { - "hex": "0009", - "name": "DIMM", - "value": 9 - }, - "set": 0, - "memory_type": { - "hex": "0007", - "name": "RAM", - "value": 7 - }, - "memory_type_details": ["Other"], - "speed": 0 - } - ], - "processor": [ - { - "handle": 1024, - "socket": "CPU 0", - "socket_type": { - "hex": "0001", - "name": "Other", - "value": 1 - }, - "socket_populated": true, - "manufacturer": "QEMU", - "version": "pc-i440fx-9.2", - "part": "", - "processor_type": { - "hex": "0003", - "name": "CPU", - "value": 3 - }, - "processor_family": { - "hex": "00fe", - "name": "Other", - "value": 254 - }, - "processor_status": { - "hex": "0001", - "name": "Enabled", - "value": 1 - }, - "clock_ext": 0, - "clock_max": 2000, - "cache_handle_l1": 0, - "cache_handle_l2": 0, - "cache_handle_l3": 0 - }, - { - "handle": 1025, - "socket": "CPU 1", - "socket_type": { - "hex": "0001", - "name": "Other", - "value": 1 - }, - "socket_populated": true, - "manufacturer": "QEMU", - "version": "pc-i440fx-9.2", - "part": "", - "processor_type": { - "hex": "0003", - "name": "CPU", - "value": 3 - }, - "processor_family": { - "hex": "00fe", - "name": "Other", - "value": 254 - }, - "processor_status": { - "hex": "0001", - "name": "Enabled", - "value": 1 - }, - "clock_ext": 0, - "clock_max": 2000, - "cache_handle_l1": 0, - "cache_handle_l2": 0, - "cache_handle_l3": 0 - }, - { - "handle": 1026, - "socket": "CPU 2", - "socket_type": { - "hex": "0001", - "name": "Other", - "value": 1 - }, - "socket_populated": true, - "manufacturer": "QEMU", - "version": "pc-i440fx-9.2", - "part": "", - "processor_type": { - "hex": "0003", - "name": "CPU", - "value": 3 - }, - "processor_family": { - "hex": "00fe", - "name": "Other", - "value": 254 - }, - "processor_status": { - "hex": "0001", - "name": "Enabled", - "value": 1 - }, - "clock_ext": 0, - "clock_max": 2000, - "cache_handle_l1": 0, - "cache_handle_l2": 0, - "cache_handle_l3": 0 - }, - { - "handle": 1027, - "socket": "CPU 3", - "socket_type": { - "hex": "0001", - "name": "Other", - "value": 1 - }, - "socket_populated": true, - "manufacturer": "QEMU", - "version": "pc-i440fx-9.2", - "part": "", - "processor_type": { - "hex": "0003", - "name": "CPU", - "value": 3 - }, - "processor_family": { - "hex": "00fe", - "name": "Other", - "value": 254 - }, - "processor_status": { - "hex": "0001", - "name": "Enabled", - "value": 1 - }, - "clock_ext": 0, - "clock_max": 2000, - "cache_handle_l1": 0, - "cache_handle_l2": 0, - "cache_handle_l3": 0 - } - ], - "system": { - "handle": 256, - "manufacturer": "netcup", - "product": "KVM Server", - "version": "RS 1000 G11", - "wake_up": { - "hex": "0006", - "name": "Power Switch", - "value": 6 - } - } - } -} diff --git a/nix/modules/hosts/nixos/snowpoint/facter.nix b/nix/modules/hosts/nixos/snowpoint/facter.nix deleted file mode 100644 index 25ef1e89..00000000 --- a/nix/modules/hosts/nixos/snowpoint/facter.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.snowpoint = {self, ...}: { - hardware.facter.reportPath = self + "/nix/modules/hosts/nixos/snowpoint/facter.json"; - }; -} diff --git a/nix/modules/hosts/nixos/snowpoint/hardware.nix b/nix/modules/hosts/nixos/snowpoint/hardware.nix deleted file mode 100644 index dad1aa7d..00000000 --- a/nix/modules/hosts/nixos/snowpoint/hardware.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.snowpoint = { - services.qemuGuest.enable = true; - }; -} diff --git a/nix/modules/hosts/nixos/snowpoint/hostname.nix b/nix/modules/hosts/nixos/snowpoint/hostname.nix deleted file mode 100644 index fbc649e1..00000000 --- a/nix/modules/hosts/nixos/snowpoint/hostname.nix +++ /dev/null @@ -1,6 +0,0 @@ -_: { - flake.nixosModules.snowpoint = { - networking.hostName = "snowpoint"; - system.stateVersion = "25.11"; - }; -} diff --git a/nix/modules/hosts/nixos/snowpoint/k3s.nix b/nix/modules/hosts/nixos/snowpoint/k3s.nix deleted file mode 100644 index 760d0bc0..00000000 --- a/nix/modules/hosts/nixos/snowpoint/k3s.nix +++ /dev/null @@ -1,12 +0,0 @@ -_: { - flake.nixosModules.snowpoint = { - myNixOs.profile.k3s = { - role = "server"; - serverAddr = "https://pastoria.cute:6443"; - transportInterface = "wg-k3s"; - nodeIP = "10.254.0.3"; - zone = "cloud"; - ingress = true; - }; - }; -} diff --git a/nix/modules/hosts/nixos/snowpoint/syncthing.nix b/nix/modules/hosts/nixos/snowpoint/syncthing.nix deleted file mode 100644 index 786aa1db..00000000 --- a/nix/modules/hosts/nixos/snowpoint/syncthing.nix +++ /dev/null @@ -1,27 +0,0 @@ -_: { - flake.nixosModules.snowpoint = { - config, - self, - ... - }: { - sops.secrets = { - syncthingCert = { - sopsFile = "${self}/secrets/syncthing.yaml"; - key = "snowpoint_cert"; - }; - syncthingKey = { - sopsFile = "${self}/secrets/syncthing.yaml"; - key = "snowpoint_key"; - }; - }; - myNixOs = { - service.syncthing = { - certFile = config.sops.secrets.syncthingCert.path; - keyFile = config.sops.secrets.syncthingKey.path; - syncROMs = false; - user = "aly"; - }; - users.aly.password = "$6$JTk2qi27OpA2fOAY$ZgTDg0wbmbwHUD..0xT4xYX.AR5hWQFCMVmn8G88yi3IAY7015AupovTpfy0arkI7nl/IDu5L09bzLKeXGvJC1"; - }; - }; -} diff --git a/nix/modules/nixos/documentation.nix b/nix/modules/nixos/documentation.nix deleted file mode 100644 index 82d4c9cc..00000000 --- a/nix/modules/nixos/documentation.nix +++ /dev/null @@ -1,8 +0,0 @@ -_: { - flake.nixosModules.default = { - documentation = { - enable = false; - nixos.enable = false; - }; - }; -} diff --git a/nix/modules/nixos/hardware/firmware.nix b/nix/modules/nixos/hardware/firmware.nix deleted file mode 100644 index 6ab248e2..00000000 --- a/nix/modules/nixos/hardware/firmware.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.default = { - hardware.enableAllFirmware = true; - }; -} diff --git a/nix/modules/nixos/hardware/intel-gpu.nix b/nix/modules/nixos/hardware/intel-gpu.nix deleted file mode 100644 index b35c4d14..00000000 --- a/nix/modules/nixos/hardware/intel-gpu.nix +++ /dev/null @@ -1,20 +0,0 @@ -_: { - flake.nixosModules.intelGpu = {pkgs, ...}: { - environment.sessionVariables.LIBVA_DRIVER_NAME = "iHD"; - - hardware = { - facter.detected.graphics.enable = true; - intel-gpu-tools.enable = true; - graphics.extraPackages = [ - (pkgs.intel-vaapi-driver.override {enableHybridCodec = true;}) - pkgs.intel-compute-runtime - pkgs.intel-media-driver - ]; - }; - - services = { - k3s.extraFlags = ["--node-label=cute.haus/intel-gpu=true"]; - xserver.videoDrivers = ["modesetting"]; - }; - }; -} diff --git a/nix/modules/nixos/known-hosts.nix b/nix/modules/nixos/known-hosts.nix deleted file mode 100644 index a2e9788e..00000000 --- a/nix/modules/nixos/known-hosts.nix +++ /dev/null @@ -1,30 +0,0 @@ -_: { - flake.nixosModules.default = { - lib, - self, - ... - }: let - tnet = "narwhal-snapper.ts.net"; - rootKeyFiles = lib.filterAttrs ( - fileName: fileType: - fileType - == "regular" - && lib.hasPrefix "root_" fileName - && lib.hasSuffix ".pub" fileName - ) (builtins.readDir "${self}/keys"); - aliases = { - jubilife = ["jubilife.cute" "lilycove" "lilycove.local" "lilycove.${tnet}"]; - pastoria = ["pastoria.cute"]; - snowpoint = ["snowpoint.cute" "dewford" "dewford.local" "dewford.${tnet}"]; - }; - in { - programs.ssh.knownHosts = lib.mapAttrs' (fileName: _fileType: let - hostName = lib.removeSuffix ".pub" (lib.removePrefix "root_" fileName); - in - lib.nameValuePair hostName { - hostNames = [hostName "${hostName}.local" "${hostName}.${tnet}"] ++ (aliases.${hostName} or []); - publicKeyFile = "${self}/keys/${fileName}"; - }) - rootKeyFiles; - }; -} diff --git a/nix/modules/nixos/locale.nix b/nix/modules/nixos/locale.nix deleted file mode 100644 index 76b6ef35..00000000 --- a/nix/modules/nixos/locale.nix +++ /dev/null @@ -1,21 +0,0 @@ -_: { - flake.nixosModules.default = {lib, ...}: { - i18n = { - defaultLocale = lib.mkDefault "en_US.UTF-8"; - - extraLocaleSettings = { - LC_ADDRESS = lib.mkDefault "en_US.UTF-8"; - LC_IDENTIFICATION = lib.mkDefault "en_US.UTF-8"; - LC_MEASUREMENT = lib.mkDefault "en_US.UTF-8"; - LC_MONETARY = lib.mkDefault "en_US.UTF-8"; - LC_NAME = lib.mkDefault "en_US.UTF-8"; - LC_NUMERIC = lib.mkDefault "en_US.UTF-8"; - LC_PAPER = lib.mkDefault "en_US.UTF-8"; - LC_TELEPHONE = lib.mkDefault "en_US.UTF-8"; - LC_TIME = lib.mkDefault "en_US.UTF-8"; - }; - }; - - time.timeZone = lib.mkDefault "America/New_York"; - }; -} diff --git a/nix/modules/nixos/nixpkgs.nix b/nix/modules/nixos/nixpkgs.nix deleted file mode 100644 index 682336c6..00000000 --- a/nix/modules/nixos/nixpkgs.nix +++ /dev/null @@ -1,5 +0,0 @@ -{sharedPackageSets, ...}: { - flake.nixosModules.default = { - nixpkgs.pkgs = sharedPackageSets.x86_64-linux; - }; -} diff --git a/nix/modules/nixos/packages.nix b/nix/modules/nixos/packages.nix deleted file mode 100644 index 6006132a..00000000 --- a/nix/modules/nixos/packages.nix +++ /dev/null @@ -1,13 +0,0 @@ -_: { - flake.nixosModules.default = {pkgs, ...}: { - environment.systemPackages = with pkgs; [ - (inxi.override {withRecommends = true;}) - helix - lm_sensors - python314 - rclone - wget - zellij - ]; - }; -} diff --git a/nix/modules/nixos/performance.nix b/nix/modules/nixos/performance.nix deleted file mode 100644 index 45f646e9..00000000 --- a/nix/modules/nixos/performance.nix +++ /dev/null @@ -1,28 +0,0 @@ -_: { - flake.nixosModules.default = {lib, ...}: { - boot.kernel.sysctl = { - "fs.file-max" = lib.mkDefault 2097152; - "fs.inotify.max_user_instances" = lib.mkOverride 100 8192; - "fs.inotify.max_user_watches" = lib.mkOverride 100 524288; - }; - - hardware.block = { - defaultScheduler = "kyber"; - defaultSchedulerRotational = "bfq"; - - scheduler = { - "mmcblk[0-9]*" = "bfq"; - "nvme[0-9]*" = "kyber"; - }; - }; - - services.bpftune.enable = true; - - systemd.oomd = { - enable = true; - enableRootSlice = true; - enableSystemSlice = true; - enableUserSlices = true; - }; - }; -} diff --git a/nix/modules/nixos/profiles/arr.nix b/nix/modules/nixos/profiles/arr.nix deleted file mode 100644 index e2742e19..00000000 --- a/nix/modules/nixos/profiles/arr.nix +++ /dev/null @@ -1,67 +0,0 @@ -_: { - flake.nixosModules.arr = { - config, - lib, - pkgs, - ... - }: let - cfg = config.myNixOs.profile.arr; - arrServices = { - bazarr.dataDir = "${cfg.dataDir}/bazarr"; - lidarr = { - dataDir = "${cfg.dataDir}/lidarr/.config/Lidarr"; - createDataDir = true; - }; - prowlarr = {}; - radarr = { - dataDir = "${cfg.dataDir}/radarr/.config/Radarr/"; - createDataDir = true; - }; - sonarr = { - dataDir = "${cfg.dataDir}/sonarr/.config/NzbDrone/"; - createDataDir = true; - }; - }; - - enabledServices = - lib.mapAttrs ( - _: service: - { - enable = true; - openFirewall = true; - } - // lib.optionalAttrs (service ? dataDir) {inherit (service) dataDir;} - ) - arrServices; - - backupJobs = - lib.mapAttrs (serviceName: _: { - backupCleanupCommand = "${pkgs.systemd}/bin/systemctl start ${serviceName}"; - backupPrepareCommand = "${pkgs.systemd}/bin/systemctl stop ${serviceName}"; - paths = [config.services.${serviceName}.dataDir]; - }) - arrServices; - - dataDirectoryServices = lib.filterAttrs (_: service: service.createDataDir or false) arrServices; - in { - options.myNixOs.profile.arr = { - dataDir = lib.mkOption { - type = lib.types.str; - default = "/var/lib"; - description = "The directory where *arr stores its data files."; - }; - }; - - config = { - services = enabledServices; - - systemd.tmpfiles.rules = - lib.mapAttrsToList ( - serviceName: service: "d ${service.dataDir} 0755 ${serviceName} ${serviceName}" - ) - dataDirectoryServices; - - myNixOs.profile.backups.jobs = backupJobs; - }; - }; -} diff --git a/nix/modules/nixos/profiles/b2-mounts.nix b/nix/modules/nixos/profiles/b2-mounts.nix deleted file mode 100644 index fb6d6d5d..00000000 --- a/nix/modules/nixos/profiles/b2-mounts.nix +++ /dev/null @@ -1,104 +0,0 @@ -_: { - flake.nixosModules.b2Mounts = { - config, - lib, - pkgs, - self, - ... - }: let - cfg = config.myNixOs.profile.b2Mounts; - - b2Options = [ - "allow_other" - "args2env" - "cache-dir=${cfg.cacheDir}" - "config=${config.sops.secrets.b2-mount-rclone.path}" - "dir-cache-time=1h" - "nodev" - "nofail" - "vfs-cache-mode=full" - "vfs-write-back=10s" - "x-systemd.after=network-online.target" - "x-systemd.automount" - ]; - - b2ProfileOptions = { - audio = [ - "buffer-size=128M" - "vfs-cache-max-age=168h" - "vfs-cache-max-size=${cfg.audioCacheSize}" - "vfs-read-ahead=${cfg.audioReadAhead}" - ]; - - video = [ - "buffer-size=512M" - "vfs-cache-max-age=336h" - "vfs-cache-max-size=${cfg.videoCacheSize}" - "vfs-read-ahead=${cfg.videoReadAhead}" - ]; - }; - - mkB2Mount = name: remote: profile: { - "/mnt/Backblaze/${name}" = { - device = "b2:${remote}"; - fsType = "rclone"; - options = b2Options ++ b2ProfileOptions.${profile}; - }; - }; - - allShares = { - Anime = mkB2Mount "Anime" "aly-anime" "video"; - Audiobooks = mkB2Mount "Audiobooks" "aly-audiobooks" "audio"; - Movies = mkB2Mount "Movies" "aly-movies" "video"; - Music = mkB2Mount "Music" "aly-music" "audio"; - Shows = mkB2Mount "Shows" "aly-shows" "video"; - }; - in { - options.myNixOs.profile.b2Mounts = { - cacheDir = lib.mkOption { - description = "Directory for rclone VFS cache."; - example = "/mnt/Data/.rclone-cache"; - type = lib.types.str; - }; - - audioCacheSize = lib.mkOption { - default = "15G"; - type = lib.types.str; - }; - videoCacheSize = lib.mkOption { - default = "50G"; - type = lib.types.str; - }; - audioReadAhead = lib.mkOption { - default = "1G"; - type = lib.types.str; - }; - videoReadAhead = lib.mkOption { - default = "3G"; - type = lib.types.str; - }; - - shares = lib.mkOption { - description = "Which B2 shares to mount."; - default = ["Anime" "Audiobooks" "Movies" "Music" "Shows"]; - type = lib.types.listOf (lib.types.enum ["Anime" "Audiobooks" "Movies" "Music" "Shows"]); - }; - }; - - config = { - sops.secrets.b2-mount-rclone = { - sopsFile = "${self}/secrets/b2.yaml"; - key = "rclone_config"; - }; - - environment.systemPackages = [pkgs.rclone]; - - fileSystems = builtins.foldl' (a: b: a // b) {} (builtins.attrValues (builtins.intersectAttrs (builtins.listToAttrs (map (s: { - name = s; - value = null; - }) - cfg.shares)) - allShares)); - }; - }; -} diff --git a/nix/modules/nixos/profiles/backups.nix b/nix/modules/nixos/profiles/backups.nix deleted file mode 100644 index 068bb101..00000000 --- a/nix/modules/nixos/profiles/backups.nix +++ /dev/null @@ -1,99 +0,0 @@ -_: { - flake.nixosModules.backups = { - config, - lib, - self, - ... - }: let - backupDestination = "rclone:b2:aly-backups/${config.networking.hostName}"; - mkRepo = service: "${backupDestination}/${service}"; - - restic = { - extraBackupArgs = [ - "--cleanup-cache" - "--compression max" - "--no-scan" - ]; - - inhibitsSleep = true; - initialize = true; - passwordFile = config.sops.secrets.restic-passwd.path; - - pruneOpts = [ - "--keep-daily 7" - "--keep-weekly 4" - "--keep-monthly 3" - ]; - - rcloneConfigFile = config.sops.secrets.rclone-b2.path; - - timerConfig = { - OnCalendar = "daily"; - Persistent = true; - RandomizedDelaySec = "3h"; - }; - }; - in { - options.myNixOs.profile.backups = { - jobs = lib.mkOption { - description = "Restic backup jobs rendered with the shared defaults."; - default = {}; - - type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { - options = { - paths = lib.mkOption { - type = lib.types.listOf lib.types.path; - description = "Paths to back up."; - }; - - repository = lib.mkOption { - type = lib.types.str; - default = mkRepo name; - description = "Restic repository URL."; - }; - - backupPrepareCommand = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - }; - - backupCleanupCommand = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - }; - - exclude = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = []; - }; - }; - })); - }; - }; - - config = { - sops.secrets = { - restic-passwd = { - sopsFile = "${self}/secrets/restic.yaml"; - key = "PASSWORD"; - }; - - rclone-b2 = { - sopsFile = "${self}/secrets/b2.yaml"; - key = "rclone_config"; - }; - }; - - services.restic.backups = let - mkRestic = _: job: - restic - // { - inherit (job) paths repository exclude; - backupPrepareCommand = lib.mkIf (job.backupPrepareCommand != null) job.backupPrepareCommand; - backupCleanupCommand = lib.mkIf (job.backupCleanupCommand != null) job.backupCleanupCommand; - }; - in - lib.mapAttrs mkRestic config.myNixOs.profile.backups.jobs; - }; - }; -} diff --git a/nix/modules/nixos/profiles/btrfs.nix b/nix/modules/nixos/profiles/btrfs.nix deleted file mode 100644 index 1bcbd48f..00000000 --- a/nix/modules/nixos/profiles/btrfs.nix +++ /dev/null @@ -1,77 +0,0 @@ -_: { - flake.nixosModules.btrfs = { - config, - lib, - pkgs, - ... - }: let - btrfsFSDevices = let - isDeviceInList = list: device: builtins.any (e: e.device == device) list; - uniqueDeviceList = lib.foldl' (acc: e: - if isDeviceInList acc e.device - then acc - else acc ++ [e]) []; - in - uniqueDeviceList ( - lib.mapAttrsToList (_: fs: {inherit (fs) mountPoint device;}) - (lib.filterAttrs (_: fs: fs.fsType == "btrfs") config.fileSystems) - ); - - beesdConfig = lib.listToAttrs (map (fs: { - name = lib.strings.sanitizeDerivationName (baseNameOf fs.device); - value = { - hashTableSizeMB = 2048; - spec = fs.device; - verbosity = "info"; - extraOptions = ["--loadavg-target" "1.0" "--thread-factor" "0.50"]; - }; - }) - btrfsFSDevices); - - hasHomeSubvolume = - lib.hasAttr "/home" config.fileSystems - && config.fileSystems."/home".fsType == "btrfs"; - in { - options.myNixOs.profile.btrfs = { - deduplicate = lib.mkEnableOption "deduplicate btrfs filesystems"; - }; - - config = { - boot.supportedFilesystems = ["btrfs"]; - environment.systemPackages = lib.optionals config.services.xserver.enable [pkgs.snapper-gui]; - - services = lib.mkIf (btrfsFSDevices != []) { - beesd.filesystems = lib.mkIf config.myNixOs.profile.btrfs.deduplicate beesdConfig; - btrfs.autoScrub.enable = true; - - snapper = { - configs.home = lib.mkIf hasHomeSubvolume { - ALLOW_GROUPS = ["users"]; - FSTYPE = "btrfs"; - SUBVOLUME = "/home"; - TIMELINE_CLEANUP = true; - TIMELINE_CREATE = true; - }; - - filters = '' - -.bash_profile - -.bashrc - -.cache - -.config - -.librewolf - -.local - -.mozilla - -.nix-profile - -.pki - -.share - -.snapshots - -.thunderbird - -.zshrc - ''; - - persistentTimer = true; - }; - }; - }; - }; -} diff --git a/nix/modules/nixos/profiles/data-share.nix b/nix/modules/nixos/profiles/data-share.nix deleted file mode 100644 index b2146d2e..00000000 --- a/nix/modules/nixos/profiles/data-share.nix +++ /dev/null @@ -1,36 +0,0 @@ -_: { - flake.nixosModules.dataShare = { - config, - pkgs, - ... - }: { - assertions = [ - { - assertion = config.services.tailscale.enable; - message = "NFS connects to jubilife shares over tailscale, but services.tailscale.enable != true."; - } - ]; - - environment.systemPackages = [pkgs.nfs-utils]; - - fileSystems."/mnt/Data" = { - fsType = "nfs"; - device = "jubilife:/mnt/Data"; - - options = [ - "default" - "noatime" - "nofail" - "retrans=2" - "rsize=1048576" - "wsize=1048576" - "x-systemd.after=network-online.target" - "x-systemd.after=tailscaled.service" - "x-systemd.automount" - "x-systemd.device-timeout=5s" - "x-systemd.idle-timeout=60" - "x-systemd.mount-timeout=5s" - ]; - }; - }; -} diff --git a/nix/modules/nixos/profiles/k3s.nix b/nix/modules/nixos/profiles/k3s.nix deleted file mode 100644 index a7eee5c5..00000000 --- a/nix/modules/nixos/profiles/k3s.nix +++ /dev/null @@ -1,173 +0,0 @@ -_: { - flake.nixosModules.k3s = { - config, - lib, - pkgs, - self, - ... - }: let - cfg = config.myNixOs.profile.k3s; - transportService = - if cfg.transportInterface == "wg-k3s" - then "wireguard-wg-k3s.service" - else "tailscaled.service"; - in { - options.myNixOs.profile.k3s = { - role = lib.mkOption { - type = lib.types.enum ["server" "agent"]; - default = "server"; - }; - - clusterInit = lib.mkOption { - type = lib.types.bool; - default = false; - description = '' - Whether this node initializes the cluster's etcd. Exactly one node - in the cluster should set this. Other servers join via `serverAddr`. - ''; - }; - - serverAddr = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - example = "https://solaceon:6443"; - }; - - transportInterface = lib.mkOption { - type = lib.types.str; - default = "tailscale0"; - description = "Network interface used for k3s node and Flannel traffic."; - }; - - nodeIP = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = "Address k3s advertises for the Kubernetes node."; - }; - - tlsSans = lib.mkOption { - type = lib.types.listOf lib.types.str; - default = [ - "snowpoint" - "pastoria" - "jubilife" - "snowpoint.cute" - "pastoria.cute" - "jubilife.cute" - ]; - }; - - zone = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - example = "cloud"; - }; - - ingress = lib.mkEnableOption "cute.haus/ingress=true node label"; - }; - - config = { - sops.secrets.k3s = { - sopsFile = "${self}/secrets/k3s.yaml"; - key = "TOKEN"; - }; - - # systemd-oomd fights kubelet's eviction manager - systemd.oomd.enable = lib.mkForce false; - - networking.firewall = { - allowedTCPPorts = lib.mkIf cfg.ingress [80 443 2222]; - - # Let a pod reach kubelet:10250 on its own host. Same-node traffic to - # the node's Tailscale IP is delivered locally and arrives via cni0, so - # metrics-server can't scrape the node it runs on without this. - trustedInterfaces = ["cni0"]; - }; - - services = { - k3s = { - enable = true; - inherit (cfg) role clusterInit; - serverAddr = lib.mkIf (cfg.serverAddr != null) cfg.serverAddr; - tokenFile = config.sops.secrets.k3s.path; - extraFlags = - [ - "--flannel-iface=${cfg.transportInterface}" - # Keep image storage below Longhorn's 75% disk-use ceiling. - "--kubelet-arg=image-gc-high-threshold=70" - "--kubelet-arg=image-gc-low-threshold=65" - ] - ++ lib.optionals (cfg.nodeIP != null) ["--node-ip=${cfg.nodeIP}"] - ++ lib.optionals (cfg.role == "server") ( - [ - "--service-node-port-range=8000-32767" - "--disable=traefik" - "--disable=servicelb" - ] - ++ lib.optionals (cfg.nodeIP != null) ["--advertise-address=${cfg.nodeIP}"] - ++ map (san: "--tls-san=${san}") cfg.tlsSans - ) - ++ lib.optionals cfg.clusterInit ["--write-kubeconfig-mode=644"] - ++ lib.optionals (cfg.zone != null) ["--node-label=topology.kubernetes.io/zone=${cfg.zone}"] - ++ lib.optionals cfg.ingress ["--node-label=cute.haus/ingress=true"]; - }; - - openiscsi = { - enable = true; - name = "iqn.2026-05.haus.cute:${config.networking.hostName}"; - }; - }; - - environment.systemPackages = with pkgs; [ - kubernetes-helm - nfs-utils - ]; - - systemd = { - # Longhorn instance-manager looks for binaries in /usr/local/bin - tmpfiles.rules = [ - "L+ /usr/local/bin - - - - /run/current-system/sw/bin/" - ]; - - services = { - # Block k3s startup until its transport interface has an IP. This - # prevents Flannel and etcd peer setup from racing at cold boot. - k3s = { - after = [transportService]; - wants = [transportService]; - serviceConfig.ExecStartPre = pkgs.writeShellScript "wait-k3s-transport" '' - until ${pkgs.iproute2}/bin/ip -4 addr show ${cfg.transportInterface} | grep -q inet; do - ${pkgs.coreutils}/bin/sleep 1 - done - ''; - }; - - # Cleanly log out iSCSI sessions at shutdown so reboots don't hang - # waiting for udev scsi_id timeouts against dead longhorn devices. - iscsi-logout = { - description = "Log out iSCSI sessions cleanly at shutdown"; - after = ["iscsid.service"]; - before = ["k3s.service"]; - requires = ["iscsid.service"]; - wantedBy = ["multi-user.target"]; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - ExecStart = "${pkgs.coreutils}/bin/true"; - ExecStop = "-${pkgs.openiscsi}/bin/iscsiadm -m node -u"; - TimeoutStopSec = "30s"; - }; - }; - }; - }; - myNixOs.profile.backups.jobs.k3s = lib.mkIf (config.services.k3s.role == "server") { - backupPrepareCommand = "${config.services.k3s.package}/bin/k3s etcd-snapshot save"; - paths = [ - "/var/lib/rancher/k3s/server/db/snapshots" - "/var/lib/rancher/k3s/server/cred" - "/var/lib/rancher/k3s/server/tls" - ]; - }; - }; - }; -} diff --git a/nix/modules/nixos/profiles/media-share.nix b/nix/modules/nixos/profiles/media-share.nix deleted file mode 100644 index 45427a1c..00000000 --- a/nix/modules/nixos/profiles/media-share.nix +++ /dev/null @@ -1,36 +0,0 @@ -_: { - flake.nixosModules.mediaShare = { - config, - pkgs, - ... - }: { - assertions = [ - { - assertion = config.services.tailscale.enable; - message = "NFS connects to jubilife shares over tailscale, but services.tailscale.enable != true."; - } - ]; - - environment.systemPackages = [pkgs.nfs-utils]; - - fileSystems."/mnt/Media" = { - fsType = "nfs"; - device = "jubilife:/mnt/Media"; - - options = [ - "default" - "noatime" - "nofail" - "retrans=2" - "rsize=1048576" - "wsize=1048576" - "x-systemd.after=network-online.target" - "x-systemd.after=tailscaled.service" - "x-systemd.automount" - "x-systemd.device-timeout=5s" - "x-systemd.idle-timeout=60" - "x-systemd.mount-timeout=5s" - ]; - }; - }; -} diff --git a/nix/modules/nixos/profiles/observability.nix b/nix/modules/nixos/profiles/observability.nix deleted file mode 100644 index 15a9d777..00000000 --- a/nix/modules/nixos/profiles/observability.nix +++ /dev/null @@ -1,308 +0,0 @@ -_: { - flake.nixosModules.observability = {pkgs, ...}: let - tailnet = "narwhal-snapper.ts.net"; - kubernetesOperationsDashboard = builtins.toJSON { - annotations.list = []; - editable = true; - panels = [ - { - datasource = "Kubernetes Prometheus"; - fieldConfig.defaults.unit = "short"; - gridPos = { - h = 8; - w = 8; - x = 0; - y = 0; - }; - targets = [ - { - expr = "sum(gotk_reconcile_condition{type=\"Ready\",status=\"True\"})"; - refId = "A"; - } - ]; - title = "Flux resources ready"; - type = "stat"; - } - { - datasource = "Kubernetes Prometheus"; - fieldConfig.defaults.unit = "short"; - gridPos = { - h = 8; - w = 8; - x = 8; - y = 0; - }; - targets = [ - { - expr = "sum(gotk_reconcile_condition{type=\"Ready\",status=\"False\"})"; - refId = "A"; - } - ]; - title = "Flux reconciliation failures"; - type = "stat"; - } - { - datasource = "Kubernetes Prometheus"; - fieldConfig.defaults.unit = "short"; - gridPos = { - h = 8; - w = 8; - x = 16; - y = 0; - }; - targets = [ - { - expr = "sum(increase(kube_pod_container_status_restarts_total[1h]))"; - refId = "A"; - } - ]; - title = "Container restarts (1h)"; - type = "stat"; - } - { - datasource = "Kubernetes Prometheus"; - fieldConfig.defaults.unit = "short"; - gridPos = { - h = 8; - w = 8; - x = 0; - y = 8; - }; - targets = [ - { - expr = "sum(kube_pod_status_ready{condition=\"true\"})"; - refId = "A"; - } - ]; - title = "Ready pods"; - type = "stat"; - } - { - datasource = "Kubernetes Prometheus"; - fieldConfig.defaults.unit = "short"; - gridPos = { - h = 8; - w = 8; - x = 8; - y = 8; - }; - targets = [ - { - expr = "sum(kube_persistentvolumeclaim_status_phase{phase=\"Pending\"})"; - refId = "A"; - } - ]; - title = "Pending PVCs"; - type = "stat"; - } - { - datasource = "Kubernetes Prometheus"; - fieldConfig.defaults.unit = "percent"; - gridPos = { - h = 8; - w = 8; - x = 16; - y = 8; - }; - targets = [ - { - expr = "sum(kube_pod_container_resource_requests{resource=\"cpu\"}) / sum(kube_node_status_allocatable{resource=\"cpu\"})"; - refId = "A"; - } - ]; - title = "Requested node CPU"; - type = "gauge"; - } - { - datasource = "Loki"; - gridPos = { - h = 10; - w = 24; - x = 0; - y = 16; - }; - targets = [ - { - expr = "{job=\"kubernetes-pods\"} |~ \"(?i)error\""; - refId = "A"; - } - ]; - title = "Recent Kubernetes error logs"; - type = "logs"; - } - ]; - refresh = "30s"; - schemaVersion = 39; - tags = ["kubernetes" "operations"]; - templating.list = []; - time = { - from = "now-6h"; - to = "now"; - }; - title = "Kubernetes Operations"; - uid = "kubernetes-operations"; - }; - in { - services = { - caddy.virtualHosts = { - "grafana.${tailnet}".extraConfig = '' - bind tailscale/grafana - reverse_proxy localhost:3010 - ''; - "loki.${tailnet}".extraConfig = '' - bind tailscale/loki - reverse_proxy localhost:3030 - ''; - "prometheus.${tailnet}".extraConfig = '' - bind tailscale/prometheus - reverse_proxy localhost:3020 - ''; - }; - - grafana = { - enable = true; - settings = { - security.secret_key = "SW2YcwTIb9zpOOhoPsMm"; - server = { - http_addr = "0.0.0.0"; - http_port = 3010; - domain = "grafana.${tailnet}"; - }; - }; - provision = { - enable = true; - datasources.settings.datasources = [ - { - name = "Prometheus"; - type = "prometheus"; - access = "proxy"; - url = "https://prometheus.${tailnet}"; - } - { - name = "Kubernetes Prometheus"; - type = "prometheus"; - access = "proxy"; - url = "http://127.0.0.1:30220"; - } - { - name = "Loki"; - type = "loki"; - access = "proxy"; - url = "https://loki.${tailnet}"; - } - ]; - dashboards.settings = { - apiVersion = 1; - providers = [ - { - name = "Kubernetes Operations"; - options.path = pkgs.writeText "kubernetes-operations.json" kubernetesOperationsDashboard; - type = "file"; - } - ]; - }; - }; - }; - - loki = { - enable = true; - configuration = { - auth_enabled = false; - server = { - http_listen_port = 3030; - grpc_listen_port = 0; - }; - common = { - instance_addr = "0.0.0.0"; - path_prefix = "/tmp/loki"; - storage.filesystem = { - chunks_directory = "/tmp/loki/chunks"; - rules_directory = "/tmp/loki/rules"; - }; - replication_factor = 1; - ring.kvstore.store = "inmemory"; - }; - frontend.max_outstanding_per_tenant = 2048; - pattern_ingester.enabled = true; - limits_config = { - max_global_streams_per_user = 0; - ingestion_rate_mb = 50000; - ingestion_burst_size_mb = 50000; - volume_enabled = true; - }; - query_range.results_cache.cache.embedded_cache = { - enabled = true; - max_size_mb = 100; - }; - schema_config.configs = [ - { - from = "2020-10-24"; - store = "tsdb"; - object_store = "filesystem"; - schema = "v13"; - index = { - prefix = "index_"; - period = "24h"; - }; - } - ]; - analytics.reporting_enabled = false; - }; - }; - - prometheus = { - enable = true; - globalConfig.scrape_interval = "10s"; - port = 3020; - scrapeConfigs = [ - { - job_name = "bazarr"; - static_configs = [{targets = ["jubilife:9708"];}]; - } - { - job_name = "lidarr"; - static_configs = [{targets = ["jubilife:9709"];}]; - } - { - job_name = "prowlarr"; - static_configs = [{targets = ["jubilife:9710"];}]; - } - { - job_name = "radarr"; - static_configs = [{targets = ["jubilife:9711"];}]; - } - { - job_name = "smartctl"; - static_configs = [ - { - targets = ["jubilife:9633"]; - labels.instance = "jubilife"; - } - ]; - } - { - job_name = "sonarr"; - static_configs = [{targets = ["jubilife:9712"];}]; - } - { - job_name = "node"; - static_configs = [ - { - targets = ["snowpoint:3021"]; - labels.instance = "snowpoint"; - } - { - targets = ["pastoria:3021"]; - labels.instance = "pastoria"; - } - { - targets = ["jubilife:3021"]; - labels.instance = "jubilife"; - } - ]; - } - ]; - }; - }; - }; -} diff --git a/nix/modules/nixos/profiles/swap.nix b/nix/modules/nixos/profiles/swap.nix deleted file mode 100644 index 452055a3..00000000 --- a/nix/modules/nixos/profiles/swap.nix +++ /dev/null @@ -1,26 +0,0 @@ -_: { - flake.nixosModules.swap = { - config, - lib, - ... - }: { - options.myNixOs.profile.swap = { - size = lib.mkOption { - default = 8192; - description = "Swap size in megabytes."; - type = lib.types.int; - }; - }; - - config = { - swapDevices = [ - { - device = "/.swap"; - priority = 0; - randomEncryption.enable = true; - inherit (config.myNixOs.profile.swap) size; - } - ]; - }; - }; -} diff --git a/nix/modules/nixos/profiles/wireguard-hoenn.nix b/nix/modules/nixos/profiles/wireguard-hoenn.nix deleted file mode 100644 index d2b4a4bf..00000000 --- a/nix/modules/nixos/profiles/wireguard-hoenn.nix +++ /dev/null @@ -1,83 +0,0 @@ -{lib, ...}: let - nodes = { - pastoria = "10.254.1.1"; - mauville = "10.254.1.2"; - rustboro = "10.254.1.3"; - sootopolis = "10.254.1.4"; - fortree = "10.254.1.5"; - fallarbor = "10.254.1.6"; - pacifidlog = "10.254.1.7"; - }; - coreDnsHosts = lib.concatStringsSep "\n" (lib.mapAttrsToList (name: address: " ${address} ${name}.hoenn") nodes); -in { - flake.nixosModules.wireguardHoenn = { - config, - self, - ... - }: { - boot.kernel.sysctl."net.ipv4.ip_forward" = 1; - - sops.secrets.wireguard-hoenn-private = { - sopsFile = self + "/secrets/wireguard-hoenn.yaml"; - key = "pastoria"; - mode = "0400"; - }; - - networking = { - firewall = { - allowedUDPPorts = [51821]; - trustedInterfaces = ["hoenn"]; - }; - - wireguard.interfaces.hoenn = { - ips = ["10.254.1.1/24"]; - listenPort = 51821; - privateKeyFile = config.sops.secrets.wireguard-hoenn-private.path; - - peers = [ - { - allowedIPs = ["10.254.1.2/32"]; - publicKey = "DLphP2R9EJ2TbIgaabt5ExQ461TdYX2EjlMsphxkVj8="; - } - { - allowedIPs = ["10.254.1.3/32"]; - publicKey = "ZhpSQzxRmKrp3Tsny9rGP1PCtcP/zghdRoQJBPWPGGQ="; - } - { - allowedIPs = ["10.254.1.4/32"]; - publicKey = "ezW8vZQUpvcb2ltr8BOIn+iZ/lXI0mvNLs49ZiaZnCA="; - } - { - allowedIPs = ["10.254.1.5/32"]; - publicKey = "rquW00TzyERo86qdjA+Xc4dtFfNQIidxxIkp9Y6hSBY="; - } - { - allowedIPs = ["10.254.1.6/32"]; - publicKey = "ZbPq07drguGi6udpyBj1zOsyoxQzcm4awstyWIJRzAQ="; - } - { - allowedIPs = ["10.254.1.7/32"]; - publicKey = "E8FXq8GhLhP83beFTzyN5G37rW5DgM9YcwtnQmaKQHs="; - } - ]; - }; - }; - - services.coredns = { - enable = true; - config = lib.concatStringsSep "\n" [ - "hoenn:53 {" - " bind ${nodes.pastoria}" - " hosts {" - coreDnsHosts - " }" - "}" - ]; - }; - - systemd.services.coredns = { - after = ["wireguard-hoenn.service"]; - requires = ["wireguard-hoenn.service"]; - }; - }; -} diff --git a/nix/modules/nixos/profiles/wireguard-k3s.nix b/nix/modules/nixos/profiles/wireguard-k3s.nix deleted file mode 100644 index d4cf663e..00000000 --- a/nix/modules/nixos/profiles/wireguard-k3s.nix +++ /dev/null @@ -1,68 +0,0 @@ -_: { - flake.nixosModules.wireguardK3s = { - config, - lib, - self, - ... - }: let - nodes = { - jubilife = { - address = "10.254.0.1"; - homeEndpoint = "192.168.1.138:51820"; - listenPort = 51820; - publicKey = "6gZ8YuQXYq1cQKOWisgjeEwOX2KLYZNnGY6vIW5wvGU="; - }; - pastoria = { - address = "10.254.0.2"; - listenPort = 51820; - endpoint = "51.81.87.134:51820"; - publicKey = "5bEvmgY36NiZalRwEy9h0oZJqsJvPC+zmaD78GOLuUo="; - }; - snowpoint = { - address = "10.254.0.3"; - listenPort = 51820; - endpoint = "152.53.90.225:51820"; - publicKey = "t1mErjV5oE4ucLtRt2UHiPShkPluxp+uM2+pRoswVS8="; - }; - }; - node = nodes.${config.networking.hostName}; - isHomeNode = node ? homeEndpoint; - in { - sops.secrets.wireguard-k3s-private = { - sopsFile = "${self}/secrets/wireguard-k3s.yaml"; - key = config.networking.hostName; - }; - - networking = { - firewall = { - allowedUDPPorts = [node.listenPort]; - # k3s control-plane, Flannel, and kubelet traffic use this private - # mesh after the transport migration. - trustedInterfaces = lib.mkBefore ["wg-k3s"]; - }; - hosts = - lib.mapAttrs' (name: peer: { - name = peer.address; - value = ["${name}.cute"]; - }) - nodes; - wireguard.interfaces.wg-k3s = { - ips = ["${node.address}/24"]; - inherit (node) listenPort; - privateKeyFile = config.sops.secrets.wireguard-k3s-private.path; - peers = lib.mapAttrsToList (_name: peer: - { - allowedIPs = ["${peer.address}/32"]; - persistentKeepalive = 25; - inherit (peer) publicKey; - } - // lib.optionalAttrs (peer ? endpoint || (isHomeNode && peer ? homeEndpoint)) { - endpoint = - if isHomeNode && peer ? homeEndpoint - then peer.homeEndpoint - else peer.endpoint; - }) (lib.filterAttrs (name: _: name != config.networking.hostName) nodes); - }; - }; - }; -} diff --git a/nix/modules/nixos/programs/direnv.nix b/nix/modules/nixos/programs/direnv.nix deleted file mode 100644 index 8067c0c5..00000000 --- a/nix/modules/nixos/programs/direnv.nix +++ /dev/null @@ -1,9 +0,0 @@ -_: { - flake.nixosModules.default = { - programs.direnv = { - enable = true; - nix-direnv.enable = true; - silent = true; - }; - }; -} diff --git a/nix/modules/nixos/programs/docker.nix b/nix/modules/nixos/programs/docker.nix deleted file mode 100644 index 77cbf997..00000000 --- a/nix/modules/nixos/programs/docker.nix +++ /dev/null @@ -1,10 +0,0 @@ -_: { - flake.nixosModules.docker = { - virtualisation.oci-containers.backend = "docker"; - - virtualisation.docker = { - enable = true; - autoPrune.enable = true; - }; - }; -} diff --git a/nix/modules/nixos/programs/fish.nix b/nix/modules/nixos/programs/fish.nix deleted file mode 100644 index 1e32ac62..00000000 --- a/nix/modules/nixos/programs/fish.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.default = { - programs.fish.enable = true; - }; -} diff --git a/nix/modules/nixos/programs/git.nix b/nix/modules/nixos/programs/git.nix deleted file mode 100644 index c3a98a1d..00000000 --- a/nix/modules/nixos/programs/git.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.default = { - programs.git.enable = true; - }; -} diff --git a/nix/modules/nixos/programs/htop.nix b/nix/modules/nixos/programs/htop.nix deleted file mode 100644 index 370f796c..00000000 --- a/nix/modules/nixos/programs/htop.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.default = { - programs.htop.enable = true; - }; -} diff --git a/nix/modules/nixos/programs/lanzaboote.md b/nix/modules/nixos/programs/lanzaboote.md deleted file mode 100644 index 619426a3..00000000 --- a/nix/modules/nixos/programs/lanzaboote.md +++ /dev/null @@ -1,63 +0,0 @@ -# Secure Boot + Automatic LUKS decryption - -1. Generate secure boot keys: - - ```bash - sudo nix run nixpkgs#sbctl create-keys - ``` - -1. Include `nixos-programs-lanzaboote` or manually enable lanzaboote in NixOS host configuration: - - ```nix - boot = { - initrd.systemd.enable = true; # For automatic decryption with TPM. - loader.systemd-boot.enable = lib.mkForce false; # Interferes with lanzaboote and must be force-disabled. - - lanzaboote = { - enable = true; - pkiBundle = "/var/lib/sbctl"; - }; - }; - ``` - -1. In UEFI, set secure boot to "setup mode" or erase platform keys. - -1. Enroll your secure boot keys: - - ```bash - sudo nix run nixpkgs#sbctl -- enroll-keys --microsoft - ``` - -1. Reboot, make sure secure boot is enabled in UEFI. - -1. Check secure boot status with `bootctl status`: - - ```bash - System: - Firmware: UEFI 2.70 (American Megatrends 5.17) - Firmware Arch: x64 - Secure Boot: enabled (user) - TPM2 Support: yes - Measured UKI: yes - Boot into FW: supported - ``` - -1. If your root drive is encrypted with LUKS, you can have the TPM automatically decrypt it on boot: - - ```bash - sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+2+7+12 --wipe-slot=tpm2 /dev/nvme0n1p2 - ``` - - Replace `/dev/nvme0n1p2` with your root partition. This policy binds the LUKS key to: - - PCR 0: core platform firmware; - - PCR 2: UEFI drivers and option ROMs loaded by the firmware; - - PCR 7: the Secure Boot state and trust policy; - - PCR 12: initrd global credentials and other boot configuration measured by the platform. - - PCR measurements are platform-dependent. Firmware or device changes can affect PCRs 0 and 2, Secure Boot key or policy changes can affect PCR 7, and NixOS or systemd updates that alter initrd global credentials can affect PCR 12. If any selected PCR differs, automatic unlock fails and the system falls back to the LUKS recovery passphrase. Always retain and test a recovery passphrase, especially on unattended systems. - - PCR 4 measures the bootloader and selected Lanzaboote EFI image. It provides stronger binding to a specific boot image, but its literal value changes when a new image is installed. Do not add PCR 4 to a static `systemd-cryptenroll --tpm2-pcrs=` policy if boot-image updates must remain unattended; managing multiple approved boot measurements requires a managed PCR policy. - - Check the [Linux TPM PCR Registry](https://uapi-group.org/specifications/specs/linux_tpm_pcr_registry/) for more details. - - **NOTE:** This requires a TPM2 module; devices with prior TPM versions will not work. diff --git a/nix/modules/nixos/programs/lanzaboote.nix b/nix/modules/nixos/programs/lanzaboote.nix deleted file mode 100644 index ae134fbb..00000000 --- a/nix/modules/nixos/programs/lanzaboote.nix +++ /dev/null @@ -1,26 +0,0 @@ -_: { - flake.nixosModules.lanzaboote = { - inputs, - lib, - pkgs, - ... - }: { - imports = [inputs.lanzaboote.nixosModules.lanzaboote]; - - boot = { - initrd.systemd.enable = true; - - lanzaboote = { - enable = true; - autoEnrollKeys.enable = true; - autoGenerateKeys.enable = true; - configurationLimit = 10; - pkiBundle = lib.mkDefault "/var/lib/sbctl"; - }; - - loader.systemd-boot.enable = lib.mkForce false; - }; - - environment.systemPackages = [pkgs.sbctl]; - }; -} diff --git a/nix/modules/nixos/programs/nh.nix b/nix/modules/nixos/programs/nh.nix deleted file mode 100644 index 60f0025b..00000000 --- a/nix/modules/nixos/programs/nh.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.default = { - programs.nh.enable = true; - }; -} diff --git a/nix/modules/nixos/programs/nix.nix b/nix/modules/nixos/programs/nix.nix deleted file mode 100644 index 290e962f..00000000 --- a/nix/modules/nixos/programs/nix.nix +++ /dev/null @@ -1,94 +0,0 @@ -_: { - flake.nixosModules.default = { - config, - lib, - ... - }: let - buildMachines = [ - { - hostName = "jubilife"; - maxJobs = 12; - protocol = "ssh-ng"; - speedFactor = 5; - sshKey = "/etc/ssh/ssh_host_ed25519_key"; - sshUser = "nixbuild"; - supportedFeatures = ["nixos-test" "benchmark" "big-parallel" "kvm"]; - systems = ["x86_64-linux"]; - } - ]; - - isBuildMachine = lib.elem config.networking.hostName (lib.map (m: m.hostName) buildMachines); - in { - config = lib.mkMerge [ - { - nix = { - buildMachines = lib.mkIf config.services.tailscale.enable ( - lib.filter (m: m.hostName != config.networking.hostName) buildMachines - ); - - distributedBuilds = true; - - gc = { - automatic = true; - - options = - if isBuildMachine - then "--delete-older-than 20d" - else "--delete-older-than 3d"; - - persistent = true; - randomizedDelaySec = "60min"; - }; - - extraOptions = '' - min-free = ${toString (1 * 1024 * 1024 * 1024)} - max-free = ${toString (5 * 1024 * 1024 * 1024)} - ''; - - optimise = { - automatic = true; - persistent = true; - randomizedDelaySec = "60min"; - }; - - settings = { - builders-use-substitutes = true; - - experimental-features = [ - "fetch-closure" - "flakes" - "nix-command" - ]; - - substituters = [ - "https://cache.nixos.org/" - "https://cutehaus.cachix.org" - ]; - - trusted-public-keys = [ - "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" - "cutehaus.cachix.org-1:KiifTsseQBitoaHH8rkDUDwzyz9akLeOM+K+e2eK8dA=" - ]; - - trusted-users = ["aly" "@admin" "@wheel" "nixbuild"]; - }; - }; - - programs.nix-ld.enable = true; - - users.users.nixbuild = lib.mkIf isBuildMachine { - uid = 1999; - isNormalUser = true; - createHome = false; - group = "nixbuild"; - }; - - users.groups.nixbuild = lib.mkIf isBuildMachine {}; - } - - (lib.mkIf isBuildMachine { - mySshKeys.authorizedUsers.nixbuild = ["aly" "root"]; - }) - ]; - }; -} diff --git a/nix/modules/nixos/programs/podman.nix b/nix/modules/nixos/programs/podman.nix deleted file mode 100644 index 43841dca..00000000 --- a/nix/modules/nixos/programs/podman.nix +++ /dev/null @@ -1,12 +0,0 @@ -_: { - flake.nixosModules.podman = { - virtualisation.oci-containers.backend = "podman"; - - virtualisation.podman = { - enable = true; - autoPrune.enable = true; - defaultNetwork.settings.dns_enabled = true; - dockerCompat = true; - }; - }; -} diff --git a/nix/modules/nixos/programs/sudo.nix b/nix/modules/nixos/programs/sudo.nix deleted file mode 100644 index 7325bb10..00000000 --- a/nix/modules/nixos/programs/sudo.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.default = { - security.sudo-rs.enable = true; - }; -} diff --git a/nix/modules/nixos/programs/systemd-boot.nix b/nix/modules/nixos/programs/systemd-boot.nix deleted file mode 100644 index 3a85c3b4..00000000 --- a/nix/modules/nixos/programs/systemd-boot.nix +++ /dev/null @@ -1,16 +0,0 @@ -_: { - flake.nixosModules.systemdBoot = {lib, ...}: { - boot = { - initrd.systemd.enable = lib.mkDefault true; - - loader = { - efi.canTouchEfiVariables = lib.mkDefault true; - - systemd-boot = { - enable = lib.mkDefault true; - configurationLimit = lib.mkDefault 10; - }; - }; - }; - }; -} diff --git a/nix/modules/nixos/repository.nix b/nix/modules/nixos/repository.nix deleted file mode 100644 index 9131f5df..00000000 --- a/nix/modules/nixos/repository.nix +++ /dev/null @@ -1,6 +0,0 @@ -_: { - flake.nixosModules.default = {self, ...}: { - environment.etc."nixos".source = self; - system.configurationRevision = self.rev or self.dirtyRev or null; - }; -} diff --git a/nix/modules/nixos/services/alloy.nix b/nix/modules/nixos/services/alloy.nix deleted file mode 100644 index eef8ab2c..00000000 --- a/nix/modules/nixos/services/alloy.nix +++ /dev/null @@ -1,51 +0,0 @@ -_: { - flake.nixosModules.alloy = { - config, - lib, - ... - }: { - options.myNixOs.service.alloy = { - lokiUrl = lib.mkOption { - description = "Loki URL to report to"; - default = "https://loki.narwhal-snapper.ts.net/loki/api/v1/push"; - type = lib.types.str; - }; - }; - - config = { - services.alloy.enable = true; - - environment.etc."alloy/config.alloy".text = '' - loki.write "default" { - endpoint { - url = "${config.myNixOs.service.alloy.lokiUrl}" - } - } - - loki.relabel "journal" { - forward_to = [] - - rule { - source_labels = ["__journal__systemd_unit"] - target_label = "unit" - } - - rule { - source_labels = ["__journal__systemd_user_unit"] - target_label = "user_unit" - } - } - - loki.source.journal "read" { - forward_to = [loki.write.default.receiver] - relabel_rules = loki.relabel.journal.rules - max_age = "12h" - labels = { - job = "systemd-journal", - host = "${config.networking.hostName}", - } - } - ''; - }; - }; -} diff --git a/nix/modules/nixos/services/atbbs.nix b/nix/modules/nixos/services/atbbs.nix deleted file mode 100644 index c0a88376..00000000 --- a/nix/modules/nixos/services/atbbs.nix +++ /dev/null @@ -1,43 +0,0 @@ -_: { - flake.nixosModules.atbbs = { - config, - lib, - ... - }: { - options.myNixOs.service.atbbs = { - port = lib.mkOption { - description = "Port to listen on."; - default = 8582; - type = lib.types.int; - }; - - telnetPort = lib.mkOption { - description = "Port to listen on for telnet."; - default = 2323; - type = lib.types.int; - }; - }; - - config = { - networking.firewall.allowedTCPPorts = [ - config.myNixOs.service.atbbs.port - config.myNixOs.service.atbbs.telnetPort - ]; - - virtualisation.oci-containers.containers = { - atbbs = { - extraOptions = ["--pull=always"]; - image = "ghcr.io/alyraffauf/atbbs"; - environment.PUBLIC_URL = "https://atbbs.xyz"; - ports = ["0.0.0.0:${toString config.myNixOs.service.atbbs.port}:80"]; - }; - - atbbs-telnet = { - extraOptions = ["--pull=always"]; - image = "ghcr.io/alyraffauf/atbbs-telnet"; - ports = ["0.0.0.0:${toString config.myNixOs.service.atbbs.telnetPort}:2323"]; - }; - }; - }; - }; -} diff --git a/nix/modules/nixos/services/auto-upgrade.nix b/nix/modules/nixos/services/auto-upgrade.nix deleted file mode 100644 index 412b8ffa..00000000 --- a/nix/modules/nixos/services/auto-upgrade.nix +++ /dev/null @@ -1,37 +0,0 @@ -_: { - flake.nixosModules.default = { - config, - lib, - ... - }: { - options.myNixOs.profile.base.flakeUrl = lib.mkOption { - type = lib.types.str; - default = "github:alyraffauf/infra"; - description = "Default flake URL for this NixOS configuration."; - }; - - config = { - environment.variables = { - FLAKE = config.myNixOs.profile.base.flakeUrl; - NH_FLAKE = config.myNixOs.profile.base.flakeUrl; - }; - - system.autoUpgrade = { - enable = true; - allowReboot = true; - dates = lib.mkDefault "02:00"; - flags = ["--accept-flake-config"]; - flake = config.myNixOs.profile.base.flakeUrl; - operation = lib.mkDefault "switch"; - persistent = true; - randomizedDelaySec = lib.mkDefault "0"; - runGarbageCollection = true; - - rebootWindow = { - lower = "02:00"; - upper = "06:00"; - }; - }; - }; - }; -} diff --git a/nix/modules/nixos/services/cachefilesd.nix b/nix/modules/nixos/services/cachefilesd.nix deleted file mode 100644 index 20bc7203..00000000 --- a/nix/modules/nixos/services/cachefilesd.nix +++ /dev/null @@ -1,13 +0,0 @@ -_: { - flake.nixosModules.cachefilesd = { - services.cachefilesd = { - enable = true; - - extraConfig = '' - brun 20% - bcull 10% - bstop 5% - ''; - }; - }; -} diff --git a/nix/modules/nixos/services/caddy.nix b/nix/modules/nixos/services/caddy.nix deleted file mode 100644 index 253bf68e..00000000 --- a/nix/modules/nixos/services/caddy.nix +++ /dev/null @@ -1,36 +0,0 @@ -_: { - flake.nixosModules.caddy = { - config, - pkgs, - self, - ... - }: { - sops.secrets.tailscaleCaddyAuth = { - sopsFile = "${self}/secrets/tailscale.yaml"; - key = "caddy_auth_env"; - }; - - networking.firewall.allowedTCPPorts = [80 443]; - - services = { - caddy = { - enable = true; - enableReload = false; - environmentFile = config.sops.secrets.tailscaleCaddyAuth.path; - - globalConfig = '' - tailscale { - ephemeral true - } - ''; - - package = pkgs.caddy.withPlugins { - plugins = ["github.com/tailscale/caddy-tailscale@v0.0.0-20260106222316-bb080c4414ac"]; - hash = "sha256-tP/ZQjZvfb+e3322dzd3I89Y9QwujcyqV1fbNWyw08g="; - }; - }; - - tailscale.permitCertUid = "caddy"; - }; - }; -} diff --git a/nix/modules/nixos/services/docker-networks.nix b/nix/modules/nixos/services/docker-networks.nix deleted file mode 100644 index 7002ef51..00000000 --- a/nix/modules/nixos/services/docker-networks.nix +++ /dev/null @@ -1,73 +0,0 @@ -_: { - flake.nixosModules.dockerNetworks = { - config, - lib, - pkgs, - ... - }: let - inherit (lib) concatMapStringsSep escapeShellArg filterAttrs listToAttrs mapAttrs' mkOption nameValuePair optionals types; - - networks = config.myNixOs.docker.networks; - - mkNetworkService = name: network: let - networkArguments = - optionals (network.subnet != null) ["--subnet" network.subnet] - ++ optionals (network.bridgeInterface != null) ["--opt" "com.docker.network.bridge.name=${network.bridgeInterface}"]; - containerServices = map (container: "docker-${container}.service") network.containers; - in - nameValuePair "docker-network-${name}" { - after = ["docker.service"]; - requires = ["docker.service"]; - before = containerServices; - requiredBy = containerServices; - - path = [pkgs.docker]; - script = '' - docker network inspect ${escapeShellArg name} >/dev/null 2>&1 || \ - docker network create --driver bridge ${concatMapStringsSep " " escapeShellArg networkArguments} ${escapeShellArg name} - ''; - serviceConfig = { - Type = "oneshot"; - RemainAfterExit = true; - }; - }; - - networksWithFirewall = filterAttrs (_: network: network.bridgeInterface != null && network.allowedTCPPorts != []) networks; - in { - options.myNixOs.docker.networks = mkOption { - default = {}; - description = "Private Docker networks managed with their dependent containers."; - type = types.attrsOf (types.submodule { - options = { - containers = mkOption { - type = types.listOf types.str; - description = "Containers that require this network."; - }; - subnet = mkOption { - type = types.nullOr types.str; - default = null; - description = "Optional IPv4 subnet for a stable network gateway."; - }; - bridgeInterface = mkOption { - type = types.nullOr types.str; - default = null; - description = "Optional Linux bridge interface name."; - }; - allowedTCPPorts = mkOption { - type = types.listOf types.port; - default = []; - description = "TCP ports exposed to containers through the bridge."; - }; - }; - }); - }; - - config = { - networking.firewall.interfaces = listToAttrs (map ( - network: nameValuePair network.bridgeInterface {inherit (network) allowedTCPPorts;} - ) (builtins.attrValues networksWithFirewall)); - - systemd.services = mapAttrs' mkNetworkService networks; - }; - }; -} diff --git a/nix/modules/nixos/services/fail2ban.nix b/nix/modules/nixos/services/fail2ban.nix deleted file mode 100644 index ce5bb06b..00000000 --- a/nix/modules/nixos/services/fail2ban.nix +++ /dev/null @@ -1,132 +0,0 @@ -_: { - flake.nixosModules.fail2ban = {config, ...}: { - environment.etc = { - "fail2ban/filter.d/forgejo.conf".text = '' - [Definition] - failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from - journalmatch = _SYSTEMD_UNIT=forgejo.service - ''; - - "fail2ban/filter.d/karakeep.conf".text = '' - [Definition] - failregex = ^.*error:\s+Authentication\serror\..*IP-Address:\s+"?"?.*$ - ignoreregex = - journalmatch = _SYSTEMD_UNIT=karakeep-web.service - ''; - - "fail2ban/filter.d/navidrome.conf".text = '' - [INCLUDES] - before = common.conf - - [Definition] - failregex = msg="Unsuccessful login".*X-Real-Ip:\[\] - ignoreregex = - journalmatch = _SYSTEMD_UNIT=navidrome.service - ''; - - "fail2ban/filter.d/vaultwarden.conf".text = '' - [INCLUDES] - before = common.conf - - [Definition] - failregex = ^.*Username or password is incorrect\. Try again\. IP: \. Username:.*$ - ignoreregex = - journalmatch = _SYSTEMD_UNIT=vaultwarden.service - ''; - - "fail2ban/filter.d/couchdb.conf".text = '' - [INCLUDES] - before = common.conf - - [Definition] - failregex = \[warning\] \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z couchdb@\d+\.\d+\.\d+\.\d+ .* couch_httpd_auth: Authentication failed for user .* from - ignoreregex = - journalmatch = _SYSTEMD_UNIT=couchdb.service - ''; - - "fail2ban/filter.d/vaultwarden-admin.conf".text = '' - [INCLUDES] - before = common.conf - - [Definition] - failregex = ^.*Invalid admin token\. IP: .*$ - ignoreregex = - journalmatch = _SYSTEMD_UNIT=vaultwarden.service - ''; - }; - - services.fail2ban = { - enable = true; - ignoreIP = [ - "10.254.0.0/24" - "100.64.0.0/10" - ]; - bantime = "24h"; - bantime-increment.enable = true; - - jails = { - couchdb = '' - enabled = true - filter = couchdb - port = 80,443,${toString config.services.couchdb.port} - maxretry = 2 - ''; - - forgejo.settings = { - action = "iptables-allports"; - filter = "forgejo"; - findtime = 3600; - maxretry = 2; - }; - - karakeep = '' - enabled = true - backend = systemd - filter = karakeep - maxretry = 2 - port = 80,443,7020 - ''; - - navidrome = '' - enabled = true - backend = systemd - filter = navidrome - maxretry = 2 - port = 0,443,${toString config.services.navidrome.settings.Port} - ''; - - nginx-http-auth = { - settings = { - enabled = true; - maxretry = 2; - findtime = 300; - }; - }; - - nginx-botsearch = { - settings = { - enabled = true; - maxretry = 10; - findtime = 300; - bantime = "24h"; - }; - }; - - vaultwarden = '' - enabled = true - filter = vaultwarden - port = 80,443,${toString config.services.vaultwarden.config.ROCKET_PORT} - maxretry = 2 - ''; - - vaultwarden-admin = '' - enabled = true - port = 80,443,${toString config.services.vaultwarden.config.ROCKET_PORT} - filter = vaultwarden-admin - maxretry = 2 - findtime = 14400 - ''; - }; - }; - }; -} diff --git a/nix/modules/nixos/services/forgejo-runner.nix b/nix/modules/nixos/services/forgejo-runner.nix deleted file mode 100644 index 27416f34..00000000 --- a/nix/modules/nixos/services/forgejo-runner.nix +++ /dev/null @@ -1,77 +0,0 @@ -_: { - flake.nixosModules.forgejoRunner = { - config, - lib, - pkgs, - self, - ... - }: { - options.myNixOs.service.forgejoRunner = { - nativeRunners = lib.mkOption { - type = lib.types.int; - default = 1; - description = "How many native NixOS runners to run."; - }; - - dockerContainers = lib.mkOption { - type = lib.types.int; - default = 1; - description = "How many docker containers to run."; - }; - }; - config = { - assertions = [ - { - assertion = config.services.tailscale.enable; - message = "We contact Forĝejo over tailscale, but services.tailscale.enable != true."; - } - ]; - - sops.secrets.act-runner = { - sopsFile = "${self}/secrets/act-runner.yaml"; - key = "TOKEN"; - }; - - services.gitea-actions-runner = let - arch = lib.replaceStrings ["-"] ["_"] pkgs.stdenv.hostPlatform.system; - in { - instances = let - tokenFile = config.sops.secrets.act-runner.path; - in { - alycodes-containers = { - inherit tokenFile; - enable = true; - labels = lib.optional (arch == "aarch64_linux") "ubuntu-24.04-arm:docker://gitea/runner-images:ubuntu-latest" ++ lib.optional (arch == "x86_64_linux") "ubuntu-latest:docker://gitea/runner-images:ubuntu-latest"; - name = "${arch}-${config.networking.hostName}-alycodes-containers"; - - settings = { - container.network = "host"; - runner.capacity = config.myNixOs.service.forgejoRunner.dockerContainers; - }; - - url = "https://git.aly.codes"; - }; - - alycodes-nixos = { - inherit tokenFile; - enable = true; - - hostPackages = with pkgs; - [bash cachix coreutils curl gawk gitMinimal gnused jq nodejs wget] - ++ [config.nix.package]; - - labels = ["nixos-${arch}:host"]; - name = "${arch}-${config.networking.hostName}-alycodes-nixos"; - - settings = { - container.network = "host"; - runner.capacity = config.myNixOs.service.forgejoRunner.nativeRunners; - }; - - url = "https://git.aly.codes"; - }; - }; - }; - }; - }; -} diff --git a/nix/modules/nixos/services/fstrim.nix b/nix/modules/nixos/services/fstrim.nix deleted file mode 100644 index a590af52..00000000 --- a/nix/modules/nixos/services/fstrim.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.default = { - services.fstrim.enable = true; - }; -} diff --git a/nix/modules/nixos/services/journald.nix b/nix/modules/nixos/services/journald.nix deleted file mode 100644 index 91f3d24e..00000000 --- a/nix/modules/nixos/services/journald.nix +++ /dev/null @@ -1,12 +0,0 @@ -_: { - flake.nixosModules.default = { - services.journald = { - storage = "persistent"; - extraConfig = '' - SystemMaxUse=1G - SystemKeepFree=1G - MaxRetentionSec=1week - ''; - }; - }; -} diff --git a/nix/modules/nixos/services/networkmanager.nix b/nix/modules/nixos/services/networkmanager.nix deleted file mode 100644 index 76bdbcd2..00000000 --- a/nix/modules/nixos/services/networkmanager.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.default = { - networking.networkmanager.enable = true; - }; -} diff --git a/nix/modules/nixos/services/openssh.nix b/nix/modules/nixos/services/openssh.nix deleted file mode 100644 index 6a83bf7a..00000000 --- a/nix/modules/nixos/services/openssh.nix +++ /dev/null @@ -1,11 +0,0 @@ -_: { - flake.nixosModules.default = { - services.openssh = { - enable = true; - openFirewall = true; - settings.PasswordAuthentication = false; - }; - - sops.age.sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"]; - }; -} diff --git a/nix/modules/nixos/services/plex.nix b/nix/modules/nixos/services/plex.nix deleted file mode 100644 index 1ba815a4..00000000 --- a/nix/modules/nixos/services/plex.nix +++ /dev/null @@ -1,67 +0,0 @@ -_: { - flake.nixosModules = { - plex = { - config, - inputs, - lib, - pkgs, - ... - }: { - options.myNixOs.service.plex.dataDir = lib.mkOption { - description = "Data directory to use."; - default = "/var/lib"; - type = lib.types.str; - }; - - config = { - services.plex = { - enable = true; - dataDir = "${config.myNixOs.service.plex.dataDir}/plex"; - extraPlugins = [ - (builtins.path { - name = "Audnexus.bundle"; - path = inputs.audnexus; - }) - (builtins.path { - name = "Hama.bundle"; - path = inputs.hama; - }) - ]; - extraScanners = [ - (builtins.path { - name = "Absolute-Series-Scanner"; - path = inputs.absolute; - }) - ]; - openFirewall = true; - }; - - systemd.services.plex.serviceConfig.TimeoutStopSec = 15; - - myNixOs.profile.backups.jobs.plex = { - backupCleanupCommand = "${pkgs.systemd}/bin/systemctl start plex"; - backupPrepareCommand = "${pkgs.systemd}/bin/systemctl stop plex"; - exclude = ["${config.services.plex.dataDir}/Plex Media Server/Plug-in Support/Databases"]; - paths = [config.services.plex.dataDir]; - }; - }; - }; - - tautulli = { - config, - pkgs, - ... - }: { - services.tautulli = { - enable = true; - openFirewall = true; - }; - - myNixOs.profile.backups.jobs.tautulli = { - backupCleanupCommand = "${pkgs.systemd}/bin/systemctl start tautulli"; - backupPrepareCommand = "${pkgs.systemd}/bin/systemctl stop tautulli"; - paths = [config.services.tautulli.dataDir]; - }; - }; - }; -} diff --git a/nix/modules/nixos/services/prometheus-node.nix b/nix/modules/nixos/services/prometheus-node.nix deleted file mode 100644 index dc8e55f3..00000000 --- a/nix/modules/nixos/services/prometheus-node.nix +++ /dev/null @@ -1,17 +0,0 @@ -_: { - flake.nixosModules.prometheusNode = { - services.prometheus.exporters.node = { - enable = true; - enabledCollectors = ["systemd"]; - - extraFlags = [ - "--collector.ethtool" - "--collector.softirqs" - "--collector.tcpstat" - "--collector.wifi" - ]; - - port = 3021; - }; - }; -} diff --git a/nix/modules/nixos/services/qbittorrent.nix b/nix/modules/nixos/services/qbittorrent.nix deleted file mode 100644 index fde525a9..00000000 --- a/nix/modules/nixos/services/qbittorrent.nix +++ /dev/null @@ -1,21 +0,0 @@ -_: { - flake.nixosModules.qbittorrent = { - config, - pkgs, - ... - }: { - services.qbittorrent = { - enable = true; - profileDir = "/var/lib/qbittorrent"; - }; - - myNixOs.profile.backups.jobs.qbittorrent = let - stop = service: "${pkgs.systemd}/bin/systemctl stop ${service}"; - start = service: "${pkgs.systemd}/bin/systemctl start ${service}"; - in { - backupCleanupCommand = start "qbittorrent"; - backupPrepareCommand = stop "qbittorrent"; - paths = [config.services.qbittorrent.profileDir]; - }; - }; -} diff --git a/nix/modules/nixos/services/syncthing.nix b/nix/modules/nixos/services/syncthing.nix deleted file mode 100644 index 8ae00210..00000000 --- a/nix/modules/nixos/services/syncthing.nix +++ /dev/null @@ -1,133 +0,0 @@ -_: { - flake.nixosModules.syncthing = { - config, - lib, - ... - }: { - options.myNixOs.service.syncthing = { - certFile = lib.mkOption { - description = "Path to the certificate file."; - type = lib.types.path; - }; - - keyFile = lib.mkOption { - description = "Path to the key file."; - type = lib.types.path; - }; - - romsPath = lib.mkOption { - default = "/home/${config.myNixOs.service.syncthing.user}/roms"; - description = "Path to the ROM folder."; - type = lib.types.path; - }; - - syncROMs = lib.mkEnableOption "Whether to sync ROMs."; - - user = lib.mkOption { - description = "User to run Syncthing as."; - type = lib.types.str; - }; - }; - - config = { - systemd.services.syncthing.environment.STNODEFAULTFOLDER = "true"; - - services = { - caddy.virtualHosts = - lib.mkIf - (config.services.caddy.enable && config.services.tailscale.enable) - { - "syncthing-${config.networking.hostName}.narwhal-snapper.ts.net" = { - extraConfig = '' - bind tailscale/syncthing-${config.networking.hostName} - reverse_proxy localhost:8384 { - header_up Host localhost - } - ''; - }; - }; - - syncthing = let - cfg = config.myNixOs.service.syncthing; - - devices = { - "allyx" = {id = "XTEVJX2-DBEFN4X-UCG43YR-V4FOQYU-DMM2WH4-AMCC5FS-42UB3DM-KUDVHQL";}; - "fallarbor" = {id = "P4URLH4-YWLMO6J-W62ET7H-TQAO3Y6-T2FAYOY-C2VTI65-VQXHVGG-NQ76PAZ";}; - "fortree" = {id = "S6PVA3I-EKOCGIU-GFX7AE6-FXM45OW-JTYN5LJ-UZ4LADZ-NNAJGDD-KST2VAG";}; - "groudon" = {id = "VOEAEAG-NP5Z3BM-DK5FO75-6G4NKSJ-3EUNFSV-VIR4KDH-OM6ZN7L-OOQKCQJ";}; - "jubilife" = {id = "52MTCMC-PKEWSAU-HADMTZU-DY5EKFO-B323P7V-OBXLNTQ-EJY7F7Y-EUWFBQX";}; - "kyogre" = {id = "SBQNUXS-H4XDJ3E-RBHJPT5-45WDJJA-2U43M4P-23XGUJ7-E3CNNKZ-BXSGIA3";}; - "oreburgh" = {id = "RFVF6DA-CQJLXTP-RKMYEB3-D2KMWJH-3Z2CIAN-PNYOXI6-FIDBFWG-JJA57AX";}; - "pacifidlog" = {id = "6EBVXYI-HZW4LQI-T6L3TTI-DZEBXJM-RP3DW7N-BCAG6FC-G2654DN-XJFSLQD";}; - "petalburg" = {id = "O75EK2H-YBXPM5D-PBYV7XB-DJKFL3E-OFZBB7H-MLCD2UT-NXQRMDG-BTZZQQH";}; - "rp5" = {id = "5AKCXRS-XU7BBSS-RDPSSLG-4BDOZ4K-OXLFQZX-HJSM53W-4GLSOAC-RZ7APA7";}; - "rpclassic" = {id = "EDNFUWI-UFYEOPI-QPJIEWF-NXVEGZ6-2J7IXW7-X22L27F-VU6JKSB-CH6GDAO";}; - "rustboro" = {id = "NY53BFH-CPVCXGH-MI5AT7E-WBK7TXS-5NQDSCW-J5BALLV-EGS2VJL-CMED2AH";}; - "slateport" = {id = "MDJFDUG-UJAXQXI-AMEF2AR-PBMD5QK-Z5ZG6AA-RCJCU3M-GZHQQEA-X2JGOAK";}; - "snowpoint" = {id = "TFSZWZB-EDIFV2P-333APP2-T655TM4-2XGA7QA-P22Z36W-3RNGX2C-DLETAQ7";}; - "sootopolis" = {id = "7QGSZ2D-CGMLPWD-OCFCBXP-7746W7F-COFV52F-Q2PMCAS-GV5DCSV-6NIXDQJ";}; - "thor" = {id = "B33X5WA-S6P4XEE-VURE4PB-WKMXHLP-6AG55LZ-QIG6ZJG-GDGXWAD-EDVIRAF";}; - "verdanturf" = {id = "CQ7A2KW-2JRZHEO-NF6NZLY-C2OX4SO-EPKQRMV-7YBSSFA-FJ2CW2P-NOIKPQB";}; - }; - - folders = lib.mkMerge [ - { - "sync" = { - devices = ["allyx" "fallarbor" "fortree" "groudon" "jubilife" "kyogre" "oreburgh" "pacifidlog" "petalburg" "rustboro" "slateport" "snowpoint" "sootopolis" "verdanturf"]; - id = "default"; - path = "~/sync"; - versioning = { - params.cleanoutDays = "5"; - type = "trashcan"; - }; - }; - - "screenshots" = { - devices = ["fallarbor" "oreburgh" "jubilife" "pacifidlog" "petalburg" "rustboro" "slateport" "snowpoint" "sootopolis" "verdanturf"]; - id = "screenshots"; - path = "~/pics/screenshots"; - versioning = { - params.cleanoutDays = "5"; - type = "trashcan"; - }; - }; - - "roms" = { - devices = ["jubilife" "oreburgh" "pacifidlog" "petalburg" "rp5" "rpclassic" "rustboro" "sootopolis" "thor"]; - id = "emudeck"; - versioning = { - params.cleanoutDays = "3"; - type = "trashcan"; - }; - }; - } - { - "roms" = { - enable = cfg.syncROMs; - path = cfg.romsPath; - }; - } - ]; - in { - enable = true; - cert = cfg.certFile; - configDir = "${config.services.syncthing.dataDir}/.syncthing"; - dataDir = "/home/${cfg.user}"; - key = cfg.keyFile; - openDefaultPorts = true; - inherit (cfg) user; - - settings = { - options = { - localAnnounceEnabled = true; - relaysEnabled = true; - urAccepted = -1; - }; - - inherit devices folders; - }; - }; - }; - }; - }; -} diff --git a/nix/modules/nixos/services/tailscale.nix b/nix/modules/nixos/services/tailscale.nix deleted file mode 100644 index 36693848..00000000 --- a/nix/modules/nixos/services/tailscale.nix +++ /dev/null @@ -1,69 +0,0 @@ -_: { - flake.nixosModules.tailscale = { - config, - lib, - self, - ... - }: { - options.myNixOs.service.tailscale = { - authKeyFile = lib.mkOption { - description = "Key file to use for authentication"; - default = config.sops.secrets.tailscaleAuthKey.path or null; - type = lib.types.nullOr lib.types.path; - }; - - operator = lib.mkOption { - description = "Tailscale operator name"; - default = null; - type = lib.types.nullOr lib.types.str; - }; - }; - config = { - sops.secrets.tailscaleAuthKey = { - sopsFile = "${self}/secrets/tailscale.yaml"; - key = "auth_key"; - }; - - assertions = [ - { - assertion = config.myNixOs.service.tailscale.authKeyFile != null; - message = "config.myNixOs.service.tailscale.authKeyFile cannot be null."; - } - ]; - - networking.firewall = { - allowedUDPPorts = [config.services.tailscale.port]; - trustedInterfaces = [config.services.tailscale.interfaceName]; - }; - - services = { - # When caddy is also enabled, expose a tailnet-hostname vhost that - # proxies the local syncthing UI through /syncthing/. - caddy = lib.mkIf config.services.caddy.enable { - virtualHosts."${config.networking.hostName}.narwhal-snapper.ts.net".extraConfig = lib.concatLines (lib.optional config.services.syncthing.enable '' - redir /syncthing /syncthing/ - handle_path /syncthing/* { - reverse_proxy localhost:8384 { - header_up Host localhost - } - } - ''); - }; - - tailscale = { - enable = true; - authKeyFile = config.myNixOs.service.tailscale.authKeyFile; - - extraUpFlags = - ["--ssh"] - ++ lib.optional (config.myNixOs.service.tailscale.operator != null) - "--operator ${config.myNixOs.service.tailscale.operator}"; - - openFirewall = true; - permitCertUid = lib.mkIf config.services.caddy.enable "caddy"; - useRoutingFeatures = "both"; - }; - }; - }; - }; -} diff --git a/nix/modules/nixos/services/timesyncd.nix b/nix/modules/nixos/services/timesyncd.nix deleted file mode 100644 index ad2097af..00000000 --- a/nix/modules/nixos/services/timesyncd.nix +++ /dev/null @@ -1,5 +0,0 @@ -_: { - flake.nixosModules.default = { - services.timesyncd.enable = true; - }; -} diff --git a/nix/modules/nixos/ssh-keys.nix b/nix/modules/nixos/ssh-keys.nix deleted file mode 100644 index 45ec05be..00000000 --- a/nix/modules/nixos/ssh-keys.nix +++ /dev/null @@ -1,40 +0,0 @@ -_: { - flake.nixosModules.default = { - config, - lib, - self, - ... - }: let - keyFiles = builtins.attrNames (builtins.readDir "${self}/keys"); - filesFor = keys: builtins.concatMap (key: config.mySshKeys.keys.${key} or []) keys; - in { - options.mySshKeys = { - keys = lib.mkOption { - type = lib.types.attrsOf (lib.types.listOf lib.types.path); - description = "Cached SSH key file paths, read once to avoid repeated filesystem scans."; - default = { - aly = lib.map (file: "${self}/keys/${file}") (lib.filter (file: lib.hasPrefix "aly_" file) keyFiles); - root = lib.map (file: "${self}/keys/${file}") (lib.filter (file: lib.hasPrefix "root_" file) keyFiles); - }; - }; - - authorizedUsers = lib.mkOption { - type = lib.types.attrsOf (lib.types.listOf lib.types.str); - default = {}; - }; - }; - - config = lib.mkMerge [ - { - mySshKeys.authorizedUsers.root = lib.mkDefault ["aly"]; - users.users.root.openssh.authorizedKeys.keyFiles = filesFor (config.mySshKeys.authorizedUsers.root or []); - } - (lib.mkIf (config.mySshKeys.authorizedUsers ? aly) { - users.users.aly.openssh.authorizedKeys.keyFiles = filesFor config.mySshKeys.authorizedUsers.aly; - }) - (lib.mkIf (config.mySshKeys.authorizedUsers ? nixbuild) { - users.users.nixbuild.openssh.authorizedKeys.keyFiles = filesFor config.mySshKeys.authorizedUsers.nixbuild; - }) - ]; - }; -} diff --git a/nix/modules/nixos/systemd.nix b/nix/modules/nixos/systemd.nix deleted file mode 100644 index cf200eff..00000000 --- a/nix/modules/nixos/systemd.nix +++ /dev/null @@ -1,8 +0,0 @@ -_: { - flake.nixosModules.default = { - systemd = { - coredump.enable = false; - enableEmergencyMode = false; - }; - }; -} diff --git a/nix/modules/nixos/users/aly.nix b/nix/modules/nixos/users/aly.nix deleted file mode 100644 index a199d8b0..00000000 --- a/nix/modules/nixos/users/aly.nix +++ /dev/null @@ -1,41 +0,0 @@ -_: { - flake.nixosModules.aly = { - config, - lib, - ... - }: { - options.myNixOs.users.aly = { - password = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - description = "Hashed password for aly."; - }; - }; - - config = { - mySshKeys.authorizedUsers.aly = ["aly"]; - - users.users.aly = { - description = "Aly Raffauf"; - - extraGroups = [ - "cdrom" - "dialout" - "docker" - "libvirtd" - "lp" - "networkmanager" - "plugdev" - "scanner" - "transmission" - "video" - "wheel" - ]; - - hashedPassword = config.myNixOs.users.aly.password; - isNormalUser = true; - uid = 1000; - }; - }; - }; -} diff --git a/nix/modules/nixos/users/defaults.nix b/nix/modules/nixos/users/defaults.nix deleted file mode 100644 index dc49aec1..00000000 --- a/nix/modules/nixos/users/defaults.nix +++ /dev/null @@ -1,10 +0,0 @@ -_: { - flake.nixosModules.default = {pkgs, ...}: { - mySshKeys.authorizedUsers.root = ["aly"]; - - users = { - defaultUserShell = pkgs.fish; - mutableUsers = false; - }; - }; -} diff --git a/nix/modules/nixos/zram.nix b/nix/modules/nixos/zram.nix deleted file mode 100644 index 99348595..00000000 --- a/nix/modules/nixos/zram.nix +++ /dev/null @@ -1,9 +0,0 @@ -_: { - flake.nixosModules.default = { - zramSwap = { - enable = true; - algorithm = "zstd"; - priority = 100; - }; - }; -} diff --git a/nix/modules/overlays.nix b/nix/modules/overlays.nix deleted file mode 100644 index 3bbf7256..00000000 --- a/nix/modules/overlays.nix +++ /dev/null @@ -1,16 +0,0 @@ -{ - flake.overlays = { - default = _final: prev: { - qbittorrent-nox = prev.qbittorrent-nox.overrideAttrs (_old: rec { - version = "5.2.2"; - - src = prev.fetchFromGitHub { - owner = "qbittorrent"; - repo = "qBittorrent"; - rev = "release-${version}"; - hash = "sha256-5lGv1ajuDE/DTqUbnVeRRBcXntrzn6bs72mZbQMf7Fc="; - }; - }); - }; - }; -} diff --git a/nix/modules/packages.nix b/nix/modules/packages.nix deleted file mode 100644 index 27aa26ee..00000000 --- a/nix/modules/packages.nix +++ /dev/null @@ -1,18 +0,0 @@ -{ - perSystem = { - config, - lib, - pkgs, - ... - }: { - packages = { - gen-files = pkgs.writeShellApplication { - name = "gen-files"; - - text = '' - ${lib.getExe config.files.writer.drv} - ''; - }; - }; - }; -} diff --git a/nix/modules/treefmt.nix b/nix/modules/treefmt.nix deleted file mode 100644 index 8958666b..00000000 --- a/nix/modules/treefmt.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ - perSystem.treefmt.config = { - settings.global.excludes = [ - # `sops-rekey` generates this file and rewrites encrypted recipient - # metadata in both secret locations. Formatting ciphertext would create - # a noisy, invalid rekey diff. - ".sops.yaml" - "secrets/*.yaml" - "k8s/flux/secrets/*.sops.yaml" - # Draft Helm templates are intentionally retained without being rendered - # or validated as Kubernetes YAML. - "k8s/drafts/**" - # Flux-generated upstream manifest (flux install output); Renovate bumps - # it verbatim, so don't let prettier reformat/diverge it from upstream. - "k8s/flux/system/gotk-components.yaml" - ]; - - programs = { - alejandra.enable = true; - deadnix.enable = true; - prettier.enable = true; - shellcheck.enable = true; - shfmt.enable = true; - statix.enable = true; - taplo.enable = true; - terraform.enable = true; - }; - }; -} diff --git a/nix/overlays.nix b/nix/overlays.nix new file mode 100644 index 00000000..ce619da4 --- /dev/null +++ b/nix/overlays.nix @@ -0,0 +1,5 @@ +_: { + flake.overlays = { + default = _final: _prev: {}; + }; +} diff --git a/nix/treefmt.nix b/nix/treefmt.nix new file mode 100644 index 00000000..e6c1574a --- /dev/null +++ b/nix/treefmt.nix @@ -0,0 +1,15 @@ +_: { + perSystem = _: { + treefmt.config = { + programs = { + alejandra.enable = true; + prettier.enable = true; + shellcheck.enable = true; + shfmt.enable = true; + terraform.enable = true; + }; + + settings.excludes = ["secrets/**"]; + }; + }; +} diff --git a/renovate.json b/renovate.json index 86f27879..a06ffd55 100644 --- a/renovate.json +++ b/renovate.json @@ -2,86 +2,14 @@ "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": ["config:recommended", ":dependencyDashboard"], "timezone": "America/New_York", - "schedule": ["* 22-23,0-5 * * *"], - "labels": ["dependencies"], - - "nix": { - "enabled": true - }, - - "flux": { - "managerFilePatterns": ["/^k8s/flux/.*\\.ya?ml$/"] - }, - - "lockFileMaintenance": { - "enabled": true, - "automerge": true - }, - - "customManagers": [ - { - "customType": "regex", - "managerFilePatterns": [ - "/^k8s\\/(?:charts|flux\\/(?:apps|platform))\\/.*\\.ya?ml$/" - ], - "matchStrings": [ - "\\s*(?:image|imageName|pluginImage):\\s+[\"']?(?[^\\s\"'{}]+?):(?[^\\s\"'@{}]+)@(?sha256:[a-f0-9]{64})[\"']?" - ], - "datasourceTemplate": "docker" - }, - { - "customType": "regex", - "managerFilePatterns": ["/^k8s/charts/.*\\.ya?ml$/"], - "matchStrings": [ - "repository:\\s+[\"']?(?[^\\s\"']+)[\"']?\\s+tag:\\s+[\"']?(?[^\\s\"'@]+)@(?sha256:[a-f0-9]{64})[\"']?" - ], - "datasourceTemplate": "docker" - }, - { - "description": "Shared image pins in the global values file (the cute-haus-global ConfigMap is generated from it)", - "customType": "regex", - "managerFilePatterns": ["/^k8s/flux/sources/global\\.values\\.ya?ml$/"], - "matchStrings": [ - "\\s+\\w+:\\s+(?[^:\\s]+(?:/[^:\\s]+)*):(?[^@\\s]+)@(?sha256:[a-f0-9]{64})" - ], - "datasourceTemplate": "docker" - }, - { - "description": "Direct OCI containers on NixOS hosts, including per-stack modules", - "customType": "regex", - "managerFilePatterns": [ - "/^nix/modules/hosts/nixos/.*/containers(?:/.*)?\\.nix$/" - ], - "matchStrings": [ - "image = \\\"(?[^\\s\\\"]+):(?[^@\\\"]+)@(?sha256:[a-f0-9]{64})\\\"" - ], - "datasourceTemplate": "docker" - } - ], - "packageRules": [ { - "description": "Skip Forgejo (Forgejo registries resolve with skopeo but return no-result in Renovate)", - "enabled": false, - "matchPackageNames": [ - "codeberg.org/forgejo/forgejo", - "data.forgejo.org/forgejo/forgejo" - ] - }, - { - "description": "Auto-merge routine updates after CI passes", - "matchUpdateTypes": ["minor", "patch", "digest", "pin", "pinDigest"], + "matchUpdateTypes": ["minor", "patch", "pin", "pinDigest"], "automerge": true }, { - "description": "Major bumps stay manual", "matchUpdateTypes": ["major"], "automerge": false } - ], - - "vulnerabilityAlerts": { - "enabled": true, - "labels": ["security"] - } + ] } diff --git a/scripts/bump-image.ts b/scripts/bump-image.ts deleted file mode 100755 index 373e415b..00000000 --- a/scripts/bump-image.ts +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/env bun -// Bumps the digest of every digest-pinned image (including sidecars) in a -// Helm chart or raw Flux workload manifest to the current upstream. -// -// Usage: -// bun scripts/bump-image.ts bump one workload (top-level + sidecars) -// bun scripts/bump-image.ts --all bump every public digest-pinned workload -// bun scripts/bump-image.ts --check report only, exit 1 if anything is stale -// -// Discovers direct image references in local Helm templates and raw Flux -// workload manifests. Floating tags are skipped — they don't need bumping. -// -// Private registries that need credentials are skipped here too — `skopeo -// inspect --no-creds` can't reach them. Bump those via their own recipe -// (e.g. `just bump-tranquil` for atcr.io). - -import { $ } from "bun"; - -const MANIFEST_GLOBS = [ - "k8s/charts/*/templates/**/*.yaml", - "k8s/flux/apps/*/**/*.yaml", - "k8s/flux/platform/*/**/*.yaml", -]; -const IMAGE_RE = /image:\s+(\S+?):(\S+?)@(sha256:[a-f0-9]+)/g; -const PRIVATE_REGISTRIES = ["atcr.io/"]; - -type PinnedImage = { - workloadName: string; - manifestPath: string; - repository: string; - floatTag: string; - currentDigest: string; -}; - -function workloadNameFromPath(manifestPath: string): string { - const pathSegments = manifestPath.split("/"); - if (pathSegments[1] === "charts") return pathSegments[2]; - return pathSegments[3]; -} - -const privateRegistryWorkloads = new Set(); - -async function discoverPinnedImages(): Promise { - const pinned: PinnedImage[] = []; - - for (const manifestGlob of MANIFEST_GLOBS) { - const glob = new Bun.Glob(manifestGlob); - for await (const manifestPath of glob.scan(".")) { - const workloadName = workloadNameFromPath(manifestPath); - const text = await Bun.file(manifestPath).text(); - - for (const match of text.matchAll(IMAGE_RE)) { - const repository = match[1]; - const floatTag = match[2]; - const currentDigest = match[3]; - - if ( - PRIVATE_REGISTRIES.some((registry) => repository.startsWith(registry)) - ) { - privateRegistryWorkloads.add(workloadName); - continue; - } - - pinned.push({ - workloadName, - manifestPath, - repository, - floatTag, - currentDigest, - }); - } - } - } - - return pinned; -} - -async function fetchUpstreamDigest( - repository: string, - floatTag: string, -): Promise { - const result = await $` - skopeo inspect --no-creds docker://${repository}:${floatTag} --format ${"{{.Digest}}"} - ` - .quiet() - .nothrow(); - if (result.exitCode !== 0) { - throw new Error( - `skopeo failed for ${repository}:${floatTag}: ${result.stderr.toString().trim()}`, - ); - } - return result.stdout.toString().trim(); -} - -function label(image: PinnedImage): string { - const short = image.repository.split("/").slice(-1)[0]; - return `${image.workloadName} (${short})`; -} - -function shortDigest(digest: string): string { - return digest.slice(7, 19); -} - -async function bumpImage( - image: PinnedImage, - write: boolean, - commitEach: boolean, -): Promise { - const upstream = await fetchUpstreamDigest(image.repository, image.floatTag); - if (upstream === image.currentDigest) { - console.log(`${label(image)}: ✓ up to date`); - return false; - } - - const before = shortDigest(image.currentDigest); - const after = shortDigest(upstream); - - console.log(`${label(image)}: ${before} → ${after}`); - - if (write) { - const text = await Bun.file(image.manifestPath).text(); - const updated = text.replace(image.currentDigest, upstream); - await Bun.write(image.manifestPath, updated); - - if (commitEach) { - const short = image.repository.split("/").slice(-1)[0]; - const msg = `k8s/${image.workloadName} (${short}): ${image.floatTag}@${before} → ${image.floatTag}@${after}`; - await $`git add ${image.manifestPath}`; - await $`git commit -m ${msg}`; - } - } - return true; -} - -// --- main --- - -const arg = process.argv[2]; -if (!arg || arg === "-h" || arg === "--help") { - console.error("usage: bump-image.ts | --all | --check"); - process.exit(2); -} - -const allImages = await discoverPinnedImages(); - -let imagesToBump: PinnedImage[]; -let shouldWrite = true; - -if (arg === "--all") { - imagesToBump = allImages; -} else if (arg === "--check") { - imagesToBump = allImages; - shouldWrite = false; -} else { - imagesToBump = allImages.filter((image) => image.workloadName === arg); - if (imagesToBump.length === 0) { - if (privateRegistryWorkloads.has(arg)) { - console.error( - `${arg} is on a private registry; use its dedicated recipe (e.g. \`just bump-tranquil\`)`, - ); - process.exit(1); - } - console.error(`no workload '${arg}' with a public digest-pinned image`); - process.exit(1); - } -} - -const commitEach = shouldWrite; - -let staleCount = 0; -for (const image of imagesToBump) { - const wasStale = await bumpImage(image, shouldWrite, commitEach); - if (wasStale) staleCount++; -} - -if (staleCount > 0) { - if (arg === "--check") { - console.error(`\n${staleCount} image(s) stale`); - process.exit(1); - } else { - console.log(`\n${staleCount} image(s) bumped`); - } -} diff --git a/scripts/bun.lock b/scripts/bun.lock deleted file mode 100644 index 1511a8ac..00000000 --- a/scripts/bun.lock +++ /dev/null @@ -1,21 +0,0 @@ -{ - "lockfileVersion": 1, - "configVersion": 1, - "workspaces": { - "": { - "name": "cute-haus-scripts", - "devDependencies": { - "@types/bun": "latest", - }, - }, - }, - "packages": { - "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="], - - "@types/node": ["@types/node@26.2.0", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg=="], - - "bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="], - - "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="], - } -} diff --git a/scripts/check-chart-inventory.ts b/scripts/check-chart-inventory.ts deleted file mode 100644 index 30e6eb43..00000000 --- a/scripts/check-chart-inventory.ts +++ /dev/null @@ -1,115 +0,0 @@ -// Every local chart is intentionally declared: production charts have at least -// one HelmRelease, while undeployed charts live in k8s/drafts. A chart may be -// used by more than one release (for example, the two Valkey instances). - -const FLUX_DIRS = [ - "k8s/flux/infra-crds", - "k8s/flux/infra-core", - "k8s/flux/platform", - "k8s/flux/apps", - "k8s/flux/external-routes", -]; - -type HelmRelease = { - kind?: string; - spec?: { chart?: { spec?: { chart?: string } } }; -}; - -function yamlDocuments(text: string): string[] { - return text - .split(/^---\s*$/m) - .map((document) => document.trim()) - .filter(Boolean); -} - -async function declaredChartCounts(): Promise> { - const counts = new Map(); - - for (const directory of FLUX_DIRS) { - const files = new Bun.Glob(`${directory}/**/*.yaml`); - for await (const path of files.scan(".")) { - for (const document of yamlDocuments(await Bun.file(path).text())) { - const release = Bun.YAML.parse(document) as HelmRelease | null; - const chart = release?.spec?.chart?.spec?.chart; - if ( - release?.kind !== "HelmRelease" || - !chart?.startsWith("./k8s/charts/") - ) - continue; - - const name = chart.slice("./k8s/charts/".length); - counts.set(name, (counts.get(name) ?? 0) + 1); - } - } - } - - return counts; -} - -async function chartDirectories(root: string): Promise> { - const charts = new Set(); - const files = new Bun.Glob(`${root}/*/Chart.yaml`); - for await (const path of files.scan(".")) { - charts.add(path.split("/")[2]); - } - return charts; -} - -async function rawApplicationNames(): Promise> { - const names = new Set(); - for (const layer of ["apps", "platform"]) { - const files = new Bun.Glob(`k8s/flux/${layer}/*/kustomization.yaml`); - for await (const path of files.scan(".")) { - names.add(path.split("/")[3]); - } - } - return names; -} - -export async function checkChartInventory(): Promise { - const [declared, production, drafts, rawApplications] = await Promise.all([ - declaredChartCounts(), - chartDirectories("k8s/charts"), - chartDirectories("k8s/drafts"), - rawApplicationNames(), - ]); - const errors: string[] = []; - - for (const chart of production) { - const count = declared.get(chart) ?? 0; - if (count === 0) - errors.push( - `production chart '${chart}' has no HelmRelease; move it to k8s/drafts or deploy it`, - ); - } - - for (const chart of drafts) { - const count = declared.get(chart) ?? 0; - if (count !== 0) - errors.push( - `draft chart '${chart}' is also deployed by ${count} HelmRelease(s)`, - ); - if (production.has(chart)) - errors.push(`chart '${chart}' exists in both k8s/charts and k8s/drafts`); - } - - for (const [chart, count] of declared) { - if (!production.has(chart)) - errors.push( - `HelmRelease references '${chart}', which is not a production chart (${count} release(s))`, - ); - } - - for (const application of rawApplications) { - if (declared.has(application)) - errors.push( - `application '${application}' is declared as both a Helm chart and raw Kustomize workload`, - ); - if (production.has(application)) - errors.push( - `raw Kustomize application '${application}' still has a production Helm chart`, - ); - } - - return errors; -} diff --git a/scripts/check-forward-auth.ts b/scripts/check-forward-auth.ts deleted file mode 100755 index 83762532..00000000 --- a/scripts/check-forward-auth.ts +++ /dev/null @@ -1,95 +0,0 @@ -// Every `integration: forward-auth` OIDC client must have a matching app in -// the forward-auth chart, and vice versa. - -const OIDC_CLIENTS_FILE = "ansible/playbooks/vars/oidc-clients.yml"; -const FORWARD_AUTH_VALUES_FILE = "k8s/flux/apps/forward-auth.yaml"; -const SLUG_PREFIX = "forward-auth-"; - -type OIDCClient = { slug: string; integration?: string }; -type OIDCFile = { oidc_clients: OIDCClient[] }; -type HelmRelease = { - kind?: string; - metadata?: { name?: string }; - spec?: { values?: { apps?: Record } }; -}; - -async function readYaml(path: string): Promise { - return Bun.YAML.parse(await Bun.file(path).text()) as T; -} - -function difference(a: Set, b: Set): string[] { - const result: string[] = []; - for (const item of a) { - if (!b.has(item)) result.push(item); - } - return result.sort(); -} - -function splitYamlDocuments(text: string): string[] { - return text - .split(/^---\s*$/m) - .map((doc) => doc.trim()) - .filter(Boolean); -} - -async function readForwardAuthApps(): Promise> { - const text = await Bun.file(FORWARD_AUTH_VALUES_FILE).text(); - for (const doc of splitYamlDocuments(text)) { - const parsed = Bun.YAML.parse(doc) as HelmRelease | null; - if ( - parsed?.kind === "HelmRelease" && - parsed.metadata?.name === "forward-auth" - ) { - return parsed.spec?.values?.apps ?? {}; - } - } - - return {}; -} - -export async function checkForwardAuth(): Promise { - const oidc = await readYaml(OIDC_CLIENTS_FILE); - const chartApps = await readForwardAuthApps(); - - const forwardAuthClients = oidc.oidc_clients.filter( - (client) => client.integration === "forward-auth", - ); - - const errors: string[] = []; - - // Every forward-auth client's slug must start with `forward-auth-` so the - // integration task can derive the Deployment name from it. - const slugsWithBadPrefix: string[] = []; - for (const client of forwardAuthClients) { - if (!client.slug.startsWith(SLUG_PREFIX)) - slugsWithBadPrefix.push(client.slug); - } - if (slugsWithBadPrefix.length > 0) { - errors.push( - `OIDC slug(s) missing '${SLUG_PREFIX}' prefix: ${slugsWithBadPrefix.join(", ")}`, - ); - } - - // The app name is the slug with the prefix stripped, e.g. - // `forward-auth-navidrome` → `navidrome`. That must equal a key in the chart. - const oidcAppNames = new Set( - forwardAuthClients.map((client) => client.slug.replace(SLUG_PREFIX, "")), - ); - const chartAppNames = new Set(Object.keys(chartApps)); - - const onlyInOIDC = difference(oidcAppNames, chartAppNames); - if (onlyInOIDC.length > 0) { - errors.push( - `OIDC client(s) without a matching app in ${FORWARD_AUTH_VALUES_FILE}: ${onlyInOIDC.join(", ")}`, - ); - } - - const onlyInChart = difference(chartAppNames, oidcAppNames); - if (onlyInChart.length > 0) { - errors.push( - `App(s) in ${FORWARD_AUTH_VALUES_FILE} without a matching OIDC client: ${onlyInChart.join(", ")}`, - ); - } - - return errors; -} diff --git a/scripts/check-pinned-images.ts b/scripts/check-pinned-images.ts deleted file mode 100644 index 6d256173..00000000 --- a/scripts/check-pinned-images.ts +++ /dev/null @@ -1,110 +0,0 @@ -// Every deployed chart must pin every container image to a sha256 digest. -// Charts in ALLOW_FLOATING are exempt — usually because they live on a -// private registry with active dev where pinning would break the -// push-and-redeploy loop. - -const GLOB = "k8s/charts/*/**/*.yaml"; -const RAW_GLOBS = [ - "k8s/flux/apps/*/**/*.yaml", - "k8s/flux/platform/*/**/*.yaml", -]; -const FLUX_DIRS = [ - "k8s/flux/infra-crds", - "k8s/flux/infra-core", - "k8s/flux/platform", - "k8s/flux/apps", - "k8s/flux/external-routes", -]; -const ALLOW_FLOATING = new Set(); - -type HelmRelease = { - kind?: string; - spec?: { chart?: { spec?: { chart?: string } } }; -}; - -function chartNameFromPath(templatePath: string): string { - return templatePath.split("/")[2]; -} - -async function deployedChartNames(): Promise> { - const names = new Set(); - - for (const dir of FLUX_DIRS) { - const glob = new Bun.Glob(`${dir}/**/*.yaml`); - for await (const path of glob.scan(".")) { - const text = await Bun.file(path).text(); - for (const doc of text - .split(/^---\s*$/m) - .map((doc) => doc.trim()) - .filter(Boolean)) { - const parsed = Bun.YAML.parse(doc) as HelmRelease | null; - if (parsed?.kind !== "HelmRelease") continue; - - const chart = parsed.spec?.chart?.spec?.chart; - if (chart?.startsWith("./k8s/charts/")) { - names.add(chart.replace(/^\.\/k8s\/charts\//, "")); - } - } - } - } - - return names; -} - -export async function checkPinnedImages(): Promise { - const deployed = await deployedChartNames(); - const errors: string[] = []; - - const glob = new Bun.Glob(GLOB); - for await (const templatePath of glob.scan(".")) { - const chartName = chartNameFromPath(templatePath); - if (!deployed.has(chartName)) continue; - if (ALLOW_FLOATING.has(chartName)) continue; - - const text = await Bun.file(templatePath).text(); - // Find concrete image refs in our local chart YAML. Template-composed refs - // are checked where their concrete tag is defined in values.yaml. - const imageLines = [ - ...text.matchAll( - /^\s*(?:image|imageName):\s+["']?([^"'\s{}]+:[^"'\s{}]+)["']?\s*$/gm, - ), - ]; - for (const match of imageLines) { - const fullRef = match[1]; - if (!fullRef.includes("@sha256:")) { - const [repo, tag] = fullRef.split(":"); - const shortRepo = repo.split("/").slice(-1)[0]; - errors.push( - `${chartName}: ${shortRepo} '${tag}' is not pinned to a sha256 digest`, - ); - } - } - } - - for (const rawGlob of RAW_GLOBS) { - const rawFiles = new Bun.Glob(rawGlob); - for await (const manifestPath of rawFiles.scan(".")) { - const application = manifestPath.split("/")[3]; - if (ALLOW_FLOATING.has(application)) continue; - - const text = await Bun.file(manifestPath).text(); - const imageLines = [ - ...text.matchAll( - /^\s*(?:image|imageName):\s+["']?([^"'\s{}]+:[^"'\s{}]+)["']?\s*$/gm, - ), - ]; - for (const match of imageLines) { - const fullRef = match[1]; - if (fullRef.includes("@sha256:")) continue; - - const [repo, tag] = fullRef.split(":"); - const shortRepo = repo.split("/").slice(-1)[0]; - errors.push( - `${application}: ${shortRepo} '${tag}' is not pinned to a sha256 digest`, - ); - } - } - } - - return errors; -} diff --git a/scripts/check-release-names.ts b/scripts/check-release-names.ts deleted file mode 100644 index 50611499..00000000 --- a/scripts/check-release-names.ts +++ /dev/null @@ -1,71 +0,0 @@ -// Every deployed local Helm chart must reference an actual -// k8s/charts//Chart.yaml. - -const FLUX_DIRS = [ - "k8s/flux/infra-crds", - "k8s/flux/infra-core", - "k8s/flux/platform", - "k8s/flux/apps", - "k8s/flux/external-routes", -]; - -type Release = { name: string; chart: string }; -type HelmRelease = { - kind?: string; - metadata?: { name?: string }; - spec?: { chart?: { spec?: { chart?: string } } }; -}; - -function splitYamlDocuments(text: string): string[] { - return text - .split(/^---\s*$/m) - .map((doc) => doc.trim()) - .filter(Boolean); -} - -async function fluxLocalReleases(): Promise { - const releases: Release[] = []; - - for (const dir of FLUX_DIRS) { - const glob = new Bun.Glob(`${dir}/**/*.yaml`); - for await (const path of glob.scan(".")) { - const text = await Bun.file(path).text(); - for (const doc of splitYamlDocuments(text)) { - const parsed = Bun.YAML.parse(doc) as HelmRelease | null; - if (parsed?.kind !== "HelmRelease") continue; - - const chart = parsed.spec?.chart?.spec?.chart; - if (!chart?.startsWith("./k8s/charts/")) continue; - - releases.push({ - name: parsed.metadata?.name ?? path, - chart, - }); - } - } - } - - return releases; -} - -function chartYamlPath(chart: string): string { - return chart.replace(/^\.\//, "") + "/Chart.yaml"; -} - -export async function checkReleaseNames(): Promise { - const errors: string[] = []; - - const releases = await fluxLocalReleases(); - - for (const release of releases) { - const chartYaml = chartYamlPath(release.chart); - const exists = await Bun.file(chartYaml).exists(); - if (!exists) { - errors.push( - `release '${release.name}' points to ${release.chart} but ${chartYaml} does not exist`, - ); - } - } - - return errors; -} diff --git a/scripts/check.ts b/scripts/check.ts deleted file mode 100755 index 97bee47d..00000000 --- a/scripts/check.ts +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bun -// Runs every consistency check and reports all failures (so one broken -// check doesn't hide another). Exits non-zero if any check fails. - -import { checkForwardAuth } from "./check-forward-auth.ts"; -import { checkChartInventory } from "./check-chart-inventory.ts"; -import { checkPinnedImages } from "./check-pinned-images.ts"; -import { checkReleaseNames } from "./check-release-names.ts"; - -const checks = [ - { name: "chart-inventory", run: checkChartInventory }, - { name: "forward-auth", run: checkForwardAuth }, - { name: "release-names", run: checkReleaseNames }, - { name: "pinned-images", run: checkPinnedImages }, -]; - -let failedCount = 0; -for (const check of checks) { - const errors = await check.run(); - if (errors.length === 0) { - console.log(`${check.name}: ✓`); - continue; - } - failedCount++; - for (const error of errors) { - console.error(`${check.name}: ${error}`); - } -} - -if (failedCount > 0) process.exit(1); diff --git a/scripts/k8s-status.ts b/scripts/k8s-status.ts deleted file mode 100644 index 49c7753f..00000000 --- a/scripts/k8s-status.ts +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/env bun -// Print only Kubernetes and Flux failures. Each item includes the shortest -// useful follow-up command for the single-operator incident workflow. - -type KubernetesObject = { - kind?: string; - metadata?: { name?: string; namespace?: string; creationTimestamp?: string }; - reason?: string; - message?: string; - spec?: { replicas?: number }; - status?: { - phase?: string; - readyReplicas?: number; - conditions?: Array<{ type?: string; status?: string; message?: string }>; - }; -}; - -type KubernetesList = { items?: KubernetesObject[] }; - -async function kubectlJson(arguments_: string[]): Promise { - const process = Bun.spawn(["kubectl", ...arguments_, "-o", "json"], { - stdout: "pipe", - stderr: "pipe", - }); - const output = await new Response(process.stdout).text(); - const error = await new Response(process.stderr).text(); - if ((await process.exited) !== 0) throw new Error(error.trim()); - return JSON.parse(output) as KubernetesList; -} - -function objectName(object: KubernetesObject): string { - return `${object.metadata?.namespace ?? "default"}/${object.metadata?.name ?? "unknown"}`; -} - -function readyCondition(object: KubernetesObject): boolean { - return ( - object.status?.conditions?.some( - (condition) => condition.type === "Ready" && condition.status === "True", - ) ?? false - ); -} - -function failedObjects(objects: KubernetesObject[]): KubernetesObject[] { - return objects.filter((object) => !readyCondition(object)); -} - -function unhealthyWorkloads(objects: KubernetesObject[]): KubernetesObject[] { - return objects.filter((object) => { - if (object.kind === "StatefulSet") { - return ( - (object.status?.readyReplicas ?? 0) !== (object.spec?.replicas ?? 1) - ); - } - return !object.status?.conditions?.some( - (condition) => - condition.type === "Available" && condition.status === "True", - ); - }); -} - -const findings: Array<{ title: string; lines: string[] }> = []; - -function collectFindings(title: string, lines: string[]): boolean { - if (lines.length === 0) return false; - findings.push({ title, lines }); - return true; -} - -let degraded = false; -try { - const [ - kustomizations, - releases, - deployments, - statefulSets, - pvcs, - certificates, - events, - ] = await Promise.all([ - kubectlJson(["get", "kustomizations.kustomize.toolkit.fluxcd.io", "-A"]), - kubectlJson(["get", "helmreleases.helm.toolkit.fluxcd.io", "-A"]), - kubectlJson(["get", "deployments", "-A"]), - kubectlJson(["get", "statefulsets", "-A"]), - kubectlJson(["get", "pvc", "-A"]), - kubectlJson(["get", "certificates.cert-manager.io", "-A"]), - kubectlJson([ - "get", - "events", - "-A", - "--field-selector=type=Warning", - "--sort-by=.lastTimestamp", - ]), - ]); - - degraded = - collectFindings( - "Flux Kustomizations", - failedObjects(kustomizations.items ?? []).map( - (object) => - `${objectName(object)} — flux reconcile kustomization ${object.metadata?.name} -n ${object.metadata?.namespace} --with-source`, - ), - ) || degraded; - degraded = - collectFindings( - "Flux HelmReleases", - failedObjects(releases.items ?? []).map( - (object) => - `${objectName(object)} — flux reconcile helmrelease ${object.metadata?.name} -n ${object.metadata?.namespace} --with-source`, - ), - ) || degraded; - const workloads = [ - ...(deployments.items ?? []), - ...(statefulSets.items ?? []), - ]; - degraded = - collectFindings( - "Unhealthy workloads", - unhealthyWorkloads(workloads).map( - (object) => - `${object.kind?.toLowerCase()} ${objectName(object)} — kubectl describe ${object.kind?.toLowerCase()} ${object.metadata?.name} -n ${object.metadata?.namespace}`, - ), - ) || degraded; - degraded = - collectFindings( - "Unbound PVCs", - (pvcs.items ?? []) - .filter((pvc) => pvc.status?.phase !== "Bound") - .map( - (pvc) => - `${objectName(pvc)} — kubectl describe pvc ${pvc.metadata?.name} -n ${pvc.metadata?.namespace}`, - ), - ) || degraded; - degraded = - collectFindings( - "Certificate problems", - failedObjects(certificates.items ?? []).map( - (certificate) => - `${objectName(certificate)} — kubectl describe certificate ${certificate.metadata?.name} -n ${certificate.metadata?.namespace}`, - ), - ) || degraded; - collectFindings( - "Recent warning events (do not imply current degradation)", - (events.items ?? []) - .slice(-20) - .map( - (event) => - `${objectName(event)} ${event.reason ?? "Warning"}: ${event.message ?? ""} — kubectl get events -A --field-selector=type=Warning --sort-by=.lastTimestamp`, - ), - ); -} catch (error) { - degraded = true; - findings.push({ - title: "Kubernetes status unavailable", - lines: [ - `${error instanceof Error ? error.message : error} — kubectl cluster-info`, - ], - }); -} - -console.log(`Kubernetes status: ${degraded ? "DEGRADED" : "HEALTHY"}`); -for (const finding of findings) { - console.log(`\n${finding.title}`); - for (const line of finding.lines) console.log(`- ${line}`); -} -if (degraded) process.exit(1); diff --git a/scripts/package.json b/scripts/package.json deleted file mode 100644 index 37e40bbb..00000000 --- a/scripts/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "cute-haus-scripts", - "private": true, - "type": "module", - "devDependencies": { - "@types/bun": "latest" - } -} diff --git a/scripts/render-releases.ts b/scripts/render-releases.ts deleted file mode 100644 index fe1a0278..00000000 --- a/scripts/render-releases.ts +++ /dev/null @@ -1,199 +0,0 @@ -#!/usr/bin/env bun -// Render every local HelmRelease with the same global values and precedence -// Flux uses. SOPS-backed values are intentionally not read in CI. - -import { join } from "node:path"; - -const FLUX_DIRS = [ - "k8s/flux/infra-crds", - "k8s/flux/infra-core", - "k8s/flux/platform", - "k8s/flux/apps", - "k8s/flux/external-routes", -]; - -// These charts use literal resource names. Keep their HelmRelease name equal -// to the chart directory so a rename cannot silently orphan or collide with -// an existing workload. -const FIXED_NAME_CHARTS = new Set([ - "morsels", - "navidrome", - "ombi", - "seerr", - "uptime-kuma", - "vaultwarden", -]); - -type HelmRelease = { - kind?: string; - metadata?: { name?: string }; - spec?: { - releaseName?: string; - targetNamespace?: string; - chart?: { spec?: { chart?: string } }; - values?: Record; - valuesFrom?: Array<{ kind?: string; name?: string; valuesKey?: string }>; - }; -}; - -function yamlDocuments(text: string): string[] { - return text - .split(/^---\s*$/m) - .map((document) => document.trim()) - .filter(Boolean); -} - -function mergeValues( - base: Record, - override: Record, -): Record { - const merged = { ...base }; - for (const [key, value] of Object.entries(override)) { - const existing = merged[key]; - if ( - value !== null && - typeof value === "object" && - !Array.isArray(value) && - existing !== null && - typeof existing === "object" && - !Array.isArray(existing) - ) { - merged[key] = mergeValues( - existing as Record, - value as Record, - ); - } else { - merged[key] = value; - } - } - return merged; -} - -async function localReleases(): Promise { - const releases: HelmRelease[] = []; - for (const directory of FLUX_DIRS) { - const files = new Bun.Glob(`${directory}/**/*.yaml`); - for await (const path of files.scan(".")) { - for (const document of yamlDocuments(await Bun.file(path).text())) { - const release = Bun.YAML.parse(document) as HelmRelease | null; - const chart = release?.spec?.chart?.spec?.chart; - if ( - release?.kind === "HelmRelease" && - chart?.startsWith("./k8s/charts/") - ) - releases.push(release); - } - } - } - return releases.sort((left, right) => - (left.metadata?.name ?? "").localeCompare(right.metadata?.name ?? ""), - ); -} - -async function run(command: string[], input?: string): Promise { - const process = Bun.spawn(command, { - stdin: input ? new Blob([input]) : undefined, - stdout: "inherit", - stderr: "inherit", - }); - if ((await process.exited) !== 0) throw new Error(command.join(" ")); -} - -async function commandOutput(command: string[]): Promise { - const process = Bun.spawn(command, { - stdout: "pipe", - stderr: "inherit", - }); - const output = await new Response(process.stdout).text(); - if ((await process.exited) !== 0) throw new Error(command.join(" ")); - return output; -} - -async function renderRelease( - release: HelmRelease, - globalValues: Record, -): Promise { - const name = release.metadata?.name; - const chart = release.spec?.chart?.spec?.chart; - if (!name || !chart) - throw new Error("HelmRelease is missing a name or chart"); - - const chartName = chart.replace(/^\.\/k8s\/charts\//, ""); - if ( - FIXED_NAME_CHARTS.has(chartName) && - (release.spec?.releaseName ?? name) !== chartName - ) { - throw new Error( - `${name}: fixed-name chart '${chartName}' must use releaseName '${chartName}'`, - ); - } - - for (const source of release.spec?.valuesFrom ?? []) { - if ( - source.kind !== "ConfigMap" || - source.name !== "cute-haus-global" || - source.valuesKey !== "values.yaml" - ) { - throw new Error( - `${name}: renderer only supports the non-secret cute-haus-global valuesFrom source`, - ); - } - } - - const values = mergeValues(globalValues, release.spec?.values ?? {}); - const valuesPath = join( - process.env.TMPDIR ?? "/tmp", - `cute-haus-${name}-${crypto.randomUUID()}.yaml`, - ); - await Bun.write(valuesPath, Bun.YAML.stringify(values)); - - try { - console.log(`${name}: lint and render`); - await run(["helm", "dependency", "build", chart]); - await run(["helm", "lint", chart, "--values", valuesPath]); - - const rendered = Bun.spawn([ - "helm", - "template", - release.spec?.releaseName ?? name, - chart, - "--namespace", - release.spec?.targetNamespace ?? "default", - "--values", - valuesPath, - "--include-crds", - ]); - const manifest = await new Response(rendered.stdout).text(); - if ((await rendered.exited) !== 0) - throw new Error(`${name}: helm template`); - - await run(["kubeconform", "-ignore-missing-schemas", "-summary"], manifest); - } finally { - await run(["rm", "-f", valuesPath]); - } -} - -async function renderRawKustomizations(): Promise { - for (const layer of ["apps", "platform"]) { - const files = new Bun.Glob(`k8s/flux/${layer}/*/kustomization.yaml`); - for await (const path of files.scan(".")) { - const directory = path.replace(/\/kustomization\.yaml$/, ""); - console.log(`${directory}: render and validate`); - const manifest = await commandOutput(["kubectl", "kustomize", directory]); - await run( - ["kubeconform", "-ignore-missing-schemas", "-summary"], - manifest, - ); - } - } -} - -const globalValues = Bun.YAML.parse( - await Bun.file("k8s/flux/sources/global.values.yaml").text(), -) as Record; - -for (const release of await localReleases()) { - await renderRelease(release, globalValues); -} - -await renderRawKustomizations(); diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json deleted file mode 100644 index 33034356..00000000 --- a/scripts/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - "lib": ["ESNext"], - "target": "ESNext", - "module": "ESNext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "types": ["bun"], - "strict": true, - "skipLibCheck": true, - "noEmit": true, - "allowImportingTsExtensions": true - } -} diff --git a/scripts/update-caddy-tailscale.ts b/scripts/update-caddy-tailscale.ts deleted file mode 100755 index 158a763e..00000000 --- a/scripts/update-caddy-tailscale.ts +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env bun -// Bumps the caddy-tailscale plugin pseudo-version + content hash to the -// latest commit on master, then commits the change. If nothing changed, -// exits silently. Mirrors the original bash recipe. -// -// Two-step build dance: -// 1. Update the version, try to build with the current hash. -// 2. If nix rejects the hash, blank it out, build again to capture -// the correct hash from nix's "got: sha256-..." error, write it back. - -import { $ } from "bun"; - -const CADDY_FILE = "nix/modules/nixos/services/caddy.nix"; -const GITHUB_REPO = "tailscale/caddy-tailscale"; -const NIX_BUILD_TARGET = - ".#nixosConfigurations.jubilife.config.services.caddy.package"; - -type GithubCommit = { - sha: string; - commit: { committer: { date: string } }; -}; - -async function fetchLatestVersion(): Promise { - const url = `https://api.github.com/repos/${GITHUB_REPO}/commits?per_page=1`; - const response = await fetch(url); - if (!response.ok) { - console.error(`github api: ${response.status} ${response.statusText}`); - process.exit(1); - } - const [latestCommit] = (await response.json()) as GithubCommit[]; - const shortSha = latestCommit.sha.slice(0, 12); - // YYYY-MM-DDTHH:MM:SSZ → YYYYMMDDHHMMSS, the Go pseudo-version style. - const timestamp = latestCommit.commit.committer.date.replaceAll( - /[-T:Z]/g, - "", - ); - return `v0.0.0-${timestamp}-${shortSha}`; -} - -async function readCaddyNix(): Promise { - return Bun.file(CADDY_FILE).text(); -} - -async function writeCaddyNix(contents: string): Promise { - await Bun.write(CADDY_FILE, contents); -} - -function currentVersionIn(caddyNix: string): string { - const match = caddyNix.match(/caddy-tailscale@([^"]+)/); - if (!match) { - console.error(`could not find caddy-tailscale version in ${CADDY_FILE}`); - process.exit(1); - } - return match[1]; -} - -async function tryBuild(): Promise<{ ok: boolean; output: string }> { - const result = await $`nix build ${NIX_BUILD_TARGET}`.quiet().nothrow(); - const output = result.stderr.toString() + result.stdout.toString(); - return { ok: result.exitCode === 0, output }; -} - -async function commit(message: string): Promise { - await $`git add ${CADDY_FILE}`; - await $`git commit -m ${message}`; - console.log(`done — committed`); -} - -// --- main --- - -const latestVersion = await fetchLatestVersion(); -let caddyNix = await readCaddyNix(); -const oldVersion = currentVersionIn(caddyNix); - -const versionChanged = oldVersion !== latestVersion; -if (versionChanged) { - console.log(`updating caddy-tailscale: ${oldVersion} → ${latestVersion}`); - caddyNix = caddyNix.replace( - /caddy-tailscale@[^"]+/, - `caddy-tailscale@${latestVersion}`, - ); - await writeCaddyNix(caddyNix); -} else { - console.log(`caddy-tailscale already at ${latestVersion}`); -} - -const firstAttempt = await tryBuild(); -if (firstAttempt.ok) { - if (versionChanged) { - await commit(`caddy: update caddy-tailscale to ${latestVersion}`); - } else { - console.log("already up to date"); - } - process.exit(0); -} - -// Hash mismatch — blank it so nix tells us the correct one. -console.log("hash is stale, fetching new hash..."); -caddyNix = (await readCaddyNix()).replace(/hash = "sha256-[^"]*"/, 'hash = ""'); -await writeCaddyNix(caddyNix); - -const blankAttempt = await tryBuild(); -const newHash = blankAttempt.output.match(/got:\s+(sha256-\S+)/)?.[1]; -if (!newHash) { - console.error("could not extract new hash from nix output"); - process.stderr.write(blankAttempt.output); - process.exit(1); -} - -caddyNix = (await readCaddyNix()).replace('hash = ""', `hash = "${newHash}"`); -await writeCaddyNix(caddyNix); -console.log(`updated hash: ${newHash}; verifying build`); -await $`nix build ${NIX_BUILD_TARGET}`; - -await commit( - versionChanged - ? `caddy: update caddy-tailscale to ${latestVersion}` - : `caddy: update caddy-tailscale hash to ${newHash}`, -); diff --git a/secrets/act-runner.yaml b/secrets/act-runner.yaml deleted file mode 100644 index 3f47f120..00000000 --- a/secrets/act-runner.yaml +++ /dev/null @@ -1,106 +0,0 @@ -TOKEN: ENC[AES256_GCM,data:6dLMVfaaddSUk8TF0IxIGHrhQkXb8clvSbddbppndx17Cm6+dOgqEIM6woj2iw==,iv:MkzX9PTYr2xGpiOlVKEr5AyF9UKIDRBkkWhBE2XUjqM=,tag:eY7LosXNJvHWcWVq+oFmDQ==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkTzMrWGhZUHJ1M25RNVFv - SDJtelZGbCtod3VWZ0VFaEMvRGx5L2Q0TjE0Clk0dGxvaDNjM3pXWnp1S3YyaVIy - T3RnWHdCT0FodTZJZ3FUV0IwQUJNbWsKLS0tIEdWUjJjUi9NaWtnNnBobTRDUkN0 - MEN5ZkRzY1pKekNsRjZqclNZMm1QYTAK1tPdunpy3T6lG4P8rxN/wB4yP7yWnp/H - 47/WCyG7igzFJhdVWvXjPzmF9L7eyl8xHj98MevBZMiE1zP//pbBAQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3Y3oxTTJ3bXRkSmc2ZW81 - TFQ5OWh6Z3ZENGM5NW1VTlJWZGIxZ2Z6YURjCmdMZ2NQSzM0NWNZb242TXozNWN3 - a3hsRWRhdWhlTzRJZXpXZ1FOVDhFb3MKLS0tIGpObVo3Q1dxVUZCdkdyNGZ2MlZi - RUp4a1ZRbllGMmVQUXlUcjVZSGJxa0EKjVcaJG9/DfHZFu6jxIXDaUux68jMPxB3 - xrgUG8baIYatPC6/Wgp/JOgg6dR2Ae4Qypi4+P6XmkrCV4IwZtS2TA== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxd2ozUmtsU2V1bVdnQ0g2 - ZVM0RjdmRWd4L0NkaG9TTVZtd0xoNlJpT0R3CmRlRTFQQUVLT2ZBVVp0K0xqd3hN - ck5VYTZIK2JReEUwbkF1amdFY1Z5eDgKLS0tIFRBeTJvcExibG9HVGU4MmIxYzZV - TUkwMTBWdDJzOHBHVHVIdVFQdTRqTGMKRsTL/IZmmFal3EiiLCQg3lnkIFSnkxTy - bxHnsbHr2s/foA4UQKSxli28q0MVGZeFbCimdzD5CCs/x9Zq5/k38A== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEajVZcGhFVzMzaTNQVTVF - Tk9CTE1Ob0JWUWRBazg4R0NDZ0ljNjQ4NlZnCmJDM0x0Z1VqSUY0YjhvRVpjRlBn - YmtJNGExYUk3d0E5U2JCWG1LbTV5ZFUKLS0tIERpTFQrVDRoZEs0azcwTmc2SWxs - UVhzZXhKMjJ4SFp2L2JiUHFYUjYwQ3MKGS5j/M3P5WIigt7La8POb0McJ4wP8oNM - 6iMxjYaSaZid5C2Vpqypw94hbvAAIPmrUfJY8UELleVFbxk8GR1kaQ== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvRy9pM01jZlVaWWViQ0pD - QmkxaEU1WTZpOERmL2UvSWFzeWEzU05zRWhNCmZidFhXWUhESm9yZnJLQTR2dDlw - TnRnaWpmMVIxcnFqaWZlcjhrbUErVXMKLS0tIHc1TjQ5VzQ2Nm93V09XZ3c4YnNE - UWFXUS84Q05kU042Um5SK0VlcmNBYkUKjnzbzOwA525p4RrM3R32wiZci33URUnz - AsRW3hV0IcoBrRJGJIs/mIBanQ+NOvEmO/b2WNFL78ohQQjAEE/Scg== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHZGdtcFh4M2VnVHBvMXJl - S0ZpeHc0VjBKS0FsaGF4Y3c0TlZTNnhCM3hJCmJFOTlCNTNEVURGYzgzVi80amtj - QktLUE1NMk1RZ3o0SmJsck1zVXROUzgKLS0tIFpZMjZxUjRZaThLdmVSNm95cmVC - ZUZaS21pOW8wOGZqTk9ySE5Fb29KbEkKOcu7qI7vyRlB8kC2Um+BSqNHC2g5tRMl - kRmrg91eFCeuPSR+3qetAaxTCK/BvtCQCgGOen/6tXppKMP+OzGoEg== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAycWNXL0toa0tiYmZiaGNw - YytHRnhxZ28yaG5XM0dyNGx2WGQvU3RuWVRRCnJUMWZWNEJjWDY2emRIYm9pZU5n - dU5IRlQ0aHRndnloQnlHS1lzK0FSNmcKLS0tIGFVUGF6UDBKVTNudWNFRFl2VTVZ - bUNpeUEzVGFzbUd2YzlzbkM0eUFuWnMKpNJ8+et8DxaJecD8BXNV26EbKG2tzBS3 - braMczkaMq+MgijPiIvub1sIqcLnLKkR7fekL3yJpNxrldh5m74RDA== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAycFg0MFBwWnlDTEdyRzV0 - TDNhZFZlNk1Ya3NsODBYOGlUcTJudFZPcEZ3CkxBWXFtcVl4cjVrQ2NDT0lzR2hR - aWkzYlNMSy9CSEVtdG11b3R5Tk4zNTAKLS0tIFh1bjZOUVN6VkpKbUdQOWk4bGNC - aEtaMlZmbVhucHBWbE1HVGxUVUxoOW8K2CfnRw2wvuR0iymYNp9YLDalrzh9kpm5 - VSeU6zc/dMAP+TdCt1kaC7qmfGIDuYuVWiM3HFZkbM+yMDkodwT60Q== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkSDNUV3FOL0wrdHR4czNa - WkE3VTlYQ3Y5VGZWN0VEb1UzVElUWTN5WkI0CkZ1SFFoWmdCSHBoU2U0dUt0blhC - MTQ0QXdrNmFvQzVIUW16WTA1N2hla0kKLS0tIGFTSEllVlZjUkViSjVYZm40QXJh - U1phSUhVMEFXME1FY29kaEZFM1dDU2MKaL9ef5tm1Bc50pqRcsj61T8Uy0o24zpi - 0zFS9u6V07+YLwZ3ttZ4edouxFjRB48n1zUFsUB7tLx+0fkI6wC9UQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIM2tXdWhGaGV0TTU3Q1Na - dDR5cXgxZStNUFBCM28rOEZGbXl0VUN2dFg4Cng3dEtkR3VndTU3bE04clRPSGdJ - ZVJLd1BEaTdQZDBaWUozZ1dMRjJ0U0kKLS0tIFpvdkdPTUVibHJzMUQ4TkRaOG5M - S1F2UTYyL3Z3YVpOQnNGZWsvd2hQOEkKfT2TKwmD7tTw9ylyNrDHiICsIw+HboM9 - zaq5Vd+VVqbvMPI7Gp676Wd4+XxydFgLSBhwIjNLF+SlXp3z8KW6/A== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuUWV3U3Q2VUV5eER6b1cz - TENKY09ZRmdnYXhDK2JLZ0V2VDRPNkgyWEdRCno5d1JSVkhRbEFtMUpmdERvZUYx - cXpKbkxBa1dDUU1FYkV5blVSNXdEN1UKLS0tIFJwdjl1RDFYZHhWZ1BLNkRKRmVS - LzA0NmxNdnQ5TFdwbE1RZWcrUGlvZDAKavD9C+I8bCpi8CGAmAG3FydjNNLp8n3S - Wf2qrXfdz08wMy2T5MlpcReCj5vjmaPbjAMBbrfA4JQeibLCNCl00Q== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - lastmodified: "2026-05-09T01:18:09Z" - mac: ENC[AES256_GCM,data:n0FeIAHA+Cq3dc+HhzD/UO2Lc/vPFjCUBdEaVMwbnTh1mY+PclTx9NoM+se2ENe2gl62+jBrsua8xNpR+85ldl+TtBpv8GmSF2BQIGLyxaJtsq8i4Mva4HuT8II2vTlgNmvsxd/1JzG4IuTkRqtzq+mmcQA9nH9+qat3Y0/Bk/E=,iv:Zzxb3izsXxygzTKchMoh44NgqutV+Zl03QZKKMOHG6Y=,tag:9vipMd5M0p7bkvzkrZVyng==,type:str] - unencrypted_suffix: _unencrypted - version: 3.12.2 diff --git a/secrets/arr.yaml b/secrets/arr.yaml deleted file mode 100644 index 755362f9..00000000 --- a/secrets/arr.yaml +++ /dev/null @@ -1,110 +0,0 @@ -bazarr_api_key: ENC[AES256_GCM,data:cPDQmmaKHj+2sva84uFlkOa9rRrzPIZjgP8/Bf8Iogs=,iv:7IuWe0kRa/zAWDfg7wlSQfDKqTrlwjy9vJxEAowsFPs=,tag:tySiYvPwb2OWMMxoyANGog==,type:str] -lidarr_api_key: ENC[AES256_GCM,data:Ljw4hVql1xrvu9auFbATG7T3XdHNFAwffsXqPyswgK0=,iv:L9cJgM/3LUP31w+dplQ9ON/AwB4ATao1vgp6yHyoxeQ=,tag:nkAOIp58+EJLeoj6U49zXw==,type:str] -prowlarr_api_key: ENC[AES256_GCM,data:WcFoCgaaY8DOeoBh2n3hVEmMn+0WNCgNBwxS+tggzsM=,iv:en92VWOC1e3rotel9cQAVGZDSieWBcDBfSvoj0KmwFY=,tag:QFw60hcSnPUpNF9gxU9wqw==,type:str] -radarr_api_key: ENC[AES256_GCM,data:B1u9uCStscVqRispqtQR3tmyJPw5SXkOKwRw5Z7zwYk=,iv:acjwPpDNzdBX5iKDuRpidLyLCFgTGbd+OBpSaaYygJA=,tag:lEO0WaUJfD9gma/SzQXOvg==,type:str] -sonarr_api_key: ENC[AES256_GCM,data:lYs1LZoSfdsbiQ/BLayfYnMlsAcA8DtW06zd07nRErM=,iv:mAk2JVmuQHUqjz5GtYz1T8Y6zjaSKHTPvcsL9KCQQL8=,tag:yI1TK/tcTMiXx+BooAyDCg==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmNExWMWFLNnN4VmRrZk12 - YVFDMm83TGxQVVN1d3YyemRJNHh0cklwYXpVCnJZZW1sWFVURzhXa2FZZ3BZNVNy - L1R6d1Z0RWRzcUR5bFhNaGE5clRPQ2sKLS0tIHVFdHFBaEdsZjNGQk14TXdkMVNG - ZVhFYXZWOHlaMUphNnZVTVVNM3JSdGcKHAnGCkKvu53ksxwLhdbhFYjf59Br9GQv - pIVrEdHV9Cyjdsk7wFt7fgpRaPZ4icLAJy2Zr0b/DoRUFakPQSEfIg== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3WHF6YTAwOVYxM3NIdUg3 - blFPaHpGVXFESVNlTWk5YUNXV25aVnFwdjN3CkFvMzREeEhKM1dxZzdFdXh3dXJy - ajR2QU5iKzB5ejFKSkpZMEJLelBOcjgKLS0tIE1IZDNkWnM3VTZtQVNpeTlUcEVu - ZC9zbzhIb0lOdWRhblZaOTlPRTFIWFEKXgc7xg07Z1YeyytjBi81Hkjt+Dd62KUt - oxVcaqHNODJWViw0Bki6N+6QG+rTTjJKROv0gSEIa1DyXPsV/zFIzg== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0NzM3QTNaaFFkckFJbXk0 - NHp4VGlXa1Y4WTduTkorNmlsNDBtMVRydlJFCkR6M3ZWQTZjV205dG52SnB1aUxJ - WnBzVHVoVHUwZDZ2cjkzR1FrN1lha0kKLS0tIHh0a2VoZFBVMktjNG9PTkd5dVdR - bVdYR2p1Sy9Velo2TmR4SmxSNzQrZ28KhZ3asoxyG5IGQoQgyIBQBzE+JD8X7joF - 4sIT/x7AD1QURPWiWg8mWeNfBrMXi1Nn12ufZPLj6Ykt2cxKmO6mbg== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFYVdEQXdMMjhMMWwrcEQw - aE1ydEllRG5aZHk3RHJvSUI3d3RzTjJxNHpFCnVDRThTR0VLQmtlSUl5TzM3M05t - K2xDTmxxbzZLS2lHbFF1TUtvYmhZRlkKLS0tIHc5eGJ0a0ZRNUJpbjVSSEpYb0NF - cjBSM1RxaTEvUEdLdFBLODNrNEN6bzgKLeqjz+3xP/z9mwTphluZJy5KNrMfF+99 - 4uy+PIbBT/Rxd7GayEYmX6CgaHwLDxp6E53VStJhVwi5UbqFvI+NeA== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtMXVQWjFqeVJwNlNFajN5 - K2oyZzdtY2dqQmJBRTRMMExibjhYNzYzYWlvCnFtVkJteXg3RzNFYjdaTExLTmtQ - T0JJMXBqTlNXV0Z0OXA4d1o5dittRFkKLS0tIDRVODE5VVFBWkdvQmxGR2MySEpl - T2RLSjR2WE1xL29MUVdFUisza1FTSEkK7jrStj5omLxNLNpLe1QLjYk/eSpIMIit - mS8CqNX2GgYDmGZXxziHDu7FhEV1EGeFCwlusS+N07iDeloF8NlNRg== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGbE5PWUdnclhvVDg3MWtq - UGlPYTl2algwSGxYdHBycWVYU2pFOUw0OW53CmZYeWtBbFRsTEpNaXpXZ3E4Slor - L250ZEg3ZUczdzVIOUxOKzFLN3ZVMW8KLS0tIElVc0Ivd0dHcmVvaXNKMmJVQ2cr - dHVYOGNETWJjK2FRS3lLNkMyYlZQUXMKz+/+Zg3oj9I/HEHdKMFiliLAvcYRSQdG - 0OB4UJf9LTixfWUyQpH4rn6TNq10ySEC92YA3U5ndZplIhTehGeUYw== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsYmR4ZlBMdHJBNHp0ZVdj - dXNlTkVPK0YrRWQxYXFMbzQyTjlDTEc4bzI4CnhmNjNOc3Z3Ri9XT3VpMGdTcVBs - VW5OYkFpQmZnWUgzSUd6eFM1bUpVdmsKLS0tIFJUUXNLMTVDNUNaNDNQRUJFLzgz - bitsSkFodkVFWXVqOExmZ2tETnZ5STQKmNc8IWGJwPncGqHQAqN0Z9ZQ5JIUUfgE - KyIj6pbSVep8fKBCDodyGGPBguyY0+qP7NMagR3P5jUoCJ9+x+sqVA== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6aDg1ekVTb2JybXNlcU1I - WGVNMm1tUlZyMFc0eWJGTEdnMi9HNzBtWmh3CjRIV1hTekxhbndWdDZtWDZpak1W - YjdhT29yMXExeXJKZUhpcDUwMnhrcmcKLS0tIHVoL2hSV1lENkU5R2NobzFPck11 - bTVGQVM1QkZGeEgvU045cmFCZWl5SmsKEbNAkMtXfOgCfCHHTvJp+mu/BXFB2Vd7 - XdfYcKr+kq3h201yGMSDKcCqulgmTyvuGw2TgZe4on2ywEzsy3SOnA== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHTStBaElTU0xFUU5NUWlU - a2hiZnVDQnByTTMvU2xBRmh3bWZmc3NaSWlVCmlaK2ZmUUFyNkVCTWxnVHVRTGRQ - Zzd6c1I4K0RGVTA2dStvbkdkWFZoYVEKLS0tIHY3aTJnVzloclRrTEduWFR2MG8y - eXFxNC95M1RZSFB5N3EyejhOV21TWWcKtwuFx3L8VYqFyOrdz/V+zpcCY2XZyzpd - RbFK7FqfzT3qU/sKnIiNxs8YS59LOrtfNuPDBNaNF4DJfum/dBSTtw== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBudlhZaGVGeG5KTGk5aTdW - cWxPeC9HM29DT0JpYzRJYkM5RzdmSXFRWHlNCncxWnl3OG5EaG5yTnQreXpvdDdy - NVNlWE5mVElxbVNJU1V6Q2pyRURlWGsKLS0tIHZGcS9IdElTd1JyQVcwejNoMy9X - RGxadUIxRTRXYTBnanFPMFptZG9IZlUKTvW2bhpu541pIqSKuIQ4XsZ1kzN0amm/ - EmectCseGAPuqmPHo4dHwKy8A8Ue5Ee866Xc7f3kZjorznNv9QabUw== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFMThnR2VJd3psWTcrUXV3 - bnFBNWFleElXK1I3eDBqMjlmRVluUUx1WDNnCmpZbmxjSGVsaVczcUtxdzZLanlC - SFJ0YitrM0VhUG9rSW9YWGhRa0VSYk0KLS0tIE51dFhVMDNnRThCY0J1MEc5clBX - c2MzcWpHMzdtenRpOWo5ZURNTm9FZDQK75NNsT0fJrLsQ8c/fTaGbz093Pjx+iGa - It8FCIrOKX1rEowxpRoOcblODFWCXYYZSPGuT4RlBzbBMmUYEq5tUg== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - lastmodified: "2026-05-09T01:18:09Z" - mac: ENC[AES256_GCM,data:yuNW51nq6s8S1PRMtOrs3TgaBiAx8Lm7aPi0RO26aSma2Qhm2VS2qsavXU2yXPmOtgskDsGx5uCtNvZNJgTPrNdD3yczXpza7AqC/x2CwgiQ3X5Yk/PEegtoZS1vz0agZrXFd9b1qp4cDkg1X1fwoW6xOlTwbysEbksLax+EpK8=,iv:xof9LPShAQ3w2WKuvX0S6lTRCTR+nxyEjANgos3O4JE=,tag:doJ2ve67VfWvVpfPdablfg==,type:str] - unencrypted_suffix: _unencrypted - version: 3.12.2 diff --git a/secrets/atcr.yaml b/secrets/atcr.yaml deleted file mode 100644 index 518c7ba5..00000000 --- a/secrets/atcr.yaml +++ /dev/null @@ -1,107 +0,0 @@ -username: ENC[AES256_GCM,data:es7yWoo1iwhXqxaJtt5IR/NUi4gz/CM7yw==,iv:E1JuIXqTL4+/53S4RsDx4kATznJqlfaJz75lLBPYkF8=,tag:nrUc7YTtmBwmnOkeWoaCQQ==,type:str] -password: ENC[AES256_GCM,data:tpm9YHx+oO4eHmKEQzAUrKuU7g==,iv:9SfpJJmgw0qle2d93PsI46/iu05X97aLmi3glURYSqU=,tag:uRilqfRKjiW6Y2SlbbJARA==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUTk93U3crY2s3YURManZZ - MG5xd2RaVGhqT1RDZko3VWF5SFRVQkc4MjN3CmtlY1E0QXpxMExLSWxKNkVKV01S - UGc3WnJiSCtSTzBtU3N3S05TWEt1S00KLS0tIDQxKzhhVk9BWnY5MVVFd2VxTGE2 - WmNVVndjS3NDQ0tBazI1NFU4WlAvdXMKReQ6kUBLV9BHNQ2Efnnj/xvi0KyAG8PY - YpkSF2i4TqO2X7DMIN1VFsz5G7q2qXJqkwlKPv37R2etUeUf9OldLA== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5ekllZDJVM2FtQ1MzNlJa - Z2J6bHFaUmhBVjRXQlR1bEJ0eWZ4M1F1bnhjCnp6ZEpIM2lheC9VcHpTQmpVbU1l - NEdKSnJ5RkpmeFRCQmNxY1kvcmdlN00KLS0tIHFvS1E5MlZac0dvSmRmbC9VMEZ0 - eHYrY2swME93OVhDUzZ1VXkxa1kvV2MKS2TEKDm0H0n6jUvcoyJG0HQCynJJHin5 - ZVY2llwSFxXxAhG18Mmgqw/qJifeCpyHxgUwAmr7wPnZ533nA0EwQw== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4ajcwMDFzTHB2cFFHOVQr - UTNEU083SUhObU1lWTUybU16OWV4THl4RG5BCjZyR055aCt6aTR1R1MvNTBOTG5q - dHlsQ2ZGTmN6bWp5Nk93U3NtL2I2bnMKLS0tIEg0SG1ZL2swY2pqSENVOWp5dWhs - OHJaMkxFOU1Ta2JnR3ZNdjk0SHVsNkUKTw++xdTRgsf+KwCqLEhg9lTyGtoHmJ7u - T7SypRXZt00sX33lPpZZ0tUb/rWnYZe3HGHoB+wbDfZCf18LMjt2VA== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuMGJBWE45TGMwMXpsT0Zt - N0ozTklDa01tUklBVGNvQVMzWVBFMU5NZ3hvCmJ3NWhDRzdHanZrZm5PZXZLQUV6 - U1UwZG9qcVdzTjBXS21DQm9aOUtiUDAKLS0tIEtFS1A3OTB6d1BGOHY4UDlvR3Fz - OXFValZvd2hUL1pUOEx0QWRrU0E1QmsKCuWDzNQJPI8dCIBwrB+bVKzYttbelCxg - ArGp9T+PTA5YgQULNxKLMBYB/XFQanjLljEAGwizO6j1/C656OW6Ng== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkb1pkd1phUlpxdTdseHZz - Rk91UU1nTXZ5NGUrTEhERlAvMHU2WUhCR2tZCmJCL3FtUFltZ0RUVkJmT1RYOGhH - NU9PVE9xdmxISVEzSkxlMERST1RmN1kKLS0tIEtlQjFwa3hQeVJIWCtqTjNXMmtB - dlBpRUd5L0tlUzhiYnYrcjk2QXVOcnMKmaDmDtcXiE4sJJm4BmBQP1WFOohM221F - eSWyHYxqsaerPtCoATDlf2tCGilUDfnxS5PWfQatDVGqQNB1nGH7qw== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMRjFiMjhJOEFxTzd0NUts - OTllZEF4RHlxeExRMUVodCsyT01URHYvQ0Q4ClVIdVR4UGNTVm55YTI3OHBYNjA2 - WmRRQjMxNGoxeXMraUR5QnZVZmxuUDQKLS0tIExPR3J2R216bUVTRWc5R0FGbExa - YytqRSsxb0E5ZXpRaFFVL1hqNHdJWEUKmYA8TCeo5RCoDb6jYCkHyDjONQvmqWOM - Otoot7ub2n0xI6DtsyIfB20ybM9K1O57kzHz9e1U063pEuhZ/N/Hkw== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzSDgxb1FTZVlVQXNYRlJ6 - WXZDTnRNYVIvUE5rdlo3ZTNHQmlOeWpoUkJFCjllamxPVUhCK3l3Tk1mQ1lsVmlG - anptS0c3aUx3TDlObVpuQTJDSlQvZG8KLS0tIGtlQXcxSjJVcnU4SkZmWERtbytp - MnRQeGtYd29ldHNZRTBxenFKL0RCWWsKs43UUjf8On5+BnheqJdK9Cn756CSYyiE - 3ChLJ7ZGfpJiERvLShnFsJgD4vSZ7mtrWRtboSwtr0Re6CgxiJBODQ== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4SzhQZEtCWXNkSW50YTdr - VlRYd2Zia0VyclBFQlUwckdnSi9ETitFcUNjCnlZdThpeUh3ZExsZklRSWYrcTVW - bkRRRjZHcDZkcTArREJVUllRbEdJcjgKLS0tIGxUeXVsQ2Q0cVQrN1VxSmIwUGZ0 - MWhSSXFUbmN0cVFSMFhKalRTcERyZHMKwLAgQCX9ewDqpDWOVYX6aVq2ALQH1F4w - ez60unKOx77YJl/LiByNVAclEnj8N64HEshvlfSzHYTN1mRZDSRr2w== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0U2loZHRSeE92NGEvWXpF - cC9jZ3lnOGVaMHpoKzBpUjRpcURlQ25BVTM4CnRtUzNnOEZ5K0JBSlgyT3RQWi81 - T3dGbWpLYzdWR0MrSWFVQzY0UzMvSWsKLS0tIEVsaEhqRVdjZjR2ZWRtZGM5b0hO - WlNuODBsY3llOTMzYnNwd0NGUnpaTmcKzAmt4IfF49WL8oovTaCgvDrhQ4Wii+CY - csJG0bJHJHkUmS2XrTYAXyjDt8Iqk5wyInRzqP1U1WvuHg6w62woDg== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6RTQvWllubk5SN0o3UHVu - ak5OaWl6R0FON2dLYzhaZjFVbFRqdExiQXdzCnN6S3FpSVcrTS83Z01JVFNYK3J3 - ejFJSGxzMWlrYVFwcmJSRzlBVHZ5aE0KLS0tIHd4N3dCTnhjWDZqRFovVVFUWFNU - WGFVV3hrWDBsZU9YZ2xWSCtBclBsWEkKFoYWOysZ15UbpjMAah0vzH0mCbBoHkEA - UQjb7yBGbICe2S2kpHS1dt9U62lFmPXj0Vi/fCXMAM6nJ/VIQ3cEjA== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2M0F6ZC90SUxqZk0wWHB1 - OGJ3UUJCWS9pZGZtMFZkWk82ZUgySU16QkRNCitpVnFnZUEyN1JYSGdkWDBSNjRD - dDdaSXI0dUFBeStIMnNGbVJnRktGb00KLS0tIEtVNnpZTm12cHgxZE1kQ0l2TmJr - WWZYTnFuMEgyZm45eCs2UkZEbmpSclUK/G2sGtqM7LRQ8UUpWNkJgtXkMpERBpot - 4CRlEfOFlWNiJrYnBTwINuMkLLLBjq74f6fQ268gYN+208Zs/4GVYQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - lastmodified: "2026-05-11T13:53:11Z" - mac: ENC[AES256_GCM,data:b3J4wZE8A/EpSh4C2c3S+eIFLjF4bSHglG/+HVN0HiuTNk3DXDzdQc/A3nGWDqqBcZYk7QaIjl/W9u7AjfYhCFW8y6q6Up3ROjnQq5XH3dYq3OjZ+cUO0Xcb4L+G05GSy4cLY9zguBtvwVMJH3ugIXgZcnyZVhJcZdP1FX2GnoQ=,iv:adDQqvKjdtIUdwEZEdsOMjquJB2PN5KbPvULR2ct0ZY=,tag:iBmuTtZ6Y6fNgRRKigRmmQ==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.0 diff --git a/secrets/b2.yaml b/secrets/b2.yaml index 9cdebc6f..067fc964 100644 --- a/secrets/b2.yaml +++ b/secrets/b2.yaml @@ -5,103 +5,67 @@ sops: age: - enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLMXlDN2NuVlZRb1REMlpq - bFZFN3BQeHo0MXZaUUUrcXN5WmRlU3dUSGlJCitJZFhscTYvdVJaMmQzUWZVeS9p - bFpuZm5zMnc2UjdjaGdLeUh0RDdyeUUKLS0tIG5FSXoxQVQvdEUxc2FQT0N6WTAz - NlNYdnVEQlVheFFpZW03MVdEeTRKcDgKUnuHe1uDhHpZB14/z3G8ohtHM9knrGgp - bM5+JAaF881sR2hHbHVNp2+nAJQK681TePpqNEJXZhWwO0Q2nx9+iA== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVT1lieG5VZlNxTlBMLzFK + WGtEZWw3S1p0dVlsY0JxNFB1VzRLaFFoQ0NNClRPbnZXRFJrOE1zT3BkaDhlSnBQ + eUx0QkdPcEtzNHpRUXl3ZmtycDM0K0UKLS0tIHZ0TVFZMno4dnJnbW1NSVhtTzhZ + dGQ5K2VHNU1HdlB2U1RQY09nSFBFbFEKrtTTDekvb6MFkzjX66kvrtpc2JG5OIGJ + 7SwXoSOzMpKIN/2IiJXDTdad3ITk/15WqhLvVUKC4FS1dNKZQfzsDQ== -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g + recipient: age1tgm3rcc2glqjxl5al2r780aweywv5tc2u065fzqlntwjzws4kckqepz7nl - enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYclN1TmdwLzFzbEcvWHY1 - bjVrUHBmZHNnYW5GRVVrRTdWNlFkRDZlZmpFCmpGNURRQlVzVWpYVVBabDJGK0ZF - eklnRTBvQnROc3hGNGxEanJMMzdmVTAKLS0tIHZ5QWo2dlExTmVHSXBzcTBZdVlK - cjlWYW54YnNJZGxmQkd1elhsaG02a2sKJa1pCamtbg/tt52jArNzlRxZO2RBdZNH - MNKTcPFtYn6me+8uZSfbod5dLawLyVxtRd+xCv2ne3Wmbb4auMMp/A== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqdTQzOElsUU9rTW00TjE2 + TzBPL1NKY0R4WjhtTGtlYnd5VWJMNHBKRFVVCmpUY3RRc1BzZGVBRHA2cXNpNUow + Y3o1ZWNpRGNCaFRBNEFVanhiRXVUT1kKLS0tIGNKYXVZU1R6UUdadmthR0gvM2Ez + ZU5GNzZiWXNIa0k5UGFEUUxaSnZEUTgKfiP0tRWp5FtfzeJapoY9Qf9VgGBAiAzj + qyMR9A3suQkHieD0QpC67j0X+0rglIeBtr3NAgDUGMuFn67Kf6Trig== -----END AGE ENCRYPTED FILE----- recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNT1RIazFxd1pwMCtMMlJn - NUVXbGo3cVNRbDlUUnFYRGl0Ny9BRUN5ZlhjCnM4ZUVuWkpnbmx4NFJXY3RxRng1 - cnlUeW9aNVFMbHZ4UTVvRUpQTC9QMkUKLS0tIEo4ZXpsdGZlR3ZIQzZ6ZFllVEJa - WU14MzByWXRkTTFnS2RtVnFKN1F4QlUKGfM/DyCSv7UwyTkgqGLheUoqBMY+3l1Q - knCl+606elWAx4U15G+zJN2l4RrpNCb2L6MuwKZ3gRwMxESGKHKm6w== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhR0Z1QlFYWVRlT0xhVGJ0 + Qk43cXRLbkxUZ01mZGU1cUk5ZHpXTktVM2tZCjFibnBrSXc2R2ZPSWZNMVhvQVBF + ZXpQeEZqZjd5QmVqMGpnaWFrS3VhVkEKLS0tIFpjRW0ydnJ3Z0RBZHlKcXpraXBx + TE5KUllDeFROZXFMY0k2ZzFGWXNXRG8Knh1bx2+qdHy0t05YTNulyeGij/DzRrsF + +lAuN/4kbw0tcXydJtpNtHVrsBjYw7UY9yOoACUG7eoW60DvDG4hrg== -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a + recipient: age1876lthmlfq2aq6nm6z2qyu0ed4aa5ss68xvnlw5cqxcdtzslaqrqzgcmlm - enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBycjB1c1FYUHd5bjZzZG0v - czZtRzhXL1BLays4UmxPamdVbHBqUnBQK3lrCnZvWVkzUW44VTNXYlJFTWVxL0lV - MzhVM0lHVVJTVTloYXF6OGlSU2RCc0kKLS0tIDJNVElTUnBOVkpMU1VHYWxRYXY4 - OWVvek1lVnBCM0JUcUVDVVlkQzV6TjQKZpDbgsux/KR3BKHWoJ4suoeKy2S9BEx/ - K/8qiEjWSzxdwe/sOw5XlxiVj+/rlLrL6ktqI9w08zdtdyeYrVFCog== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBObUxJMHQzaEZiblZZbXZ2 + YlhCSEo4WmE2UXRyMjlmaUtzdDhiUUZHcGhrCmV5R0svdHBiaE45YUthTUZPUVR3 + ZzdJVzMwdk5ZUEEzM1BjdnVhTGM3cTQKLS0tIGdnL3V1NWN0S2NkemxQNHo3TEJi + elByL2ltMm9rdTNTMlRBYTJMZWYwUFkKCt8usCQSKVdr/JL/q/CIQOpa4fMQdu05 + yvmiGz0ej0kCB2SrScMj78O3XcSpAnDp/tETUyXTVWO/WVMsp7VsNQ== -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf + recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyL1BkVTNaSFBoUEJLVWhQ - M2Y2RTRVQ0NDcDhMdDFSMGpEb24wZmhsZVFvCmE2TFMzMzFYWElIbTBueXdWZ0xJ - aXdicGl2VFVpUmxwQURUdEFCVG5nUFkKLS0tIFVLY1NwSlRDTVQ1V1pMYjE3Wm90 - VjdpZGhUY0c1Z1BUaGd6MnU3RW9zM3MKj7b5rvs4isBfdZGkQIZNrsPEtVM1Vr3L - rwrOrZmCbTOwje4OdYRJ1749dtUS+YYMJ2vRsgC6ETGloh50gIFaqQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQRjAxc1M5Tnhza1duOURn + Y2hGVDUyNzBHZENjc1dzcDB6aURRSmtGT0FZCkVPWlNVOTlUUnRoV1RzbVdET3c0 + ZmVOdWkrSnFyT2pLZUwrZExBOXpydjQKLS0tIDNUZzdzQnlwU2FiTUVtcklPbnFI + anp5RlNlU0NENTQycnVhdUZMazJMaTQKv1djCYRl/aDly9q+LJwD0qwLagiXonGi + 3yigyiWlXyvm39yvXG5Ib0tGWO0eNcNGfdjLyO8b2YytA4RFegzKzA== -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 + recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSTitqSGI2TFlDelhKSDJw - a3FOU01GMDlsOXloQko4dTduUHN4dVVrUmx3CmRLWW12ZTVELy9hKzc3ZGZXQjh0 - T1gvSS9ncmw2UGgzNDAzSmhla25rVFUKLS0tIDN0cW9jc2ZEMzFuOHFNK2RUQTJS - Z3ZrOUNwWUFnR1dvSjQ1ZXZUWStxcncKShJoN+r0IpIaa5uHD2iSnMr1yOzrs/Ki - qPF8000H6M6OLY1DWDem0wdKHCkbbwL4snwzzP6nIxE6aEmY84Emgw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTZjVVczBEQkRlTGhaaFVS + anQzdVM4M1J5TTVYTjgxR1Rqb3JFUVpGQlVJClJ5SnpTdk1lSUhDbytHWkFleHlX + T3dyUWRWNWo4UnVXZy9zOENOOW9aZ3cKLS0tIEN4STM5aFhlMTdlQWJiYTdTNnM2 + TkNlVEhSMHcvd0gvcjFMeDdCT3FJbk0Kw3xfmtU0OZ2R0WoE2oy4oeszV0zMVkdX + aPFSj116pWQ2TkafRlolqL+LL/bMh4ysO0X5TAisqNWVQbnCQErVxw== -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s + recipient: age1fczwtlqdqq7pjyzna2yl9nvmhpe68zk5k6nyn0dt4sp0lts04anskhcmu6 - enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvMDJqOXE1UU5DMk5VYzdk - Qk9QTXNjUEQyOXJxc0RTclV4bTZGaGdKMWxVClRLMFVpdkVRcThVS2t1S1JnekM1 - UlFrdGhpaHI0SjkwTEZLeTBTWFpmb00KLS0tIGpJaGJ2ZTlEVnNZU3pTNjBLV3Vl - Rnl1dWVkZm1aa2hDK1BoWmN6cXgwZnMKJOeMOakPgPFclGK9rIW2pWxr9IU8z9w9 - xTDCv2SmD1Frty+jdT5RR0gCfpAmCPkNBz58PuDOIGxGJAOwuRRbNw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1VGNVWHRldG5JZWZoVGpY + dE5TZ3l5OVMybDlNRVpPTnJ6YS9nbk5UTHdvCnlMNjIvbmREQzZGQWVjSkMrQzQ4 + dUhrc3lydmtjbGJaQXpObmhkbjJNcTgKLS0tIFpzK2RhWEdOakFyLzYrQWVaZUpN + ekJjUnErVGJBazMwWlhOMkkxN0lzZzQKDqVdZU61LTxO6pxLKbAaD1dVJ4lcDAhK + UF8yGfJSVVft2cGIE+VKX41cqINK+EAZuxjXU1x0RlL6/EpVfdbn6A== -----END AGE ENCRYPTED FILE----- recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzamRtanFWTGVJNHBpL0xj - T1R2SWEyUE9SdTh2Uk9mTGI0eEdJcWVmSjFNCkQyM09qVkVTNnpVRFVSbGV6SVhZ - dElhckZ2OGJJWW1Kcy90WUlCUjFMYWcKLS0tIDlvaGdWL1VoLzYvdjNnRTBkKzlY - MnJuN2RmSjQwOXZrVXRPazZ1V0YybjQK4L/jTeY54lsTpwjvd+Dpy/GXyCb7svg6 - 0VW38FLXh8Od5crFW1Ia3tQqzZ6ymrPr0Aw+lBYxgYOD/gEl9+Spyg== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGLzlFVisxRVV4MTc5Q28r - RUFqQk9oYnRrTVpCUFRiMlJoVnpTRHJvSVdNCk5iRW1LUlByVVN3QmZzekZJKzdQ - RytNRXYrN016Tlp5bUpVdnc2MlFSQ2sKLS0tIHJMcW9mVU5zOE5EL3k4UkErWnZi - VnNuVU1CWGhQV2YxbVRmMTNjNk03MnMKa091nCyphj8eTQmhRqAB5XX612wzOKW2 - YoD4ha8fkolYH4oj/EVj9gmz92zTRk7K6txP/xlLjxmbRUZXckldvg== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyNlJ3YmwzU2FEaEpYVlZs - cXVsVVhxdm5UcWJxZ3gxOHE1dHpnNFZmREM0Cjg5SGF6RDkyUEtia1VVWnJUZ3FV - VFRhQTFWbVpXcVhZdmQ2elU5b0Y4Tk0KLS0tIFNTaHZFV3IwaEJjOGlXWXYxOTZt - V2cxMHpBYTdXM2lnZEFLRjB4dk9PRVEK1bXkgYmZoqbkOprGUbVlCED140a3U42d - tDHcdZr7Y6YAaJ1tP4kv9chcBS0X+Cj+iC92EJJaJLxdrWlVtT/J3Q== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTRW5mMFJpWTMzcmVjOUhV - aStWUER0Z0xhQlVhY1RmY21DaDFvQXdVc0UwClBjdVIyUkpKZGFiZ0JRTVJjVnJL - aEdDTVhjY0VBZVhmcnV5UkxCVVJ3LzAKLS0tIHc1K2QwZDVqdnpIWTVUQ0JZVTRF - bGRpN2tIaWg1VUxIL0QvelRYd0lybFEKUpkzck1midvOj0RYv1inLkCdvuDGqUvN - dKU5v+rcHvU1cvrgG/HTmR4V+A2fU+U4ilaMghU5mfLo6HltnUyG6w== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx lastmodified: "2026-05-09T01:19:02Z" mac: ENC[AES256_GCM,data:RdTQ81HtF0tcy/DfVYYSZn+tOJCOA+GoHRom6mFgAM/NvTN6fF2QnVGq93YmJWdVTEZ1gr/Ww/PgZc30vXO/DFcrX0JGuXoQllQE21l/qVrjjWG9rddyz9nJxynPILwQf1gnxfxR0Ih5tYgIcqBSfp64aPlM1RJzuzF1YRfLWWk=,iv:dFQSKbRqS0zB7SCFV+ibz6sd1tzxv0y/1ENp8oyjODw=,tag:RV09z3PoyjjxvwifFDx94Q==,type:str] unencrypted_suffix: _unencrypted diff --git a/secrets/garage.yaml b/secrets/garage.yaml deleted file mode 100644 index 7d7a3413..00000000 --- a/secrets/garage.yaml +++ /dev/null @@ -1,109 +0,0 @@ -rpc_secret: ENC[AES256_GCM,data:5OUicnhbHFrpQJdrelD3dNgGkaopkTO+3x2yPSKoj+DEI4A5f7Q/yUtNuRrq8OyGruw27DI5HtLklJbAonDzug==,iv:ffn2XxgZ4WDYvjnbDXENO0KQSm9WbzEu0rj0ak0/y9w=,tag:FvgoW6NlCpmpdF6K/+DdsA==,type:str] -admin_token: ENC[AES256_GCM,data:ePlnEw49+Atx0T8oEfK3aYoPrQU117F0DelZ2Oj7z859fZIiBaGSCWdL5J8=,iv:uvNcnMx5rFhskJzyNwv8yyN9ZhY8IikUOQ4Ae6cpJ2s=,tag:BDGvs6YDjUFgyqu/ikSQLg==,type:str] -nextcloud_access_key: ENC[AES256_GCM,data:RXBIS+ejTuLFfc/SBNZXeujQSZI+E+jAVgMQDimGmTfnLg==,iv:/94nQib2H0VZbSutmI9mYA/rlmCKWv3Pz/wQEKAOM3k=,tag:WdL4Ia+Vmx2Ncj8OmqwWIQ==,type:str] -nextcloud_secret_key: ENC[AES256_GCM,data:4iLuuP72s84heoYYT4lBEwDUTzd2CI4bV2Z9QijzUteHlPHrFxZ5epu/MqQAiBououqb0uRyo2Heu0vZg/L2Vg==,iv:hDI0OSydxFOOgxQTaMe48Ft1tRWwcP+EcXdE2Hk0k1I=,tag:6WXVv4temKCtxSUulljn6w==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5UHFBQWN1VFp2bjYyNEpw - V0ZMeS85QkE3SW5IWTN4NUdkS2F2dnJKeFJzCmVWcVA2VDFsY1A0THhrbGxuMmU2 - NldPSUVTOFZ2Y3FHMFNHcHNlVFV5NUUKLS0tIGpMRE85SHNlYzJOQ2xUSjB0QTRL - SGd2dk1STnhJcUlPeE90RldFdzBNdHcKsRTyVHQ8wZtK8OpjN5qDvH64tWqSXHx5 - EEzRwuCMUfg+JrIq+htoaMWOlm1aqRYUGAkuNV0g1Mn5BEya5JyIKQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuYVkraGZiMEdhT2VZd25t - ZFBmWEdDUTk4a3JNR04zZzIydHgxdXpFbW5VCnpJaThrM0NKYWRZL2pBM2VzcEFJ - NzUvTEt5SmJPRnpFRVlTSFoyd3ViWGsKLS0tIE5ucjBMaVBPWG1UYldkNDM5S3kx - ZHFCS3JxclFydVVuK25lOEZYQitUc1kKZvCueM82gsr92ViC/cQZCRcFZ4bBEGgg - pBALDfo0EcAwc3LT8HQdWIvy8zuwXbYcztbd+zFI8ExX+VQ2K1/Sow== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZZm15VVR1TTIvb3pUVlpJ - WndFNzBjemVqcXR4UDBIQXpLU2NBZXhVdW4wCjV5UDJSSVl3SkxrNWJuYXVHUU9w - WnUwVXJ1T2hyNUYwUUJzdER5cDdhOTgKLS0tIEVMUzV0ZWo3VEFUTFgyZ1dsd0N2 - bko1UExjeTdJSzBWcVdBQ1JLZENRdUkKAC567arQMMUNZH3y2YS1HZp8XY6LnubM - 28Cti9aeRLtcC7USLWc4DxJY60BeXszw6CFU8v+kavmRgutHL9OxQg== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxNURsR253Y2dWOS9SZTE4 - T0QyZ3k1RC9LNjF1bCtWQldSb2ZBbWhNZFdNCjgrazdROWdaYXRnM3h2bndzSkx2 - V0FFQUpkeFphanBHV3FtcTdMRm1WUmsKLS0tIGl4b2ZPWjZzL2swQmE4TWRVTnZH - Q1V5Uk1WZzhZZnYwc2tnRkpLQVp5RWcKHCjIEcFq8Hgv+S6iQQNr1IfG70RNB+j7 - EpAbo6N6IcmY9n1LsvkJVtWk27DrXjIwZZ/C083jKsSLCdVnLqcm8w== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3UmhqN3VVUi9yZ3U0Unhr - bU10UVd6SzVmeS9qLzVMeXBwOXh3L21RSms4CnFvMjBQVmdBcWMwd0I0bUVzaFlD - dHFZM2d2aGw3NWxNR2FVWlFMbGd2TmcKLS0tIFBCT3FKR1VxdEdhVERoNi8xT1Ra - ZEZObWNuVlJibHFGbEJVRStDbmxQV3cKuv8t3Ei8brSwgFX5P3PPbDoTaIYMF7Vp - k8OqCDLrI2SmHt9YkkiX+IuYhjSyf5EihQVkdJX6w7pW2wFRgayQSA== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtQjBpUXBlUmtNR0tTWFhj - RlAxSzd5alNvSXdrbzF1VU50cy81KzRyY2pjCnlkYVpaZ0dNM1BYU1poNEpJK2Jj - Y21JclZxcDNGSzROMWliOVo0S0F1Wk0KLS0tIFUxcmxOVU5PU3ZkZG9lSDNnSk0r - TVlZMVh5Tk10UWZDNW50QVVCalRPelkKAIo7X1gUvvl1sc1Jyc6BA/CRLnbZXZKQ - jZGr4iR34IDNocDRi+xTgKFkncdnNl2uhXR2Fri6PeeHzH/MvX4Jgg== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZWEdydDdYUkFTK3k5V2pN - UjRWNS9FL0xINkxLb0huR1JNOXRCRHhRRGtnCjB1UkM5MDRUaFdUWTNjSHpqanZH - bkVJbFYxcUI2dVRtNHM4SmlpR2xSdEkKLS0tIElFVmhldGxHaFpEcytrRTVRNzRm - M1lZWSsySHhBOSsrdDBuYjRpZjFNYmsK6TDGsorp43KbRyQVLCSQpWRjzC/VReU4 - 1KoPc5n8C8XmbFK4i2H7hlecFVfCuFGbpYR4b1AWIS3pSAfH0lcnlA== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUeERjeU5jZm93N2hWVXFD - cXVUOWZlUHlucFdLQmJhWEMzSkltRWxkRm1vCk9QYUgveVNDRnJDdDdkbW5pY1dr - V3VXaTQwTHVvUCt5N3AvT2M1d2kxd2MKLS0tIHpVbE1jSW04dzJnUjdScXhreEdS - TUlNVDhoUkdkQnE0WXpJbzRLOTR6VW8Kys8KirH2T4oe/gTE56x02g3QyUmWtUoC - 6zrXfDJYdQ7WNPszV0ZX2Y0IqSHNLljQQPP9ryiJ2Gn2MfLeTZfiPg== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWb2h5RUtFL3JoS3cvOHdY - NC9vZkVZUXd2eFJ0TlNqdmVSMzVyaFhiYkN3Ck1Oam1GVTltU0RDL0hmVjFVS0lt - bXN5QzRoMGZCUHg5bW93Q290MHVvZHMKLS0tIExFVlNod2gvWHVxY1FYamxORElL - SFZJNGRTZXZwdHVrWWViQzYwM3JtUlkK+0Q36/0En1gB4iT4N0isE6qRJmH9oi9y - ADWejLQ9WklZYo57ZEK9JyKW1pRvLR6OVlqD14KElbMfMRuy7lgDog== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQYW9POWU1aGxsWVpjbENK - NXpEUmdjNWRGWlIrc2JEVGJJTjlYOG5aa3gwClVsbCtSOWNRV1EyRW5PUzNRVnFY - a3dtd2pwOEdlSEkwckI0UjYvK1BQWWcKLS0tIHg1TExadGswaloyOW5CdVhzaWFZ - ZW16WEFNQlkrTy9adnJUcS9mMzlxRDgKyV9IMLe9q8sBEfe7iqJ1AyMcaOKdAVdN - 1+kzCWvehF1wW2SF7Vt7YDMVXTl1h1dAj4v5ub1RvCqafCu/Pz57UA== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4cUVUdlJEQUNCRHhxekY1 - UXl4dmdJc2ZQQ2prcHVheks0NnhPaitzc1JjCm9ZUkRqNVIrVi9CYmgwMjBEeGxO - NzlYdjVaVnhoVGZIS1hFWTlObWhxTk0KLS0tIC9oUkFmcGh0K2xOeDdwaUs2VkNy - V3Brd1BKRWRudnpnMWhSZ1pvMFc5MFkKNoNbVP3zwpa0ULeWy5z/NiWsOBtNlhv1 - aTZ79Wxkie93LhygUlAcxvwRiKlMVRvGJwqkT1qNaYKKkrtZiQpkXg== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - lastmodified: "2026-08-04T17:13:36Z" - mac: ENC[AES256_GCM,data:z3ZtfFhtBQ+YHFMR5DjqVld4H3wgRb559S3rMHcoQZQvAkhBTTrXeeS3uuP5p487MJEp0svJpBiFnJY99ak1BA+3CcqOwSQHNRuVtPZYrh+S4bqafx1r+b7WhVI0RWzaRRxonEeXGESPvw2eyA5vhZ01YOnX14LiiTbZkDaQhnE=,iv:4ok699iBB0WdJAI1AjiJwFfA8NjGv6P9puce+H1XTig=,tag:nAy1bgJpCUD9AJBycbYtoA==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.3 diff --git a/secrets/hetzner.yaml b/secrets/hetzner.yaml deleted file mode 100644 index f071671a..00000000 --- a/secrets/hetzner.yaml +++ /dev/null @@ -1,106 +0,0 @@ -api_token: ENC[AES256_GCM,data:IsmZ/RpiZPrO8ukP3I+IwSMEdyxn7JULdhE0daXm5VhVjDXS3/Kpg9qMTX5vMPUvobg4cgYWvovE2PmMngs2aw==,iv:pkCJE12mtWOdze+LiHW0e/Uzn4A4/B/6kATUecqpPGs=,tag:lJ820VQJxIQCcJLQrmL8Eg==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZdXE2TXJjeTF4Nk0vSFpu - dytwZ2FHaTMyckpqNERSSEY4NFRLRW0rK2pVCmM5MWNKN3NyZWU4SGlxNnRIMGkw - ckJuNkJ1VlV5eUJtYWdLMUZWcTRhMGMKLS0tIDZyM1R4ZksrTE9QdFBUa3hETlNa - cEw0dWJIaWFKZy9sbDNuUnhJemk2MW8Kn8ts7Dp3k8wHpjcbRL3CXdfJUokzFxDA - 7IV9goyUPVB/bMdTAR5t6W97kO//6Aihtk9CgWAt+2eR59WB7rK0og== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBydWVSTUoxK21XRDFYTWRl - dXByOGtEZTFoVnJXbGxsUldOcmhKa09hQ3dJCldLK1ZCbSs2cXZVWU9rajh6Q1A2 - YXFndGVzT3FpOFRaR3hjRVZ2QmFMMEUKLS0tIDNVN1ZKcDc1YU94Qm5wZ0xac0Vh - V05MK2ljYlBoSE0wbmlqZFNiY3lBQXcK5Te8SojrVNiL6WKeqpWJixDEzudLhZLY - TMguhA4tnETXhrIrqCdTPfBH3Vg1RqwPUAeCRrnhkpOouVrI/sVDdg== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIOVowODR0RGJEMkVaTHZI - bzZtdkdNWEdZVkZEZ296MHg4TlE3QXpBVVNZCnhBODJSZDM1VnFETzVXTU0vZHh5 - UW1mMjhYYkJIWTFnaFlhRmxRZE1wVEUKLS0tIEJZRUhMeE42Sjhxa2w2S2wyUTlu - UEdSMzRuUVMzWDNrc0xFSUF1MUJJbFkK7+mcqBdkIzXT8QudhGMSRI7acpWa46DN - W1cWXufLrz194kIy46SBsqaL6jofQw+bEi4GnupnP9aCslHoTIwb1w== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2dkJiaUZ2aU92eURZS1BL - TUdQUDFmdWt3TTNxMVZUSUxjOUpUTEJVOUg4Ck5GQmttWUxKbU5OSUNaNHNDVFJK - d0h2QWFjSnpFd3hpT3lBWXJmVXFxS0kKLS0tIGJGeGYyb2dOd1JtNXU2czRSZU8r - b2hYTGg1V3loQisybEdQdjdUeG9iTUEKS3Az0OjAjlnRyilk+YRB+UnHgebzNilx - pFZcumYo9T9LyTKz04nk4uNcBpw5VZPhzeDMZcwy3/dLw/1BKUkbaw== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrcDc2aGhHUEgxTWIwR1ZZ - d2VQZGFOc0hkSCtuQUd6bCtFN0d5MWNnSzJrCm81RXlsYVhVazYvOU1PNTBiVHZS - ME9lQTkwYThLeGtrZ2JxUHZ4enJPbkUKLS0tIEhjaFdVZnhGS3FkUjA3OGlKYVVE - ZXNGMzN4QWgyQi9KYTFTaE5VNStwQVUKJrn3vwX0rjcDURdzTywLyBBaLrutiXcl - 5xyQkzP3hQ9dJR7B9l2bTcLXTbOe48kXnO4O2SuSkKBX5NOeRXLytA== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhM1pLSXRNWkJJWkQ2SDN4 - cmxwVmQyNW9Gd0VPSlhJZG1QL2R4bHRaMFZnCkVsbGttR0VNWjJ3aFlPc2JVcWp3 - UjlVSFliMVR1VFpRK2llUVQ2aUhzSmsKLS0tIG1USlI2K0VRMmFWelZ2bDc5eWRj - bmdueDlhT0lBeGk5dnJJNzk0enptYzQKDaW5yFPTOnCnIDJmU0MF2bEjJtd2AOP5 - 0bLNthY/A28uottDR2JQYHaH6kNr6Uz3vokLcDXDocooZwU8Z9j7EA== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWV3ZVMmZxQy9WSjJST0Nu - UFZTbWNjRVlZb2p1SHJEaDB5OHFRUnBnblNJCjZKUlpVV0FtWGpCKzY1OWVxUmlk - TDZzeVlNcEN0UzdZem5zM2V6MHhUSDgKLS0tIHRFTmFOM3hpdHpkcXErejFuTDl6 - aUhuSHVGWENjdThUYXZMZzFuQ2RnZ0kKtx7a+a/BpLyuQ64gXXlEEONdGq4MqyPA - i9WsmavaFqoble3796kCHblYBvoHOOE+Ce1T0RErIz/rlGrvRdbU+A== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOM3pWTjlTZTlTM0NCa0Fl - a1lpOEMxOTk3WnhLdDNHOFVTYW1xK2p5NVNRCitDaU12ckc4RnJ5WUR5ZUJTRDl0 - VTBFZWxyUmY5TVM1TExLRU9lSUwyaU0KLS0tIFBJNVBHN1ZJOHFBd01MNmxFbE5B - bWVtdHUvY1hXUmEwUm5CajBBdTJCaG8KKhk6S8ZXc2IMWrc9zjpYV1Mb76TjXCnK - /1xqK52GlOqcgRSBtvpkLJFwYBKhxbyUrGkVmNwz6WKQpVH3L4XhYw== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTVWlHQ2Y1VVpkTG8wQlEw - Zkt5bDhpeXR2R3J6TC9Cb1lRKzhYMkQxNWlvCmRTbkFIQzQ1N0J2TDh6Q0Qzd2V4 - d1lEbEt0TGdlTEZOditZckdsOG5rdjQKLS0tIGxoUFhxWFRwRmNFb2kvNHQzK3FS - RFJRSnQzZUhiRmI1TmZQakxTcVJ3Uk0KssuGgRRACfpDd0NzEfOxHk6Da2/wwgWm - TGPzUmeL8JHp7SwOzTmEuMNOLTWegVtnYY5T1P6ujkOQ1beqRTsPFQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuNmI0ckg4NEhQRHpQOHR5 - UnJpeFkrZHMycDFGVXpTaWdFeXhuSWw0M1JjClQ5Lzlublk4cURDN0RSaWYzdjEr - UDdtZ1oyZUpPVEl6S0ovRCtjUzBlYkEKLS0tIGdqckNPWTNaK0FFYzg5MU1ua0JI - bWg2RUtQeXI5SUp0Mm5lWGkzdmplcFUKSJy7ZZ1sWnQdIPZKQC5RwpmxCiwA/3CO - /tfIJHoaK2gmsYvaY+Yp9b622ARF1eMBtQRuxftZTFGhyGSf96ZomQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXK1Q4dDFOb0VSZmFGbjhr - SWhBNVZLYW4wQ29YTDkxZXY4dmVIZU5PZHk4Cm1ON1pMekxkOVordG1IWEtqTld0 - bnArKzErbEVobnFmdGI4V3lZNWY3a2MKLS0tIEMrT2NGUjVDZ0txb0JmQnRhWmJX - VkxYYmFpL0YydE9NM0tWSHMvZmRPcDAKSTr5Sl/g/Fd2gWgADZXuK3V4se3XKfwp - IQuEtaOceAmLCX95yXsUpd3VVvWYvzfzKJWua7HkUunHdvT72zB4Xw== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - lastmodified: "2026-05-11T16:16:15Z" - mac: ENC[AES256_GCM,data:jYA2FNlbtfb9MGUkW3cnN/Vs1/fRXMjSPYOh3gtkTlpknLmJAyEe18ZJ/A3uE5Xka9KA+Tocppu9q2UI6z8Bp44+GfyR7CVBgQvV4Q+i3QyZVVAVLf0cn34x0Z49QnRMDeCo6s2eJyQnMZIZRhC7457tHd8y74Z2DbnDgIMtXmQ=,iv:L1lxOf/clvPNZhvCRJdUzwQ0sbGskxBwA9MbUwjBkzY=,tag:Pugr28aIB9yULGZPj8Hymw==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.0 diff --git a/secrets/k3s.yaml b/secrets/k3s.yaml deleted file mode 100644 index 7aa0dd11..00000000 --- a/secrets/k3s.yaml +++ /dev/null @@ -1,106 +0,0 @@ -TOKEN: ENC[AES256_GCM,data:BRo/znFkbXHz8dN4GzUoyTwcBcoOjSlw0M+Ywm2XMjCqDaJuYXpJJzW0z1awv0v1HB+7xFzGUJ6AoPLDwDRHXY9iuDpW2KvxK7Jv6iPHyCT/EWbE876aGg1dhAqTRAArqGSl1G9GnoSecLw+,iv:uFFJSKTNXQfh8OKmK+6PJJlfTN66xzvxTSe0mmRD53E=,tag:/xIs8Q9tD5W6m3lK7YXSiQ==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6ZGtZc01oQThRci9zZ2Yy - NTVrYmdJVjVwTjNDbDhJNFhUWlBzLzFzK0FZClZPVUZ4WjVwb1FudEMyaE15dmVz - SnVMSEdmQm96Y0ZnVTl5RFNVVmRhL1EKLS0tIGQvcFByMkJRYmI1MzRLRmpYSGd5 - b01YK1IrNnBscDdzOG95ckhORWNtUDAKjPlzoW7Qd7RXRH0gLe3pyWDviUwx5Jxn - 7TU/uXXGvES3CmthtiJo8rAXRJpE73AJLKoVhhi8dVhCyoNEVYt4LA== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2YU9jNm44MVhBVEcrcmR0 - RmNaYi9NQ2pQTW9nUmorRy83czllaE9sK1RrCkJBNVVEZFI1bW1sNTFNSWxKVC80 - emovQmpxNnR4Mnk5bUt4dSt5dlMzUEEKLS0tIGlZK2J6QVJLZnZBclRGa21Benc1 - MUs3SjhYelQ5d2QyU0x1ZVVXbGIwajAKRO48ZkJZllzf5Sy4n9lIskFsDRuP/ffk - X/HwsyKyi+jVDELXT93is7dyn2KfnqYQuR53nvQ3CRag+yECjZVzaA== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjaEt3SFk4ZE1WenkxQllS - UEloN0lvc2JBcExESmxQdEFBbzBhKzF2ZVhvCnRRbzloWmM5bGd3Q1I2Z3ZBS3ZV - RHpta0V3S29RMjJpUlIyeERmUnkzNzQKLS0tIGpiTFcxZ21scFExUUc1T29vNlJz - TUphTDBkdmNqTmJlMDZwRThaZ2VNcWsKGb8heLK4H3P3RbFqDXXkyh8aY0yU+2dy - HA+h0yrV6ye47f8bvoa0YWoSG6xBK4NbevSeWGAWTmKMb+TfePK2zQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTSEFkTjFpV0d2K1AxLzhR - STJtcFVWT0VCcWRlLzd3OHEzb2drL2ZKbEFRCmlEejc5cmcvSFFnTVdhZEYzT0k3 - aENrMFNIUm5tdDBqSCtwRm5Gb1V0MFEKLS0tICtmdHhPbjErQWZsdzJ2S1ZwUXd4 - dW1CbVRFamdLZHFpdzV0Zmg0eHEwMDAKSNLPHXWM1sbvTDoBM6SnSwXaEW8cr2wV - HSwDkzdb8V03q3waKfcLxr9WG6dA2mrrkin/SS0fUBbyXkzkAZqFWA== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2SE9QRXhkTlc2QzBSZ296 - bjFzYzNlM1Z1WmFSZ3NleFM5WjM2TWtuL1FrCkw1ZW92SDljWVhNSTZFakZCYmpV - WFIvMGNGbENUbUdBZStXcU0xbGdQZGMKLS0tIHV2ZVNTNUxucWwrUGFPaTU3N3Ns - UkU5Ulk0TWVPM0ZhL241NEhKbG1aTjQKrDsCTO/1tDrcDgwhSSYd1NPfoCe1bKeA - LbhvzWoHVPzWK0D1Yh6KK24u7EC72jmFst5colgKKLAlNXPS46nyOA== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2WWVPZ1RVUDNoUUx3b2x3 - dDI0a3lselVHWk9aclcydzgzWDVJYVkwcnpNCjU2bElTbFdlL2QyOUFMWStCcnUz - Z1VsbnlQVTFZdVh2V3ZHOFB5OW9ScVUKLS0tIDE4R1Q5MzRCRVBwcnVzM0lPaTl5 - VkxrNXdiYjMveGVlalBFaE5HRGVwTUUKZlEYVyQd5vkmV5eSsMglqXkM0k4Q1+QT - 0pWfQRtHZAnlc6+2smRt39fszaVApn5B5rim9qkrMkBTRmLh1VmyzA== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvMVdrYTZ4VXpISVh1QU1Y - VjJTekRITTl5VTdiN2JyM3hScjgwcHRUdWl3CkNZOEoySGs4QnNsRnN0Yy9NTzRk - TlBsM0tyc0gzRGVPYlpndGQyYUJseTQKLS0tIGMyUmRxZlR1MWFBc0JUejF3Vkp5 - U0JVeWQvL0Ywc2l5angreTR0YS9YM1kK+SmuBssymwwJg8tjAeq7LJKyMIvK3qhD - Ev1CDWc91J581Nl71963peaG5NAYnmWtUy883PuCYmBMtZFss7V2Jg== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOTlNKb284Qk5tc1I2VWNv - VUc4c25sM0VWV3FRMkRFMEsrM1FtRGJXVFU0Cm1rSnFWYTU3UzFxbkFCUVNPWTJm - M05DaFdERGkvdVQ5VkJMTTV5czdIcHcKLS0tIFpkTkdKaC9QekpsM0xtKzErRG5s - MHNGdGs5QlJyaUR1djViU3VYYU5xSTgKZInmr5OmRaeAuK4vCCJztVQDGCE96ie+ - 18VP9yOO35W+/0xXKtTj/zbOO/bdeTNGc3XAXeH2b5k0cN5vcyxhSA== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA1ZnkxcCs4UzFubHhPa2N6 - ZForc0F2WkR0bWlYcTh4UzdMUnJPMzFHK3pvCnZEWWRiVVZodzlvVXF6TWFJSU4w - T3FoVUtSL0V5blJ6K1h1cEd3dGtDNUUKLS0tIHUzQUQ1SjZnWFpKS3g1SEZsa2JX - ZHhkQlhGMVJQaml4bCt6UTk2c2dPc3cKuN7mnrOfOoncEM7bYzDSklsmezuh5c0+ - jCf/XNfwoCIms3w4E6wQtNFd/+gaTktwzFNG8H/7xJQIPyBcqAvOqA== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAraG1oYmtmbnV6ZFF1a2lS - VGM4Y3MrRVN6ZG9pM2cxc2hxUG5ia2dYVEVBCnljT1J5SUZoeVA5WG82SFMxWXBp - c2cvUFNvNG5DNmk4YW1JSVA3cFJLNW8KLS0tIFhwbktaQjNEM0QrWGVFSWh3eDlx - MXlaNWNFZzA4bDBVK2lLZHZESUl0bk0Kvla5ARYLJsLdSDOyuplvwYA/8Gw1v+4j - hB1lWJwFIb/voG8zG6X8uM4ue4o0c1a9COahEavr7SUnPVgRvchfLQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUSlNodlhnNUZ4UXRmL1FV - bk9ITk1wNjVPNWpCeGl1WnNFSXFvVWFHNGhVCk8wS2YwTUw1ZUZlRDdnUks2VGJr - bmFvZzVNR3pvNEZVL2NGVE9mODIxQTAKLS0tIFdBeVZ0ZEZjNUtWOVJBMXh0M0lV - cEdaMnFvdi8zRDVRZ01zRnNmNkhCSWcKK3HFjCfxWVUvARpWvg4q9q9YHLrUL5Cc - PmjWZUZJ7PGACLTRTs+T9wg9upEFQ4SMnKprXaqfM44/2gaoAVfEig== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - lastmodified: "2026-05-09T01:18:09Z" - mac: ENC[AES256_GCM,data:MDD0CAr+qy9z9l3xlYN7Syo0Y5WC/DqimrDKM7WGF6iHUZZFK2hwxSDUkk8qL4QCIAALUKhSccuHLaIzqbUSiTEJu1u2GU/dhHRzdcfGB90ll8cHdaSt6KasygfNWRRQe+ApVBG8vRtqdUpv3FZVwUy11eosT3cLqI47sAJTZO0=,iv:RT4zSTXYSuoe+sD2w7BbUhkLyNF10PjBWkI9jCQyGto=,tag:dmztZoOGPvMZGm360nLmxw==,type:str] - unencrypted_suffix: _unencrypted - version: 3.12.2 diff --git a/secrets/paperless.yaml b/secrets/paperless.yaml deleted file mode 100644 index 6838b3b5..00000000 --- a/secrets/paperless.yaml +++ /dev/null @@ -1,109 +0,0 @@ -PAPERLESS_ADMIN_PASSWORD: ENC[AES256_GCM,data:FR+odx0NQTmWBJ6keGejesLFCCHS/LNBFunrJktrPpc0A1xmrEQx2ZWnHBE=,iv:drhK2yFw4at5mszzJ20O3J75GcFdGqBbFbXKhgRkuVs=,tag:q6GeutWsFtHxrc/Z25/TVw==,type:str] -PAPERLESS_DBPASS: ENC[AES256_GCM,data:/fGrjDXAKypvsBfvMc2C5oYjCEDdXvufDmC8OJyExSEFOnhSE3Xp2dvUhwTsnvcCOc9LLKZUYUjqwf5H2DMqaCHTVwOOImdp1V02c8VuX43E+7PWlPehgg==,iv:uj+6Y4KidZK+A1NWRSveZ6epuHrnMHAMDvCzWo03EjQ=,tag:36q6CyfkrrXaHxi8E2zWUw==,type:str] -PAPERLESS_SECRET_KEY: ENC[AES256_GCM,data:YLKhA5sfLLPzvKTk9SUG4azS91KitX1ru3wBfZyAJRnEdAQTgW70xxNb0B9CE5SdRq9ogSH3EMLssG94MRHjs59sLJfR5NbXZkw3K/LDuUR0gsx8rIvtzg==,iv:R60QxwqkjkCOWbC8yhBlIUdnCn0rqRRdJQor6Cpc/N0=,tag:IS0lUFucYVTXEjZAhy96ZA==,type:str] -PAPERLESS_SOCIALACCOUNT_PROVIDERS: ENC[AES256_GCM,data:47I8nB6Gr6OHTbqp4pCLYGrnsDQXhSsj3hFtQ9f1muOirUo1McxK0kZO9REjYoj1NtZ2FDnUX7fOWtL/RXj7Usq2gq3StbnP7ZfHpKVnGttft62ho+iNxomazTavQXpxZCNt8L5GGb4h1sYQtH9i9c0Wf9UgVlTP/mVJoYVOZKl/uLGuDrHGRuIliVcLViSiFkaEnKPTQXV1aOaEZQZDMGhOMe+f1d7iXorDxTjv8DwchIcRVHMVNWB2lEDytPAdmc+SQ/Oj0xlTqJhwI0W/rSWEm+oe1yA4hfKy3Mn1EidA3hzak3sTrXcdJnvov2Y6Fijzk+onhnVHsFpgOTGhyi9w5/PRJMeqOIwM54ejcbUH9pmnDQebsYSGnhRDuw7Wotttz0E=,iv:6lEyvX/IhJTDI9ACl5LxZg9Fg25P/aWlNV8aYknHJa4=,tag:VRmxWz/x3fCsWiwb7NRQQg==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2RHBVZElBUU4ra2I5YzZZ - TGhiZ2djUXVwbWpZTUFzWmZEVGVhWmx4Ukh3CnY5dC9Jd0FBQUNEUlZjamdCZTls - Unh4a3prNWI1cHZNMGhIaVB2dnhQMVkKLS0tIDZZaHhGakt2UnhEU3c2VlRMLzVM - OEt3cHM0SGY4OE1GamloTmFjdStNdGcKKnF4l39u/TQWfyzTVATGTX5zq3nTfPjB - RdvbDEY1bJZH2EFYL5T5LCAthJ8jVLPkhofaNrTA/E53DLscY2gEBA== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzbHREZGFuMWQ4L0I0U2tv - N0pQYjMwRkFpTHRtc3Q0QlFvZXpDeDJKTVVrCkxGakxCRTE1UVhWYnRNTlVkK3d1 - OC81KzhuZEhlSzNtRDgvVHdGTWVIZ3cKLS0tIHVpMEFBdzU1RG96RUJsSnJmM2k2 - SEFJaVJnc1huN1VzMjUxWSs5cmpOZncK1wx8LvypfKNWFaL441erHJl5xNMfvaB0 - q4ge4qiw7ND9ibaknYMmGVA10BO+H+1RbwlHREW/JQ5x4ZOnAZjgug== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzemc2MDh5d2h0VVRpUHBr - eC9EdGduck5BZjYvZTZTS21PR3h1ZGJwYWhNCnQ2ZHJQOWhNemkwUmNKckx1eXhr - dE4rOEhmSW1wVVBQai84b0pUcU0rMTQKLS0tIEd6UUlkMmdjWHNSSjNCblppbk5v - VTk2M2Zia3dVZ0NPaWx1OFJ0cDl2TjgKWc4DtGhgguohlnCXn5Y2SPc1kKbXogZL - CCZe9tHWRcmbqSaafGKRyOBbdGTDApanFFJD876WFi5B7DIw7YoVQA== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0STcrM0hneTRyekR0dUZN - U0xMOE5rOGtPcWZTVFlLd0c4aGFTRkpuRlY0CkNKZ0pESjY5YmY1cEVZVm8zeTdh - RnlVaUV6SE5iVUtDd1lsNVZ2VmVqSTgKLS0tIFVQV0FZQUhaNEhXVVFXRXVuS09x - K1BvUk9sQ2hLc1REajBPaUowOHlGaEEKDI00E7M5j8R9U60fR3zvucHv8jfLm/tH - Yc0KKlfRDrzJ8qqhcuD5BnIBp3SVvH6UdaVS/uZhgk2PKJS16pm7Dw== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA4aU9DeFVRRGl4TlFPMWtS - eHd6dHByTlI2QmMrM1BaYnNSY3k0K05Lb25NClJ5UUdpQ1NWQktkeWVMbkFPRXhX - RDNmY2UwbXBPOWZ0ZlhQNy9XMjFad0kKLS0tIHdpbDg0UDM5bVJQK2YrN3ZsQ21k - T2hXVWNwSDlZL2tQTVpVcHFNNGhPeUEKXRwCQpgwVOTyL7bg71FdwzbUh2sQSdMw - auyLJGrwuyy5SJCBr4NgiHj8XnbLKVTu7DoFVEXViSINe+MhZ3GgNw== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvSEd4UHU3MHRFNVVEY1FF - YzJuUE9zblEwb0tuVnViOTdaU3JRNDhrb0JzCnFZeC81UGl0cWx1Q05jdFl5UW1j - NGYreVR6SjRTbzNjd3ZkQ2JUMDhJS0kKLS0tIGFmY2o0KzFkZXRicytXQVNZTXN0 - N0FJeGFVd3IwSE5UYVpWbzF3RWRCc0EKvv0ihsPykIGGGflvjlPbZ/37C5p2XGSR - U4aW5ew72bf4lRx3qwXhtgG4tUBOzal53MWqCUcHO2ZwMRmjRbmSlA== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJaHpERmdUQkk3enZXOHYv - WlU1MkF4TkJEMHRXQm1pZkRadURZNGZPcmc4Cit4QmlTRHh3cDdRekYxSGNKQldR - bjJwZEVYYVc4MVpGNCtDQUNLd2ZGSTAKLS0tIFFlMlhQUHpoNmo5TFJBSGw5T1dG - akFDb0hjb091ZEtyeHhnVTZxb01HZHMKQHGVCmib46hrrqbAXrjhwHcB69Bfyy9W - lKEoHXWT5/F6Lbghusez1/VsWBs8DQHUCQtC/0tkjA5D76BAn4j1cA== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0QWpJNFk3c1Btb2RlMXI0 - ay9LbkFzR3F5bjJGRS9OQStZUC9HblRCUkNJCm1PY2htUk9SN0x1ajJSc1YrdzQ1 - V3M3Q216RnhaazdPV0hTM2xTS1ZCZEUKLS0tIGVmWE1qK0VuKzRRTThpUkt1UEIx - N0hBWktTNkk0ZzlhSTlMYzVaV2tJVG8Kvre1djJ2TZ3Lj4awH1DWzs6YMW8wxPqd - +5q+LBk2+49GkRwyKhzs1emfTkOurHyz1T0NSJenK93Oeo9w+C17Fg== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzME00YjcxWXZrVlNsOVlW - cS9aYXF2MnZWN2hIclVCOWRpTy8wYnZYRkg4CktQYWVnUERZYWV0ajdsaGRqK2Yw - MUdERk5rTEtYYVpjL1VvSklNQ3dmS28KLS0tIDRkMWdUUmdZbU1QWEFWbTY5dFZI - QkZ0WENFSTM3WEd6NnY0YUM4M29NelEKrXD3Nm2HK92eK1bWqVzP48caOa9knHKm - pbNnQTlDyOBjk1XLrWUQ/57nZG1WXNQx2Szl9gYjbq6B1Xnma6NH8w== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJczQzc1ZNOWhtUlBuRysz - WnpIWlJiY1lESmVGWjFYamNkWmdVWTJPT3lVCmM5UVRGb3h6ZmJ1eHJpTTJBdFk2 - bHRBRGNTMyswS3ZZMFY5SFpJSG55aE0KLS0tIHVrcFlxREc0MUNWMkVGb1licW9Z - c093cEkrRFAxR0JTM1dYK1drMzhTVlkKsqNB2WWcVB5qL0Fk8Aq/S/VJakIfs8aH - 6wPOdX6g+T0Z4mhyrUBDsP5A3mxfnUAq0nO3Q8W2ftUFwa0oyG0DYA== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOcGtHa3ZUK0UxTEtPWGZ3 - SW41UU0vUkxOUHc3MkFYWUxZc2JiazVrQWdRClN1SzkyOWpscjhxSTNpQUJTYm13 - SUFVbmUydkpoR2htNnN3T3FHSlNIYVkKLS0tIHl5aUUyY1FLbjZ1TzNTUUNpTG10 - RFBDZUlaV1o0ZlhZNWJTc1Q2cHgwdmcKY7bfns9yvwmP9xlWhPocrizfW457XH9U - knl2F9UtTLU0IYEOyWv1OV5FbDbHvzYmK86mpFMRv2bWISWCi/WXNA== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - lastmodified: "2026-08-18T00:59:34Z" - mac: ENC[AES256_GCM,data:mq93xFr6pOxn5BUixOxqnqjtmckiZ2G7x52nh5vLtGVmIhdkNyHj7IZFZvSVB2t5puuJSfwE3FSxCzCHzJMyGyTVQnIArVBtxc6peOeGDwXDw8V8EUZqd4QRlDS42xAzh5XDQqOeMPGOX44IhalybQZ5rA2nUKF60isjCQj4AVE=,iv:1ElRVjgxSlrc2NYoJ1uuUUjx7jJBcZ21twvEfx2p4n4=,tag:9kvvoty9jvPYGaMX7UefAg==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.3 diff --git a/secrets/photoprism.yaml b/secrets/photoprism.yaml deleted file mode 100644 index d688ad24..00000000 --- a/secrets/photoprism.yaml +++ /dev/null @@ -1,106 +0,0 @@ -ADMIN_PASSWORD: ENC[AES256_GCM,data:Nv5H6m2X/OjGUf9SiP0=,iv:BGNRycqyZySOLqHIBHh2i66oE2aqnz9acsKqBCTOT6k=,tag:VqldO92KNKtQjQOpwSHurA==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2bnhyTTExRFVNbUZ6dEJz - aFBxMExUS3YxbDZaM0RxS2w2VlFRU09pVzNNCjZheFlaV3loY2ZDdlBCMWlVSy9m - R1Jod3FyNmJPMVRuTzZZR1pmc1JEYlUKLS0tIEo3c1ZUdzd6RW9kVW1kQVdaVlBn - cms2bEY1SUJ3TEpEUFVlTHRrZmllcFUKF2PRj11fnElhHnG+1NH4guAfN8yh55mP - cjqUOVwcjFY1vNbLRHg42gMXxfAJfL7MSeVZ0QEjxsI3smWH/7Z9Rg== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpdmtzZzNkSUp2MlRyaHE0 - VUpKeWwzMXhNbHJrY283SUVGU3JwS3RDd2cwCktKeGxvSExNM3NSUEh1SWpRMVcz - dHkvSk5ZOVp2K1VvSnZqOE9SV2E0UXMKLS0tIGxpdE9KZnFDTmR4Ti9XazJjQUs2 - bHZNcEplR05QSnowNDVnd3FvTERSZXMKIWtBY9IsBDd9hHXxiZMKZ3p3Sc7fifdP - 7IxE4cHiAkyxCWVBNLo+jyT+nnH1MI22dLxFVen5v0XjpOuvcV4mTQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0emFsNGFMR0oxMXVnbHdV - anJ4b09jU0Rmc0lRaGlsQzYxdkx1SWt5b0g4CktIZnEyd2JqUW1rME1DRUtaYXhB - bWdQRVozNlFqenZwenA0NkloRXdOTkEKLS0tIGFXdUlwbVk5WWFBTHpKR0lHT1I1 - THptVkFiZGR4SnBBdUYxejYwYnF3YlUK8VufSkaEXAUwnwx/XOjMiQHJkfUfdm4U - t/FvS0ZAwL82f/0d12LZaFSFT35mWaK2nRcCUndmpC15fcH8+sNpXg== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFMVV4RmY0YW1acVNZNEtw - QlE1U3dkSzMzd1ZLOE4rYnc2UllONWZIM1hZCmwrTHlzL1JmdythQ2tuTWIxQkxX - MVF4MWdhczYyMlRhRDFpdnNVNENDd0EKLS0tIE9YYXBHMElMQUxwWXVuRTZLc3lt - d0JTdHRQVVJWbVM1SmkxY281SFQ1YVUKtXIsPySLFeHNbEFPA3mMDvM7RW2CUYnN - vPjH+/IOm5o+CbGnbj2vU/mYudzER0quvTEJqAh5wzv/oNdXjmNLzw== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBodG1JZ2ExZFpWWXZKWUFS - eTNWZkFhbEhPankrVDNLSHhQa3djOWpqUnd3CmVrTG8wUFRkZnVqSzBzbW5kcms2 - Rm9mVk9zblN1Vm45UEdIbnlMU1V2WnMKLS0tICtXM3BJUU9rUHFDOC9Ed3FYUmNn - RlZUdDJvMEdqb3NzY0YwbXBKSk04NDgKX1PCVxZlo3MnWCxwX89d8m8O73aJyHEk - NCLDiLC64alrt8ogqqDFDiG3VdIX4qiilEYFzNGcyyYm17LmUadsqQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEbkRmVHJVYlg5VTcvRnNk - ejU1U0lEaXRNWFlxSk00ZjVOZENVaFk2VW5FCnpWR3hIMWdySVVLK0syUGZiNURw - WDl6NElBTGJieXBxTVlnT2VmMHlYaVkKLS0tIFJodXV4WUNGY0ZMSWUxeTZPQll0 - V29QcDJjcWNFWmdjaGtDdTVZa3NWQ00KxzDVnulLDk8mf3Jn8UaEMzcwtashwTn/ - eVs50PWYRUBcmLyyqhyAEEp2iPvOc7Y68b1reY08lCh1rtiE62oMKw== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwY0VWc0FNYkdVM0dFTHdJ - ZUExY2hLM2JHNWtINVJub3NtM0FFZk41VW1RCkpUUGtUTzlnNURYZTQ0MlVIby9p - NjdTdEFrSENyR1pKWHVyN0QzcWgyMVEKLS0tICtqQnIyQS9MOFVJK25BcFd4WEJQ - aE51VzFyZkRyN29WTWpRNnlFb3VxTXcKIeMFhNu6z5VcP1BwzCWXPujgiaD82tFL - fF+M9UjMFgAoVoSI8FIMSrDfTuwaAj5/Rp1U6/Cq5x4RVDb3X7ehMA== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjNXUvYzV2YTkxbmJQR3VN - WGcyRVpRM0dydStXSGtQOVBESVZ3QUoyM1UwCmtlYnAzRnB6bUNIOXBZQndIN25E - cVRBRHYzTXpWbVllRzZ4eWN1czM3YUUKLS0tIHdRR2l0d3hKMkw2WFVXSFp2cFVX - Z1pUc3dOemxXY3BsazhDdmRDdlZJUmMK65U1ZEf2ugm6+T1utYvjGe0J8ayjQhsF - vArBkF3UjPdTtM6i1WlLlCJ4FbGegecrnTRYtvPTqzDxUnuH1cx+rA== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArcUQwUUlPSldpbEo1UElk - ck92VllNRkVYdlh6RnNFbGNROGV1MG9TRm1vClM0aVk4eUI4aGVDeXduRnVzWkxs - S2tPeTZpM1NjSlJEV1RoWUtmU0RJa1UKLS0tIDlXVmxHdUxGWTNYNndvZU9UVmha - WDlZcEdOampTY0t3ZGdBdkoxMVJiY2cK1wfmgH2QIx52YFQaiq+U75GYsRLMY20f - vgFETLemlIJ9i+OmueVb7f7xhioehzXNYxFCIw5bnvdalRZN2+7HZA== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzSHQ5ZVBVcHJkL2FaZ0Fq - NTFPVEVRRjg5di9RWDgzM0VmMjdCR2F5MGxBCnRZOUYvMExTYjBtOGJhMHkyQkVU - aFNPRjByYktGUWlnWWVuTXFmakEvcG8KLS0tIGpsRGZCRy9aS0Q2cXlLdG5JMlUz - WENXWU5XcVJxQjBVejkyc0tmRjJjS0UKxEEXOdGsxDn2mbyexwiZCd4gqs8kb/km - oy5eCjJvsPG7OWwBLOI0An9d2mkhee3XkFmNDti7TBcEfiOShuTaVg== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKRUZSVjZvYWlORjVCMVp1 - MEh2V2E4ell0ZFUxQUR6VGpyRUZyT1I3aVZRCkp0MkRwTkhqbGlpSVpZVHZxQ2RD - RU5lM044d2NmMWZxeTZsWDNXYkFtcUkKLS0tIDlTU2NBVjJaeDBNeXNBVnJ3bnJD - eFJQVk9odzJ6dHRna3BpY1ZoRmU1NFEKMmsVs8rrKa+I8ATn33H4AjFzPQNn4o9i - DCHijPDGHZsN0fEmeAu+lhjtGmMw4j0ORvdgKbZnToGNOBooWZ71ww== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - lastmodified: "2026-05-09T01:18:09Z" - mac: ENC[AES256_GCM,data:bb/DArBCBMdiHSmcm6SQfGZgIWmAMDrfZ0ff6UOt1SE2cYTd/vZNObdPGJJNT73VMp8xNc9oZX/VHCXlK5eTWID8VyVRnlI9xRQssVJFRcu/I4FP9GPmFXspgBkqmRuS7HG+wJ/YkNmibDfrU2WPf6Foqq75xJabun/ZMqj1a98=,iv:i7UL/Bw/xQR+lc5FmDJLNMjtZV9As6FV2NKMir5ucyw=,tag:LiXqdHbVQFbx+e7p5pRfeg==,type:str] - unencrypted_suffix: _unencrypted - version: 3.12.2 diff --git a/secrets/pocket-id.yaml b/secrets/pocket-id.yaml deleted file mode 100644 index d6d12c38..00000000 --- a/secrets/pocket-id.yaml +++ /dev/null @@ -1,108 +0,0 @@ -admin_api_key: ENC[AES256_GCM,data:mUqwoNLWoRnNgS4RPn1NCVtxLe2QPlQMEU3RhwX3Phw=,iv:VJKOVAWpgxV3oMXN4ZPkgCwLbLIK6JL8nQK348OwOIA=,tag:ZVhVvBEQtgzD6fprakF5Aw==,type:str] -smtp_password: ENC[AES256_GCM,data:ovFXGXnrZcwcM7geU550NjetHTTetF0HWbF7QVYGLGmInCzB,iv:DicSeWXUFPbKW/jT0UBGnLRIrNE2Dkt2IGLfVamgshs=,tag:ZeCw7TyHwEBDao7BwgOlKg==,type:str] -encryption_key: ENC[AES256_GCM,data:mGI9Je8m6HRUop8NPOtWd+q9Z7PE7RCJ3ujNqg4M38/1DwiLg5WGSVI=,iv:zjiLeuT2CiWqUM/ajKHtjTjKudxG6Am0e/Raup1P4To=,tag:xQkjN4JKyGOKsB7uX+t/Yg==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4cHpjQks5cmJ1LzdSNkdm - WGVBTEkyNGlNYVN2dkcwZ2VlMml3aUtSN2pZCmtXSlVDMTdwSnE0d09NNUZFOXgw - VUxkMExzSEVRcFNqWENHS05seHZSMTQKLS0tIHdVL3l0WU1FZklvQWx4d2NLazFz - YWg2Nnkzem02Rmd3ZlUrUnJHUTIxWDQKT9/IRCiZn5FTE5FsyXjSzRPRDol5eaOi - H1oFnRnw0fzhRF34eqL0ZZKDSgRHARjTLcClEeIcVR52m/hvgJxpqQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2UFh5VEU2UzZEazgxL3hk - aFdYUVBaQ3UwOVlWYjNyQksvNjA5RDg4WWtJCjViQUg3UkwrWFVVMzBHRlNHc3BC - ZmxzcE5uNEt2ZkY1dWo4Y20xN1dtTVUKLS0tIG5hZTdnSG9GTHpjS0Z1eVg4TWh2 - aTgyL2VmWDdQbnYzRWJISnU5VUpGc1EKnbTqHOp5TuRP/MdUDu1c47AA7Q6lmMtM - rjUKnk5tn0tmQoRSMOAl6MldDeO5JGnX7WuyzY60GwsWoYWmYLzkMA== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBYnZyUHBzbTZ0ZDFXMEMy - ZEJsM3had1lsejlpa3ppaE1HV0o4SHhqODJNCkdORURYN2lwT29jRUU2VDdsV3Bj - eFhWMzRrcnlxNmxqNlY0OHVYMmgrekUKLS0tIEJDZGh4VUF6dmw4cUttNGFRZ0FP - U3VXcWdnQnZNWDhxT0NMVEZhaVNMT3cKGyn+twMwpYKDWF7Bv0IWuZp1ml0W0yuR - kNeM7IWQtmG2EjM08qMJcCzW8hPtNdA/7XCIdH/6p6SdN0j11GQF3A== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzZ1hmQ0dmQk1lT3BvL043 - WHFsR2hwYnN5TE5YQTVLNjE0cjdmM2E2Q25FCjB0TjQvcVh0cEoyeW5TUzM2bUJX - TEttSi9EY0ZrMDlUOFgxMmJaS00zUjAKLS0tIEVmMkpTMTZraXJYZXFLdWhTK2pJ - b2hOUFQyWFJRU1ArWGh0d2UrOVBzeWcKNRSs+NL/qEQaCIcBb8fHTaB7in2INDhw - NMiPS7EiSErG+JVQ9B2LiPg0F8sXkL0kac4YmVnMFWEi2RMgVZFZnw== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqUUk2VUhWdnBxTTlpM2NJ - bHR5TW5JQVhyWUtOSkYwMzFvQTJpOFNoN1EwCmtrbjNZbys1SjJnRGh4cjlzT1NN - emp1dnFsOVpQQThmOUpQcTRBOUNhSTAKLS0tIG0xSThMUFYrZkhENE1WUUVsUDFB - b3BvOGFUK0FhR05hYlpicXluOGtsM2cKWT+7/FccDNOzZZGeaLnmX2z+IGVksNBJ - ORL4TlJkIqy8S8DtNMd5JKP9DXJ5cVD2jzQSjd1YSdjXREugeLGcAA== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0cVB3NVVpZTJQNzRLUXlB - U0dLcGtJQy9PTHZ6cjhob2ttM0kxMTZ4a0Y0CmtlRTBhTHh0blV6SjlKNTRnMGFa - QTN4b2Q4WldDMjBPM0ZqVUZHc2FKY1kKLS0tIEE2SStmcDM4ZW41M1ZvK0Ewa0tO - QTRPQ2xxUTNTMmVPZDRmanZIWGpSUmMK1PHKTQYVXUo7eeWN9g7PyuINTjOiYfhZ - DPHe1GXaWXjibtAdio8w105sNgWP0nADTnvjlKfoizIbL9Ub+ZPoNg== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzZkh5T2tYSmxCTlFDRWJI - RW91aXJ1SThuQW1ITnB5T2VHWnJkcngrSG1BCm9MZkJzeENLNzVLZ1VzQmxwVURO - aGJlS1ZMRm9qRjUzMUd0MlFYNnB0SXcKLS0tIHF6cUF4UncyQjdQODdLUElJaS80 - L280VHlGbXdsZTVLUDZzbVdzL3paS0kKnrBrub4YbayXkSgkSCJlQw1unC/xa36p - ezKFxHe6dP3cYpUmvjwmwaju3XUyHakfTpak5zAZgdjJaXfWmIFndw== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxYm8za0kxME43VFQ4RTNh - STFjOEhWOHNtMncwNjdmNWJqMlVYM0FoRkhJCnBDa2FDYk9WdVdKU0Y4dHNIOFlq - L1lEYTNsNkVyYnpEdzRoVERpWXJ6d0UKLS0tIDQ1WjNOSWJKbmxZUS9Za3hRVDB0 - N28vT24zWEs2M0hDV1ViS0Ywb1VaUU0K1w7xGwyz907KNmKj8HoWUTFr2AWw+5HW - +FPVf+jGU5ORdoMSZqBoi8UtG25OLC3oK6svPwnOIKs1gM0DNz8dmg== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3NUcxcUIxcjJuRndxRzlX - OTBtZzFjdHl6cGhMRW5JekUvM1dMZ2NBYm1nCjNuMm5BM2hmTTVQUGhRQ0RRK2g2 - WHBsbks2NFlidXJpYTNISkxyb085WDgKLS0tIDFza1V4d05RNmYvQXdYOFRnTkZn - S2VSemhwRHNjeDd2TWIvb21mb0dDMUEKpu4Wz3kU6cwEazMduz1YmqnoTBKXa4ot - KSQrrpoXbFHt8qTmq/gXlJFzBsSYny+OTkCqbG4gfkpLF3IMMQEJGQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3V1pGdEE3VG84SlV1MGJ5 - UExSS3RIdEJyTmtXQ3V4K29lUVBhMmd1ZUE0ClJUWW1OY2x0UFRoRnM2bmtFRE82 - UmRjcGtrNmwxYkZHOWtLZjJxQVJpRXcKLS0tIHZsMEhNbThaSkY1akJic0pRdHl3 - SUdDUkFMZWtXTGY4V2FxQ0xGZE13bXcKHW60+KdVfUce+Vv5RmF8XiRuR/SKHZSe - 4/ZOl9+4otrjIgj1XfyJZiJwoSQXCj4zkYp+u5TUft7XwcZcn1LQ6A== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBU3VBYmVmMm5USGpiZTg1 - dmhieDJyaE4xMzI1K3U3ZHhYZnBPRHQzTWx3CnVYUGFJdmV0Z3c4L0lHUm1kYmww - NzRkYVNaazV1MXREbm5ZTFVNSVRWUEUKLS0tIG5QOHZJTmFiV3c5RTBsMllYZXdO - a3dLRjlteDR0UXllYjNNWDR2VkdxeGMKvX9upmqkDTdVNoS+z5MgiM/TwMeBQPSU - qsVa/14a0ym/Rl+1sAY26Px7JCL8l757UvYN4A2Imj+366jD5+JKYw== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - lastmodified: "2026-05-13T19:25:31Z" - mac: ENC[AES256_GCM,data:G6gzW6+8yPolONAU67tpaae13aXPy0jddOLDi82brJvA0/2RpgT5SbOAAimPl+GTZDCHSrK/uGhYmdCtAklAWcHRtTLJd8cqHoJ+04ZoNuHKqbP8UiJlNUVjos96//1EhIptBppdgIToYgxabInoP5ZjtsceAAzYBP5DUBzZVcU=,iv:KtMUv0P3CrdC+rjduV/LX6NFxZXFTHnP5dKPnGCJg/8=,tag:q0b2iss/tiNH/fMIWoF5og==,type:str] - unencrypted_suffix: _unencrypted - version: 3.12.1 diff --git a/secrets/postgres.yaml b/secrets/postgres.yaml deleted file mode 100644 index 5b4a8f76..00000000 --- a/secrets/postgres.yaml +++ /dev/null @@ -1,106 +0,0 @@ -postgresPassword: ENC[AES256_GCM,data:3B2+IiXMtQhSmWbAx2k8JEf6n34/CZuTAi2CsmXX2/4OTOqhhw9J3k0lOeRLnzfJTuwLH0u64iKlOrNhq0vl9Q==,iv:e4IB+fRHTUEPtJDOBW1BdQwRa6JevLaclNQ5ox2c70A=,tag:qXEOpSwP8e+b5XbCVRuDfQ==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrQ3NJYXNxK0NWWlc3YUZN - TCs1T0h1alhMY0NEc1hZeWYva011TWVaZzFjCjl1YWRXeFFHTXhic29uSHZXV1Jp - UThVYk50a3ZwR0xzaitjTW9kNFNFeVEKLS0tIFRmalcyZURMaUZyN3dTM0EwVzB6 - UnlJSlBEZ2FkaE5NRFFjcnhWc0Y0N00KyA1Bbu8PrR2hd1oUZU4acWUEpThRnuue - vU3y6m5PO78ZAJg6UavFmKfvl9n44sN/94cla0kEwFoG0YnJtTqWuA== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmQVU0U2pyeGVGeFVhUUd6 - emg1dDBXaUlwaldwd2FXVmtOek1YeUpGTTNvCi8yMHNWclNuY1RwQmNxQnVxZXhU - TVVwNjNvS3h5eklQRExwMG1lUWFYRFEKLS0tIFV2UWlmNTVIVFo1MEx5NVZkRlJa - Q1JNdFZsYnFZaG5EVlIxWk1aRzZYa1UKM5ip9jRX0lohA29vJj2ZnH7i0t8dG7kM - RMZRwR/xkYJhHUH2RJhk87BSd4VQOqXKRQA9GBC/TDESzg9uXUz7jQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoSVRObW1YRWZlNkNiU0Vv - aEdiMGZudm85QVprUXhKRG5TNHI1ZTVFd3lJCnJMK2RRUWYyT0tTcjY3Y0pDTWhJ - SW96ZzZLMlBTRDdGU1BwQkh6ZUdnNk0KLS0tIG9QSDhXb0g3MWVzdmNBMjhwSUdk - NHF3S3AyanhMd25jb2xXcHg1SVlqbGMKyxd4HIoS0bl9dGJUyAEp9IwejlVgOaYx - ryyjiTkLLU4pQS2f7u72WnRU/3iI/IIwRkj33YhjFuV3gh2LrIMytg== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEZHd0T0dlT1hFTXBGQjJx - WnlNYjA0VXF3Tk1vTWNsY1ZsellmSnpOcEU0CmNJVUtkdEhsTnN1UnpWallFWHUz - cU9ScjJ4SmYxZ3FsLzBVNHpwbEFkOVkKLS0tIFN1WUZqQXltbzdMclcva0oxeVNH - c1FIRmFKQndHS3luTGJZUUxLQkkwVUUK79utwmOjx8Nx5jcPO8RPTQs37q17ImTX - c609D4u9/QQ2E83byEYccZjZzF6lH3K9umTSKXkO2yrr9ZBvKcRkcA== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuRUNIbytzNkgwRS9ycXov - OEYzWm1CZGUyMVNYbXdPRWNHL1pVRlp5TnhzClpXMEtPbVhXYXYzaWo5Q24zL3Ju - Yklab0hTa2l2VTF1SXU3TVl2NDVwV00KLS0tIDI1UXJkN0I5VUpjaDlqejFuanZG - VzEvRUZGMERJS1pZMi9Va0Z4dXlFTmsKOPfiduCbBaTng7hQI7Lywtu/RjXwOANN - mr3xaDmppztpG5o38n8OTbGRnxcFGaLhTv+LBWC1nUxj1oOrr9pn7w== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRMnBwcVBhMDZOUkErMGo2 - YmV4cTdMZVJZd2t1RnQwZHdCY0FSdThIMG44Cms0RFFLd1lVeEFKWFRJUDlzelUx - OXlxeVJqa3c3VVFaSEFSeHRLcThSZ00KLS0tIE1MSm1vWDRIT0xUWWx5T1F3RVc4 - cXJuaitxNUlYdHhTOEkwSGZRTmRPVjQKghn6q/lS3mNnafi1yz7N95QmF9wCqKoU - jGJyje03ZuppR46yV4dtgoPVe3cR3W7TQDOMca6FbP+0QDVqALOGeA== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSUDhpTDNhRkN2Rzl3NmQ3 - M051TzREZ1B4Qmt5dVk5SHJrTjFpWUU0L1VFCjJhQWZCMUJNeGxORWJGUmJBR0xo - aG85WlhjSGlYRllRc0VIS3JQWmMySnMKLS0tIDl6T2gwc3FFZWU0anVqUlRhYkhK - VEVOOEppMGNWT0YvU1MrTndFZ1VvazgKnrDTnGIOm4D82m8HXW/jDEtbT+aWFHVg - 0UgrPHn+FcmdZsuSKYibRzvUw2PDh1vU6z7QLrNPjvdr9oNWiVIZTA== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5YUhyZVJmWmQyQU90MGZr - ZGU4U2htSHZhYStuMmxtWGNIQy9Hd0xxVzIwCnVVb3MyNjd2Y3JQc3UyQUgzSjJt - QU9TSjlDdEMyNEdTaGxkc3ZoY1F5Uk0KLS0tIG52cnk0MW9qbTl2NHM0ME9DcXRW - Zmo3SllzWjhtVStNd2xZQ2JKZGRzejAKBhO8iBs7wdeKVbsxjykssusYrr+DWwAI - Xr8FUvWjaFhR3eRKP8wpdcUR+L71h7t3vhU2s2/gmk7RmadRjhZy4Q== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzSHBpb3hsMHVOQSs0V0JX - OS9ISWhsNUlZZm14dmdNS0dIUlQzSCtYNWowCjhhNmlEYmVLeVRTMEtkcEwwbjBv - QVlGbFFqUGdyRTBKOHdKNm1KdkkrcXcKLS0tIDNkMWtQOVdTSVl6eHNKdnBiQTJS - WHZ6b3lBb1NxYjdsL1gyT3UxU3JpMnMK2neomJjwNgvzNZyRZFIIAmgxAst1X4gI - QNG056CFZkJT+cHyWggy14PBBjdTZhOJtK07YOnLtd9Zni+M/18C5Q== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxMHZFTnpwSlRKa1plbEVj - emE0a20vRndaZWFDT1BWdnJVdU8wUi9saUc0CmdkeERhMU0vc3ZxOHpkMjlCd3Bl - Q29WekZ2ZlcxTnN1T1F1Zk9MVkd0NzgKLS0tIDcyVlcxTWtYbHUxaEtmMTF1eVVG - RU9CWEkvd2hQaUFrOE01WXB6eWJpWHcKq8bhfk5LCnQrQjw3hi1y+foPNvguDhZA - 04u96J+UQUmzIxcI1cavIx1d8iB7+R4DKsWL9VpKkNJ+cr5C2je8hA== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6cFJWdHdPSHI0VWFpcTAy - QWkxNi9mZXpnckh6eVB3VEd3R2lVaVd2aXlRCmxNVXVma29NZ0dpV2hvWlYzOFJz - VW93MmlLalhYb1hIWWRvMS8wUks0OEUKLS0tIG1OeVNIU1lyUC9lVUdvT1NtUVll - MmdDaWFjL28rZmhMVVpPQms4bi9LNzgK6RNhCBuBrcoWPjd0YcMcPUBVx3KwXfaM - DZuMCbR6FteTnc4A/Jm1KGQ1RPDmfwvptlTSgdL2PxOO728BCG2TJw== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - lastmodified: "2026-08-17T00:26:22Z" - mac: ENC[AES256_GCM,data:W2rOLmagKMc3nQB0HMKX15lTjl1xVVVWCsO/cztq2/lvrFAsf75eXiBdm+C4grnmk8355FGWCDOVtDDdrrmk311sPTh4aBiI/NDY05w2iH1zcqbZB2+3a3CeShWuAueUjyWxEzcUNqELc/bOPavJTONSRjQqK1raNSMYFtfe0HQ=,iv:VBau5owUnDWg4sImkcCfG3vQzsk3iM55b9wzkL93xL4=,tag:7m0x4QEZN+uhwwISz72rTw==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.3 diff --git a/secrets/restic.yaml b/secrets/restic.yaml deleted file mode 100644 index f099b697..00000000 --- a/secrets/restic.yaml +++ /dev/null @@ -1,106 +0,0 @@ -PASSWORD: ENC[AES256_GCM,data:vCfoGO8kOMZYGjP1+w0=,iv:9fjxBEWiEtyfqNN1riZo7gtp17UoCL10UoVmQ3KzPyQ=,tag:PTf64IxhBO8aSdzeZkNeVQ==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBncW1TQnh6R25JVmxHS05h - ZTdZSTBOZ0swSUtUNS91TDU4Vng0QXpiVURzCmdzbnl2ODBFbEY4WGhBRkwzTFlm - aTh5SWJLcFZ4SFJWQTRrcWZ5UTNvSEEKLS0tIFFCaXQ4c25OT0VVSXE3M21ob0o5 - dTJodTViU2lxWkRzQS9aeHBuMmJTZkEK2yqh1McAPiMhF1Jnr1ENu9Hlh8cWglzS - UsvnpRiaHIeUcpD/cenhxncBVDp8sItiZH+XuBkPjrCletZgzBAQWg== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6UHJiTFlkNnRTT3lQOUNZ - Q3FtSFBmckJNRCtLcElZL3ZWUVlzREhvYzJ3CmRGOXZIRDkrK2hoMDhPNHZjMXBZ - TWJNRDk4WnE2SHFKQVhtTitlMFVhS1EKLS0tIDFlbHpyamo4WVpWVnJhMEFpZU1l - OUZ4aEFMOTJrM2dpa2tlS0FqczR1TTgKsTTKNgOna3K78kobDWW9ymObqiWRKsfU - 0OIEvG0dDdYLrwHwq1opWKKiJ9sK/eEM0qiuwAbhO/bRhchQYTcaYA== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuZzNvNzFrWkVTVFRHY0F6 - S3NpRXBQdU9jUExiSk0xVjhCYllHMTZicFY0CngxZDQ5aS9ydzdDRHpoNGJEMXBt - dDNLRm1ZejEyL05GbTN1cGtudU9YRUEKLS0tIGtmd1FxM0hVd0J2Ym5MbVI2aHBq - UTFRMFhCdkJvNURzMWJiNmUwdVFsazQKHgRd3HpbhEJdHjbHY3IzIUZB45xfpPLs - j9hxWocIoESVigwjFmToTjUvakGo5gxIniqJ+3kuTL8Zdqep7XZLYA== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQMHBYQkpPZEJkTFI0ME5N - eVR0ODA4azY3Yy9CY2N6WW5SZEQ5eDlLZ2gwCjdHVkNrQzJOQVlLNU9NQjE4cHZw - cHV0eWZGSWpyVXVSTDZWZUxkOTRPWXcKLS0tIHFIS1UwKzBucEFiTE4yRm42NEky - Q1ZKL0lYZHR1UjlCV2trc1haYklhVDQKf9g/2cHmLZw++jQiUA8TxkqoJXVQmqJx - e/P9KzDbxlNBbEDqJd/bkZ16oUB+7M16sSp26kGGKUGVT0PmnjyHqg== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtcno0Y1BhOGl5cmNwZFY5 - YmRKZlBXTnpDT09DZkdxYjQ4Vm9haWZPL2dnCmlOSGZUNHkxdzFaSDJGZ1BxUTY4 - Q2k0dUhxMVFaK3NGTDFpczFqemlqM00KLS0tIEJhTm5RTDFieE5PeE5CcEtORUZO - ZEVORzV0VVAzbnBINTI3TTREZEVLUkUKNqe6qgSbRBNdshH1YN8GMFG3jcRHd5+f - fzKdsxq94eXt7D0yIrWnQ11u14e5xFjFGkLwh826/DcCV2HZf3nILw== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDUVBiTVJmZmpURkN4OGN0 - Y3RYeFo5OHE1UHFERUVNaFpNd1ZXYTloSEZzCkt0QytLMFhDcU15UUtrNTVCck4v - UEJWTkMvYUduYkJoTkc1VUpaMFZ4amcKLS0tIDlKaXFxUW8zZGNTcDE0clBLbkh5 - cUdPODZZZHppWlBGM1B0aW5lUklhRGsKB9bS8dl4Bl/97JZfdxDeQb9PQodl6Wny - shXfqijYlHzGWnVa4L+t8p55oReR6GAZTHa9wfP4Q3Lg4KRPbbCv4A== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCSkpab2VPNThFckZaYit4 - RVVISDRKdng5bVhQSE5qVE5iMUEwczAxQjE0CjNyRVQxUTByQ3h3Qi93aStRbTha - MnhUSzJKQU5XWVlkdDlsNFJKalc4b28KLS0tIDRXQ1BsM3AyVHZGL2NxYkFJMjBN - Y0lHd3VIejVEQ3V6bFV5VkVpNFRXczQK+I8uk7a4sG6TXds56Ua8YYOrEIxWjb/G - PJ7zy+TURSg/KGioNhZTGtKzS2Zru41PduKQZfV4DCPu2tyE7AR5GQ== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmZkRtVGx0bDkvdFliRGs0 - OE82elpPMFBYVHZkZDZYYTVRa05MakVaWVEwCmZYLzdTNUQvNmw5WGVaUnBCZUtP - bTNYb1UrZlFRM2h1ZTR5eUFDQ0hpOHcKLS0tIHlWaU56M05EY0ZSSFFVcjBWZ3ls - SVRLUWNDQ2Q5Y0oyMEY3M2NsREdzbFUKupQI9P5MLT57/xwR1F1Lakk9I3BZBceG - Mv1esvFD027Ip3+6UuDS2uDngfTHOGR1NmsxodS1okNsWWd1W1wC4A== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvVFUvY0ZMWlArellqVVhz - UHNYZnZORklhWEF6V3ZERFNFRFFrYjhyeW5jCjRYNlhPMEVaclRuMTF1RG5IUFlF - R0U0ZDhlWVVqUHhOcmR5MThXbE10anMKLS0tIFJKSHkzdVgyM3VYZ2kvUmkrQzJT - U1ZDdVRRYlBiby9UcVZMWEdJa3JxY1EK9UWFhHYGaxrJADwjQRLyzgLC9nNCjyI1 - /1+DPaPRW2B/6ypXVvOUNlSn+wOYNL1ar8cRg/QmJa3+dn8PKQk9WQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBsdDVIbUptZURkdDhTUmh6 - UXlsYUxtbUVvWlppL0ZnZzJGVWVOZzg4c1RBCmJwckpzc1BGKzJvcGI0MERWZkZH - eUM4UVVXOGFmaWFKdHRTMzF4dXpZaUUKLS0tIFJ3MVhEQkNyR3dENWljVm1lU2hp - dVI5NXRBa3U2aHJJYXo4THV3VWJ6eEkKoZr4Fq6qicyLyL1dJ3MUsR2HS8W+5NK4 - 1F0b/hZ9PIlqHAXRaFh7Cw9/8kRXc2LaCxnCvB5t+a6G+2Y4fR3gRQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxWWdsbVcxaWk3RnJLQ21S - ZDZmSld6Tnk3cEZxYTFRNmRScjYvOFV1Y3hZCkxoc0I1YTFDSDNJRnZFWTR2RXVD - VlhnUFVqZU9NVjlMdnVqbnBJaUM5aGsKLS0tIFRpbHVxby9FeWhNVW1HcmtmWjN4 - cklHY1hGeFJxbWNtMHdzbTBlLytEVW8KcWxuw4yjAL57Px5ycvoiSLllY5ARsbTU - GMCojaj53cHn0jpLr+wAKXYXskeIoZvb2da24p/66XiZ0mjwTF9AKg== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - lastmodified: "2026-05-09T01:18:09Z" - mac: ENC[AES256_GCM,data:eri8lcJK26sn3ZKhq3w3VwyGTr1L+cwtAbs8vcLD45ZdYGopWDklgwaIMrq9nFfdj57aMNHde3Ns66f3Rb+k5EJIXKYzndyl2sIVPvdD72pz//ibO5+51oF6G3q8h/D+C2J7w4UPG8WcdAzs+iR9yiP/kK6QZAupCwf1Sho+1g0=,iv:qec0bf0zM2zGOthTSS5CjzoUj/nCRuWdAEbk7J1gNGY=,tag:kJdnwkt0eRpDisk1lMAQnQ==,type:str] - unencrypted_suffix: _unencrypted - version: 3.12.2 diff --git a/secrets/syncthing.yaml b/secrets/syncthing.yaml deleted file mode 100644 index aa4407cf..00000000 --- a/secrets/syncthing.yaml +++ /dev/null @@ -1,109 +0,0 @@ -jubilife_cert: ENC[AES256_GCM,data:3uK4YJuoY2cnTSYJw2BZKJ9PopUypFBe5b5BPUXaBdUb7Lj9mRileQ8FbBvm/AaaCFKuxzAGuZIu2JlGQCWwJ7v4lZlFUA229tUCTcQklVAm5Ij1dWk8/SjJ6eK0wse1xNyo0L5w5iRVVG0EqXhx9uQBgaUeCGMlyvmGSOYSP0Jv8QZJLphMWzK5rraCrw6lkKHn8DnJtNXk6F+l3XmzmxCfNQjKkCFWb3cOnqRiQ5LV9QWV6cXZ+ba5Z9PMH1lmUBKCaBO25LecHrnY3J6PfZZBEdZnqjvdROjP8qok8mNw+i6UD2l1h1uHxOIhIjdOAkVaNWhwQjtOlBvCnuK7DzWnMqwsA1So+GQo1bdD7osgzU+fS6JoehXHwU1/wd93qoop+GXgYxetRD/SGxAmVZUFEJ88p2lSbxV6SD7lieuSBnp+yDkQ9NEe9o6GCUoL6GhyXz1R+kV1KnP7nX1FporkHt0xZWfsjQQpkeEU+Rv655eGBVeHr0l7OINUXeFQmR2OrJHAu+Oj43wgy+5d+IZJ1XcRKbFLPbfM0c3XSFQC18yCKAnvq0ga5rAEl76ZJ+kg8ONvCE6TCPo+XCBgvH2YgftOcJlWhpC/jrSN4eNarrMEHj2zFwwgZako5rORWauTF/DBaGKWu5HXDyoo2DwfgTz+N1XLSoXhi/CMzFXFy8QKzkw7MSFNSXkjLDYSCSLJgd9cRsEtwdea0FXIdyoVl/gv2jaKEjQnXUAtJBUVsaFvJYyrHDU+WpD7TGkIZ9nu1mTHnzLfikVcWtGaHtIkqUM7GO08odxQN57uHAJDUJwB5tUubMCTA+qM3bddcnfzkBUDMwHFFagVuRYhNEFA8KJshPV0PyUe9CNdv9sKKzn9gR4yLk74bCoUybKIvsJDNOzi/+uS8ZmiN8V7sRkM+o3XvjsuGaI4dASQj4F94nNq42gw8Bq5GCrYwEZEWyAjW7Ic8A3W2O2nl5IsXCmDDL/ssONF+dmAzgys8KLnenEuhTfaKntD0bbl5MIx+l1Dw9l6pxuI7vSDClch9XrbRduwTMp1jWQ=,iv:hj5W0rjKbsCm+hxKUAWJmC6q+ef9m+okH+nJJODaxLU=,tag:M3LbMfDhU4L0HC1ILJpIUw==,type:str] -jubilife_key: ENC[AES256_GCM,data:kU4y9+Ms5JZk28ph7R1LaiFRiOvSh1JBqmNp3lZwolBn+4vLlmj9NpdUXuCmC7gQmXOzqQCA1SgAZdUj43rw+WTl2MFO0PXIgBTiqhYpIYiqtOT133vnYPYLVShlwyGORg8kXAqnS2DbTaUqChOAeXa5MJbFKmNYakaIv+EJUbgT487vgf5xo/YDO5aVLPGSaiZXRM5N3WCbUTNC94FrV+/dPGm8qpUiBx6HceF7oVDLK2gJVjrwP00P3vCrdZYSVu7KkU60A8A1xxS8dNvtgJ3sSUn3MCBCP92WVSAB0bBb4ozGzOD4+As5ITl7Uu1hjLEVZOxtoca0VgJOxhgDzPgHBKFTPCNzh2W0L4a4GszifYqgcHhBl8qVBrkkkEgA,iv:Rshah7Sq/sWNsBgDfvM8JszAoWaSGKdQYVY6JeBgEoU=,tag:JL+DmsCzJjyJxDhyNw4yKw==,type:str] -snowpoint_cert: ENC[AES256_GCM,data:zqRMGEezTp0hhjWj68p45IlkE1MK8ZRkkDY7+/JKxPJjhgNv98A7j+JRR6CWk3/DUsTTTy7qTQcM8/ebKLOOgOpRt+ckVExd2czmlTusYE3PqrFmHRuxpu7BZ8TwcYjJOQLeRribd7BxCghVEYCH0gT6FzK1FGJdI9mVAzOUeXURvQ+fdrEavuRc5UPSTLDG98cuilr+LxbkiPt9NfGGT1JMLAoN9inKusRVYkJ0s4V6X8Hser/kTVvPqgTayD+sSqc1AS6t1D++oRgGyVRaMFdWvO3a/u/CRKO9bmQQCLiQpTMvvg7S6atl8NyeKLm4em3Z/zvwK5SuLrMdy/zGYdJHtTkEsKG80nBO514zLE8T0Yfld/KsOWo+/qSkvzGTDl5zo+dfcr8UBkR7NB8/GifpS7/pVlDO3WobKQXU44of+CKemI2KZfgb2QP9RJIduwowG+6jktjX+T3s9ZRins3YKOPcpmTV9lYZ5Kj1B4ixGoHYiPjy0x5tMLgvjURwfE/XTRCEoADr84dlIHpTfS3FigJMjJsj3mW8DQtsTBRjoXNgHpxSLgNw7Ewr0W4hOoro4ifUdzkvMwydznXvMObeWRa0qjLPTm6ABCjwokFt576POAM6DJ36M4yJvtZt615Iu7447sq7+H56Bn2H5Yn1R5G+qSYCAu6BIiHe/24yU74LKJxfP03OsI+IQjVkhiWbY3BNUGulr1T8YMY4H7j89APRUOVhQ+AfzMiJj7lxbQH9ka10hpHSRj4Dr3C7wFESWrhVWLhqls1jdNhWtdV+LeB43zsoyyl/aJ/tg7656JhYhOcdf36pS/6Q6KY=,iv:X7ggkfyPYWKkRESaWPWk1JFR/J9WxEQCQFvbe82lbg4=,tag:M+bwXjfINEt1MINtcPzVxg==,type:str] -snowpoint_key: ENC[AES256_GCM,data:XfyTrRPNN38Rt1l37MfXvBq76KTTwrrJ31fSvyIdDmOkv5s0H5Ed87qw79kuPcRyJ56KcNHP0O+qKYu9bGmaN1mKhCoHIC7Wo41IGiSBMoPIWeQ5ysCoUGyKS8BeTJ3DNz3haUUYmmdfzRbyHm7eCEnGF2aMQpc=,iv:40ksmoB99gsbCgLd7CEA35p5mNckKGwv/9K6IGWVOEc=,tag:8tQ8c4J3LxYsB6q6kLVtaw==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGOW80UTIvem1ORGJIWTYz - SzdMSlNkNnpWdEZlNUQwc1VqSUpVSktjTVJBCk9MOE91dVJvMlNMZTNCSG1HVlVp - RmtTZWR0RzdYTjZTa0JpRkRBMi9KbzgKLS0tIGxWVS9Bd3lpak1BcTFtaHh6OHZa - amlob2ZkN0s1K0t1YVRzek5TRTRwQ1EKTj426cWBRqFTqJNG6o1aS/+IQR95gg7J - rUPcnD1EcW7sM+F82p8mTy33q+uHA3tZa9Npa672gINB90+FD1uXEA== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSZUY2RFRIVUJERFBYY1VR - RnkyRnYxRzVwVVBxckc5VlRIc3V3Q2w2TlJnCk1oOWNHYnlJck8xayt1UEMwTHpR - ZDV2UGxuck9HVUdzM2VXMGJLYXVuSUUKLS0tIGZKLzNhZVIraXhJRFc5OEhTdlNS - U2RTK09ETkRPeFY5a1FoUDFpWGdmeFEKHZw5/CugY6tgPFzIIpKmsSwMwmbGW0ED - L60HEHXlMmzqFQS+xYf/cVV7BIo5m15+Zfv9XL+A4jB9B2BVmduM8w== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNQXRQWG9NbG04ZmVyT0dG - VmV5c0JZdjNBaCsrRjRVd2tSajVaUjMxUkJrCkwwWDR2enZUbU5qalk1NE1yUWhV - OE9xb3c4Nno5TmFzL216VVEvSTREZlkKLS0tIGZLSEVkdEN0UlcwNUZsT0wxUVpT - OHJieVNTTXpNR2ZqdmdqMzMrdmozQ0UKQPlMAhkSV60tlfn/4i3g4BLgaZUw8HOj - LgdRssui81HveRy6dHC6M26jLItyWGdmNfZSzIvqHUVAymkV5HdnFQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFb1RFd0h5RmJ0cGJvdFBX - bzgvVmZuSmdRd3ZBTUxmTlpwTnVKb09NREdFCmZ4ekpXcklkRzdQU3drd3RFOU0r - TXFISzN3bXRma0M2OHRlYUNWRVU1YlUKLS0tIDFqakQzeXB3TnNmR1dlUld4UWhV - SnBXaFdmZEl5NFUzLy9Eak5RcXpOWUEK//35iIynDwCdrWiQun14nbl3FdKkKedh - 1U26+LF8J0lm6RdJFjGvygVkls7OeMGe9ONUWJ/2yoM0bw1bp6gmog== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5UjgzVTZIQmZqWEZWUlMw - VXdMOG5RNGwxdnEyUHB5eDY3dzJQM3hqR0Y4Cit1MW1nZHUweUJtWkJrNkxmRjBL - c2V0a09nQWYvT0J0Tit5SFd1b2xOYzAKLS0tIENMcVR1clp3cnVHUktNUlN2Y0R4 - VEdmNWtkY3NsVmdXaG1iQ3BGcjR4bjAKUkOw5qk4/0n0HRa9QW5UX+yppd22iNXc - kWLKXpaML/YcSMg7ymTz72ZP7M/2Ul3KdRGkV0S8SvAXcjvYwYzZiQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSa2l6WCtCdmI4Q0N0WmNX - dDdQSENKRVlidzZTQnk4UGxoS0F0amlHRm5ZCkJrZXVMamJXQlNVSjF5UGgvMTJ5 - eWxUbjZSWnhCak5qTEJFVmxpTi92M1UKLS0tIFhydzlwMmJQeDJRRzZwcFVvc3VW - SWRkS0FNdmxsMzRGUUR4S2pseWFyN1kKUB38Jrex7Jz/dQ64SBBYjyrVxXoCyf6z - ij2+az5+SmVz8VipUYoUCNBCmDsLfKMk091xkY/KvEHaJFdoupNFJA== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBUTJCZ3M5bGl5MmhtbklD - Skw3VVNNa2dyVDhuSWw0cTVzMlhla1pOclh3CkdIdmNTUmNiTGNzekZSaHBTR1dt - YTJuZ2RxV1ovYjh0U0N1SU55N2xkU1kKLS0tIDdsWkxGbk1zWnZUeVp0clV6eVha - V1NCK0ZRa0JLelRLOXhuTGJ6cjU4cFkK91WvaEZYJaY70v0VuclsUNQL5mlUKeX/ - SKbzI5a7oGujv8UB6tbuaImNTxLOgbv917qZkSAw8tAYZdxu+rVXWQ== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZeU15a1N1RUt5QUd5S2Q3 - dk9XUitCTFRpcjF0ZHNuRjNtdFNySmRFVGswCkx6Mkk2WWFqeXpsT25rd0k3dDhI - THo2NXFWSzlLaWJlQWZRZGNEZnIzRlUKLS0tIDRLbzlQaFlkaGVOT3UvSUhVTTRl - VU9McWZjdVJvaE1CcGJ6eGJKT0FuR3MK/bDIFzhUgUs3tRvZVRw+4IBm7ViDTctw - y9zbe+25UFHEF0mVEwyHchIgrj3RZQ+nndH8Nmkc40IOR2s2iU9QVQ== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBEcHhJd3BObjBuVXNreWRa - UUJmQlo0REpiVVJRZE83Z0ZyTHRTVnBFQW5JCnpDSm05c2N6UVY3by9RM0dLMzAy - WG8xNEovRnNMZXl6aVA1ZW1IWWwrUmMKLS0tIHhMbGdDVVM1WGxvN2xTSE1PRmhE - aThoNEl5VGtNVVpxcWJuaXhuZnMyT0EKyPENZHfgpT6SK97eRa6OU83mc4Su2fs8 - vFhqn1EW8J3gxdyc7LxLbJ2EMSx8c59k9UmUzHQJl/LYQuR++gycoA== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpSUU0TjRzMTg3Wk9uR0Z2 - bW51bVpjRjdXWVkxbUluVW1hRlJKZDlmL0FVCndzSGFSSndFUkcwakhQOGt0eWVS - SWZMZVNSTnBCQVc1UDY5U0c1cmJueU0KLS0tIDRUemxSMlZ1ejVIbUtMRFNGdjhI - WXFLZzQvOGVtV3VoUGNjLzNNeUFMdWsKGbNrHMBIZe7tEW2K7NYlTaMJjKqyVfaf - QPLZn32+G3M2zVvXqL5gprQJYDWK9HyP1Pk7LoZfikVPOB7TDUAhFQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyTUdxOFI4UFZrSThVYXBh - LzdXaWJ3aFZrRXZqZ1Y0Z2NRa0s3MlIwNzFFCjI4blF4cEptdFZZRUE3NXo2SGll - MEtIcXRpWjFGOXlCZG9neldjWkxEeVEKLS0tIG1ibmJRV2Z0Y3dUdk8zcHp0d3pT - OW05Q0xoakJ5WFZaTjVjRC9DdVpCbG8KCM8woBUw2eu3t/BuWUD9tT5EG64KZn60 - 8MWuaDgDINgAoWucqUBE//ppy8s1ITYLOMKxr7gKyKOEnpp5DyuthA== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - lastmodified: "2026-08-16T03:34:05Z" - mac: ENC[AES256_GCM,data:NF3Ddnm6EDRy6ToyrI0tdV9N6w2NpSroOrBwY1b2AxnXvyP/aCpOCLk6pNBhjyYEgpnnTQ1aoi2papu/T8PqiJMKKtoVBnP7k69aJu4D1tWlAGkUpOvSFAtpDIp5Lc1Pw3R9gZ+X9Hzd+znGP8Y2GwNzqTVXzTx5XRFikDn7GHo=,iv:Di4xeFLDyzm5QQqmaT4B9u8Id3k2BjOE+ZUfRM8wFGo=,tag:IdzE5FTXHleYmHPS1biGIw==,type:str] - unencrypted_suffix: _unencrypted - version: 3.12.2 diff --git a/secrets/tailscale-api.yaml b/secrets/tailscale-api.yaml index c926d0bc..5ca6c10e 100644 --- a/secrets/tailscale-api.yaml +++ b/secrets/tailscale-api.yaml @@ -3,103 +3,67 @@ sops: age: - enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnYjdscWUvNjdVK1BVL0p5 - SU9NajVqbGFwMHNvQnBTZDNlcUtSd04yS2t3CjYxQnJ1WG44SzVwL0d2Q0FIKzZE - RjhoRkNZd2g0QjhJbnBhcEExRlVOaWsKLS0tICs0TEg0dytUdVNrWFFVVUUvUTU1 - R0oyMS9mMUhOVzBQZ1JZcEh4T3V3MkkKr9ZXtMV6xxZ+k7nu9MMj5phNNH76RAZQ - kWH9Jdl21xOvI1rwBTWOLmil61h7/HqmyJ8EDZ669BJDmm0U9L88zQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXRC9TcUI1NS9OUTllU1pz + elBuSThZaUxRVEFJR0cyN3JyQ3puaUw5NzAwCjAxb1Y0M3hWcGVNRHJUdHFtVEts + S1NOK1E3ck9FQXpRY0NwZ0p5dmdsRFEKLS0tIDFJRFZuNW5BV2lzaWxnV1pGNjJE + dm53eDlldnI3WUJIdDVpc0lwQ2x2YzQKSjdULTqSyL9pUNvNbKGVrV6XVZKoo/OH + zwvuWqx4BK/KlRgIjunWApm2nWbJ2EmvFirn9d2+yXcez3pRPt5G5Q== -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g + recipient: age1tgm3rcc2glqjxl5al2r780aweywv5tc2u065fzqlntwjzws4kckqepz7nl - enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVUXliWHVSWjRhd1Bhc0h4 - TkZWSW1ROUJVRnFUZzVpaWhKYlJSTjVvTHg0CnZxYzloajJrSHo4TlpkZTQrTklW - VTlveEZqbUUzbUoybDhKVnJIQnhRdGMKLS0tIFBpQ2djV1Z6UHFhTXBaK0N3RWRx - Ukx6TnJySzZpMlo4TllpODBZdEkwaWsKHm84ahjWtER4RZ9Z69azT3+g95G5Bw0A - iE3Evhcc2BR51elqZE59FS6zEswyjxpd8zQZ8hbtW47tH26EG9723w== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpSUZWT1hZcWxZVEIyVWpl + UDk2bEI3OFFTR1ZvZGZwMmtZRjQ4MVZaKzNJCkl1Mkp4SU9iUjVrNm9MQmliSHlS + TGRPQkxrclFjQkoyMm5ZR0Irc0wyU0EKLS0tIEg2SG1naW5OYUh5ckpFakxvZ29Q + OGZwRHFhM0tNTnA5M1g5UDBLTkE1TmsKApvYkWTqHJ4ySRQi5KxAyRVkkgLtzfzS + IG11vCN/dps+gn8c8Sr6Sf7ytpTpB6CFvsFMT4o5wqcy00o9n/YQdg== -----END AGE ENCRYPTED FILE----- recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxTlQ2cWdGdW9NSGFPam1a - Vm5ReFM4SVRsWDYvOGRXbm8wVEpQa2NvMzBjCjNNZ0Vpalc2MUpkankzRG1IZE5i - ZlpOcFBsWFViWVRsTk05aFFXTm9zeFkKLS0tIEs4aEQ4b3NUY0ZnTHVuY2tZY3d1 - RG8zdllIQndSa2FoR0JYT1BXWVJTblEK4dwORjudZegKvs1Gminhk8b+jy0+4kvL - Ai8Jo1i5hubav7wMoVr9IqRfQNvRj4mI2XVDrYQiKT31vyJN1SJ9kQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtS3J2ZmE0YWp3UWxhZDVR + b1hFbEhROEdtL1pXZC9ZeWQ5WVBQZnN6aHdrClp1eFlrYVlQdThFNmdvOWI5ZXdz + dHBhOHlhOCtWNVNaZW5nMURER0ZPQkUKLS0tIEUxRkhSQ2JTME51K09QRjY5S2pU + NXFOR25HNjJqd1BsNElwaHFDNG5XVDQKjaobP4fRssgyDh0ndcnwsbAA45t/D2tw + b+1O1poV+NPy5dvwJpGk3pgDucEhwLDKBrtpAW3mN4RCMBqatbiINA== -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a + recipient: age1876lthmlfq2aq6nm6z2qyu0ed4aa5ss68xvnlw5cqxcdtzslaqrqzgcmlm - enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2M3J2R21lcGR0QTB5ZWNL - T1lsNHRpQnR0bWtUa0k1d3ArSVdCVXhuRUhBCnZQQnRvWUl1aURKeDVpaWtMV0NH - ejdBbFV0c05malJsU21yK251VG5EaGcKLS0tIDVqeC9rV0huWit2MnNjWU42bUQx - YUJtTnNvRHp6SmZpcklqdkJ3SXZQM0EKAnPyCmnp+sceGeV+PBcpGZr+/yM3lxfO - FzNv2Ye2dTGgYGgh5iU1NDuQNMUyKmE1J8hfdkPJ0IqzoOx9XhAdvQ== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTWjRnd0I4WU9USVVLcllQ + dCtONElmOXJTMENBV1Era3RXcUN4UjU5MUZzCnZkb0JJRnNrNzYxOE5XTWpxeWR1 + WnBoTjJxMVZSdHN4UEczZnZBdVhNeU0KLS0tIDBoNG9zc3NpQlc1RksxT1NLR1oz + eHBMeGJGZmVITC9WKzdhV29Nb0Y4amcKLWU2kdw7Gush4ftrLdCIPx2Mr4fPzYqX + dZo5cdK+o3j5U1tbM4Hc4GqXCMqAikmJUG7489lT1D4HaPbV656kNw== -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf + recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjd25XTkpHT3ZWVy9JRVA2 - bDFQVE4yZ2dPTFlWOW5NV0JZK0tCWWRabGpBCnYyMGxhMDFMcVZJQVIyOXM4NEll - UXA4UmI3VzdGK1hmZW5Wdld5VGc1RVUKLS0tIEN2anR3ZmlhWTRWQndvd2tTOURj - dUs2d2hZcXRWM1JjN2dsdC9xRjJ5QzgKU5RVmJJeetRgtUJ9Cj6w6aTU/QFNb4hD - vwjcXKlLNnG+gaBf2qNDXADld87Xt1wD5m8TBlHVNEMiyxHnsTcaqA== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuWHJqWFdtcVU5S1ZNaUpE + NXpERmcrejBlVXFPNUQ3WUdmSnVFdU4yOXpFCmZ1bTZqd1N6ZTNkYm9xZ3ZVQ2NI + Z1pOVnFrTU0raDhMUHJFb1k0YVZKVDgKLS0tIEFjSWRXMjhqbGpxbXdITHRYZnUx + YUlSN2NuVjhlaVh5VlJ0WTVncnBWQWsKR0TUw26LPwxxbZ8tSkqQPJ0jfDdF6dnQ + xiJDlj9liHIK04FAWSWfkwUJ7HVuVuPq1c98JrI0vHsc7PFwtUMiRA== -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 + recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJRXFzUnJwRzBmRE1yK1Z1 - cmJXaVVQR0ZlME9MMURNdXdSNXlnVk41NzE0CkxDOEZUaVQrdU0wNXd4RSt0dEpL - UUUydURvYXJGeVo0aE5POXE1eTl0WEkKLS0tIDBVaEIwT3ZkcGVyUkttSmFsQzg5 - YXdGcmZXNFRzbUhSWkk3Nll3SHRXOGcKs+dhJapYAFdb63Pmxs0C6LXQF5KKFlIh - rInGZW9EbxJ0p5vNoFWcYw16ckQFi5vRGJY2+zVSnGKZSCdutZYi8w== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBrSmtYcS9qUlYrUEROM2R2 + Z20yK0ZHUzhhYUdkUkFVTVJ1TmZVNXhlZ0RvCml3QVR1VmtBU0dPUjlFODRJQVRV + OGhaS2N5WW1WV0UraytvYlBpSVJ0dGsKLS0tIEFPcE1QdndmZUJhUUZHRS9XWUpI + bFU5MXhQYXAxRVZlckcwTGZ2ZjVnYzAK0+6PBMx8Hje8Nws8TPNWLu2RjwLi/NdK + wE/y3T7Sh6V/obdn8ZqslPb17Cij+QS+cgVDy41FLKNB0VytW1Bc7g== -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s + recipient: age1fczwtlqdqq7pjyzna2yl9nvmhpe68zk5k6nyn0dt4sp0lts04anskhcmu6 - enc: | -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1Rkx6NGwzUE9GVWsvWkd5 - bTk0NzNJMjNvZXZMekVTTWNrR05QbSt6dUhFCm1INy9VZUJFLytNaks3NGhoMm9N - b2w4RnlJNmFJdTZ0YUwyV0FiVitCQjAKLS0tIFdTMjQ3cTRMRkxFQTZHOE9yOTNB - c2NBL2ZGZ2tST1dOanlQVW5xM1U2R2sKtAo38ZKtKhUtro1f9FF6qItKcjllQ+QP - F/1l7CkGlw6bHCODAOypO7kT5eKcE49DmikcRy4nslOfEQAGYGvaiw== + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZMUlaTVRVc2dacm5waTdT + NFA3VjB6anVqVU8xK1NkT2VSRHkzQm80N20wCkEwSXM2WTFIVzJnbEhEaW5TTm1P + b1hBeXJEYnlCRG1tVXI2SHpiQ0hIdkUKLS0tIE9SOHoyeWlvSDVqejduVXM5RkRU + ekR4K2dUeG0zSkNtNnVGNWhEeVFvR0EKxwtLpEDvl6Q5UtPmAuM2Nk0ngCLskIDE + LmC2Ik76PSHj3xdLdm5bRwiVIuDj/dJOZ0P46N45iICmj/qJXomkBA== -----END AGE ENCRYPTED FILE----- recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXeDhvUmZlazdZM3JvRURP - UjFucEV5cmxsMFJxd0RkZitMcnFheVQ4R0FzCkVWOGtXMUI4V2ZDcEViMWhIWGpN - LzhqZFJrL0dwd0d2UkRuTVZodlhrSmcKLS0tIFlicSszb21sdmF6Qld3ZTdveTdP - M0F4L2RXeWFaMFZwekZRQ054ZHpkc0UKGqV6dTeRqpB1+WAAR3wvDHiHn9WBIY9J - eG19IyKJbY1TCwaaNRgPqm+wFhgfO7rlgsXR92+SMsNBewH7fCig6Q== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzaWp3NlloRHpvTzBPRGJW - cStya24wNXk5S2pUc0RoZXlkdXgzZWtUUkN3CmxaV1poSWF3aEJoNHJ4d3JrMzJi - bzBmdXU2alQ3WlhOYWtTTTYvb3JmZ0UKLS0tIFBJQ1RaZTBlb3ZoSHZoT1IwR0pN - WHZnT2hzdTNtMnhlRitubEluUFJxcHcKKEDnI7+t4z1C0pvphYL3tBGbkPjlB2b1 - yFQ3V+6IBBLgP0zWv/kirJXeBEY+svD3l7DstfbAByFAB5xsElCRvg== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOY05RMzlWbG40bkxWeGtQ - WDA4YnRLcDdjODVldEtlWVkzZld6MHZ0eFJvCmtsSy96RzNNOW9TWHpRWFpQTUpj - QnFLQkRlemRKb1ZrMEN2TEJGcmRTNlEKLS0tIFdlWGRiT1NpSlhQRkpPc3FXUHF0 - L29nRzFseGFNV1grNm5aV2swODBJVTQKdAUxaghCT68WLMTk+BAMk3IFqOIDqy+r - l4u6zRqF1miuluRr8yCVPU9FnuJ29okdrgonfvBI8Z7YeMeShDIZPg== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxZytPQVk2NWR5YWVLaXVF - cnA2UU10WEUrSEEyblhsT3A1TnNkZjJ0V2tRCnVrSk9pbEk5T3FYRUxLRkh5WjBi - aWkxZnE0QUltY2UyaGYybDV5M0dlMDAKLS0tIEhhcFFEcVNLRE44d2xzRFRtVFVD - YStDd0tsR3QzNjNTMXlwNFNWbVR4dzQKAI6KEdx13eaNutN2SHVaCFq0cUcMAF0h - nBMCwyw06fgoVEMHtt9kv0HbE4BlZTitvzDH2NE8PXEHXBC0Lb5eXQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx lastmodified: "2026-07-09T19:22:40Z" mac: ENC[AES256_GCM,data:Mu9ZY9fhxkcwQO3yBInq4712i1DjLknKYsE3j0Gw/Iw6M74EkBRAhyXkGqTsqS78JjgjrcY3AIRemBWrK2EsOG/2uCuvM3bJO+vCwer9AIPoY2dHuk2bmBakWRUI+gxR4ad2/qaw9NGw6VQYMnuZu5yG9OBy1bbvl9zCcE+/Wz0=,iv:Xxb/y7ANsXovw2MWoGwWwQG0fQVxxHK25JQQjp2AKT4=,tag:dyPNNljCtIz0sQTu1VFoUA==,type:str] unencrypted_suffix: _unencrypted diff --git a/secrets/tailscale.yaml b/secrets/tailscale.yaml deleted file mode 100644 index 50e0dfbe..00000000 --- a/secrets/tailscale.yaml +++ /dev/null @@ -1,107 +0,0 @@ -auth_key: ENC[AES256_GCM,data:XZjvQ6sxr6m2urflEGknADuUE2R+1saokjV2pV95D3yzPxVljyv7FIFSHo6q0k4TpT2u9lWUYOTIoHa4Y98=,iv:4TKPdzNKVZLfQCCG5XyT7ONqB8+PX+p3qISISjkd9IY=,tag:Ab0dzDmdV801BhiJ7EvWGQ==,type:str] -caddy_auth_env: ENC[AES256_GCM,data:AiqAjXVFvO5CRtmshn/Z7zF6+4BOXTWghaN0hGq7QWB0ZYEuatYQe5uz5E4h+j2nyrTiB9nw3PqVRJBnJX0zsvCTXModAo6o,iv:vSid/Posm2PMPDw1/HYPWS9mjt83tjcD3U1GBq/Vh+Y=,tag:eUDRvySKxRN9bV/2XkS/8g==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqb2QzdzZleUliWHJDVmFh - T1pTVDBFKzdZeWZ6OWxKbVo4cVlBcjhoNlNJCkMrMGN0Mm83RHhWNmVJdG5WNXN3 - NG9Ub212czRZRnU3VWVzRkxQbXZTK00KLS0tIGtFcGQ0cnFmYzV2c1B0eDFFbzlM - cXk1aWptNFFFYWx2Ymg5OXhuOXN0T1EKU6T52InFpaNNFJIMbYjRsl7yHK0DN2cT - CqgLqfMoFn7XsC2FqQ4fhi97xScdOvS7o9gYHXCb7bu4xUC7u9owUQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjblRFaUJjZjNHUnFkcTlp - SVJOSUhoSjN0Y1FreTE4bFZvUXRMdmhqR1hRCmxHby9vODV6Nkk2T1JTWkl3cHNP - a0pXVlhBYktvVlpYaUh2M2VlNHFxNkUKLS0tIFJPRXFVZkRIcHlLdXBZelYvek5W - alJyK2M2S1NkZkxuSUtuZTNGRW5qSFEK65HY7LrKZwuMZawmloQT+XOLThCBCfSq - MkoYLJoUhn40RrBMKf1YwVbegM0Y3D1/xYZltqLGmHpMEYD7xnXVOg== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtWFJ3Q1VVVG8vZC8rZkEw - am01dzR0Tk93QVdUVjJLRHBUdnNRVzdzNGgwCitwZVBlOG1vVXZhbUtoSzZiTk16 - Z0I1T1dkSURxdFRRU202Nmx0M3JOWVUKLS0tIE94a01EeXIyWGYvUTNSWjY3V1p1 - NWlCY3h1SnhTTHkwVU9TaUxlZ2NqNG8KdU3EOhjIddtW64lP4S9Acea09+fDveym - Uk8AqoZWSi/ev0JqzRsO+BA+Z+RGHsDfHPd5bMFCawpY2TPceqWb0w== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxR0puWmhiZ3g0ZkpZQmhv - MUdocXFnMUc2cTRvMnp3eHFhUDU5QW5NQzJrCmpHTU4zbVphZjBEb2JMQW0yUGhY - RDkwUHM3M0p5VWhrUVExbTVlMUZiOHcKLS0tIDM1SmFETWxZZlYrVWk5VlZvaWFp - dEw5a2RYdUcrNEFUUnlOazNYeXgwK1UKyBvvCCsXNAnVKESPVY38DPujNBjz7Ngy - xK7eYRv4MRcC7R8opmDi/t1pVqVOesoBZVpPrc7TAjOYegxMDWUsZQ== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0K3RPSFY5WGhEb3J6WXVo - QlBLWjVEVjZMWU5UWFkzakdTdHEyS2xuMHh3Cnprc3liRTJQejdBRHNyc1ExZzds - RGRTemZhcmIvelE2SEJGdGNFUVhPeGcKLS0tIDNuaS9mb001SEltTDhSRWRvM0li - NlFCRXcrMUErM0pVNkVORy9yMFlhRFEKUVIrWmjQ+RSQVyqck5CVaHnt2ahC6vG1 - z3YWDiZURUQTuIhj2dGpWGQGlKaYga586F4hDEM3jXxVQi37G6Lf1A== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLaGVCUUJaTExwbFBBZU1p - QWxXL3NSU2YxWlRyREk5OEkzQUdTN09GaENvCjhqWmlYZjJldFpKZGdFODUvdE91 - Y0xQc2NBWjE5c1JhcFU4eFNGa0xYd00KLS0tIER5dEU5SnVlNHl5dzd1Y1hFcmg0 - N1hqMEluOFROejdMd2IyM0paRnhYWTAK+ZqopjT/dSZ9cO3fwLg0WCW1qffc3LBZ - 1C/we9c0HAwoZaCNShWbQLilQo2A4ybiM4IWfywqMNxSjuHwNW4qQA== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwZFZOeWlXMENINGJEcktL - VGlaN25kdGxvWGVITXNtM3JxYy9ORVN0UUM0ClVjWWNxTlEvZzNhQ3VaQ2xhaCtw - MUQ5ZS9FdStuZHdqeWZxVmF3czVmb3MKLS0tIFhlYUtUVjgvRlFPYU03L09oZzd0 - aDh3MW41OWg2RGVHdXVXNjhrRGJYUlEKcKADn2EzSVQcgOjBeLJxRhztVOE8W3iI - 5kzW+hJLp6NuSjBe4G5YyfDmXntetg60/QkiWdsAiYVOD1CC9lbBNw== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlSG5aeEtlMjJibGJkVWdS - aXJpTzROcktrYVJ4NG40T3FpRjhmZ0hSYUU0CmpqK0tDbklBVG5aUEc5WjRXMW1B - NEYzYVp3Yyt0U3lwRHZXL3BIZk41SlEKLS0tIFVFVEZSK2hZWUxkbXR4ckVjZDlD - V1NxU0lpQktsN1hjeUtBc0QxOTNGUlkKk/bLG5j0CPFgq0hok2N0F9u/vlW35oyd - ksQBaHE8dgAYZfrzsM9PF5aVsBNvlnlrO3s3Jrw9X7hkjZRh3VrxQQ== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOcm1aTVgvTjBKemNaRjZu - RnkyTFV5OEVvVUFyQ1kxa09QM1hmT0JRV3pBClE3UjBiYk1sM2kxbGt0MVZpMTgw - dmsyNFcwZFN1cCtranVBd0I3Y2phZXMKLS0tIDd1Mks5YUcvVThXZ0cya1FsT2FF - RkdkQ2pHd0xIV3VuWmxwWm9UdEZrNEkKLuYiAb0LdeEfU6UOYcqKuR9WpS3J4CBR - rKJx/bE1FGzYrQH2unsg6nx5udCH9Uo6ao5OHqLzMtqei5/RU5SzSw== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMb3pqTmR5SUJsaXEzZ0Nj - MGxMZEV1SmFtQnkxS2tFNUtZMFUvUzlGeGg4Clc2ZmpDc2YvenJtM2Fwa00reGpa - dlEza1VUVFY3bkVHQXZYbGR3bjhwZk0KLS0tIGVtTURGTGpDMlFyZXcyMTh1eCtq - VklYVndMZVp3cHpBS1ZUSXdMeGwzd1UK6xORFHUfpaTS3xnEvhh4Pq4iPkwZNKLu - wrffFiukugAJUiQmBvjh+5Eor0A1BCCoRAW3qe5pZr66EJ+NSUlyfw== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBONkJQRXdVZG9uQm5BUlE4 - RVdNR0hiSWtlVnJlWDFuNzEvdFF1YytoYkJZClhsWTd5Z3lJWVl6VGc0UDBaRlgr - SENxcXBhaW1xcXptQU4waEJ5R0VRKzgKLS0tIHhiVVhKMHNRcklCdWxodGhvbGMx - dSt5RFhQVDNLU2FiUWJnMnZ5S2htVm8KFRuf/MruGtULxmPSC7Qbiz8CtZ8+dM+D - RF7oboi0XjMq1HtN9ETIaZYgC2b+vX1zSwkcEUM4ehAZltPkV4n32Q== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - lastmodified: "2026-08-12T21:14:03Z" - mac: ENC[AES256_GCM,data:Sy3Q/62u7ojZF+fUXulMKR0ZGBKlw1pQ5+eUVvJt0luijxq1qwXwbasY5C44OWrhGncQH80tr8QstFp44BLxYiHOZiSLGpBgJRLu8FSiusNI1ddDJStpPUsKyhYpV1w5iJDWo+kedqr6WM9NFelt226lmr6fdv0ny+taO8FFU9M=,iv:NXBkdCPXvDcK9HaPClEgeU6V0HyZuGFeFcMck4TSuX4=,tag:6o4JKYhCrAXyjilNsFyxOw==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.3 diff --git a/secrets/wireguard-hoenn.yaml b/secrets/wireguard-hoenn.yaml deleted file mode 100644 index 5ea0f844..00000000 --- a/secrets/wireguard-hoenn.yaml +++ /dev/null @@ -1,106 +0,0 @@ -pastoria: ENC[AES256_GCM,data:s++kJcufe+fazdpGvFtinnvz+XO4xTEU0VtGaee8iH1Owf6fAqBQL7OA/uUC,iv:BBGAhbE5cOqAqUBByhyoslJSPs5RnBvM343scrBQYWw=,tag:t3c0NrIOvE3asmj+8S8i+Q==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQb2Z6UVp0bGM2NmJML3pS - UTJBTU1lUk9pUEcxa0czMkZYS1BCbi9RbVRJCkpyRTl5TWRrd3JOa0dIRDFsVmpm - Nlk1Ly9zUWk0RWNQTjNmZExWWGFObkEKLS0tIDE1T0FSN010ejRnWjdqZDk1blh6 - ZVBRakRTN3VPTkNkemtiaDBFcnZEaDQKlcqyhmAj2ZZTQRVLeQM1F/y1GNlgJusV - wrF8Xa8lQT2fGijM4QhdeHpiQTL1g6j3FweyPxoAXb4m7JD+MPcecg== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBreFFIL0hwcm5JdVVnUDEw - WmZPSmNaSlZqOWtvSHh3VUZqeTB6N0VxYVNrCjdQL3Qra3ZMNlRPaTZ5YjVuOWtH - MU4rdkJlQnVMcHZpK1BFbmJGd3h2MXMKLS0tICtTYWF0Q01wdGRFeGNqYjdoTFdB - V1E3L2lhUjNCaFI1eHdqUGh0NUEyU2MK14FkncnQ/rVnWleiXTXKj/KK/c02+SHY - 2aHjYh7rsBQtx1aazRvGg82zUCaqvVJU+Q0wE9EPRwFtUpbPxFDVVA== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoRTUvVTEydXVDM01KV2Fx - TDBHTG10TVhiSlBXT3VuNTVKSndaV0RiWjBNCkJXbzQrNVQxNG1KT3dETURpNWxR - a25HNExIVmlBcWJjU2hlc3RhbWt3Ym8KLS0tIFA3MzZwZGxPc0s2bVlyUG9DajZW - RDJNV3Vjak1UbmdoRG5SdVFibTNYekEKIfwFvZMITlR2UXgkaXhKHeDupqXK/TTQ - 5vJ0E0Qe7U4Xph+VO+WOuCLYnRonQmwbuKVyaMQadsyemIHUGDf4Hw== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIOUkxMVZnMzBoNU91cnB2 - cjU3bENid0V2N0xCVUszUGhMRnlwL3FzV3hFCkh2cjhqcVRpd2tNcHIzRzd1K0RY - ZXlQaU9JNXJIMmM4T3hNdDhtK1lVdEkKLS0tIHRkbVhaa0I4MXVteFRzcG1RbGkv - MXBPd2F5Vll3Skc3SGZmYUZlUkdRaW8KotDwILclnnQ3O39tksu2ZJNyqCpW5kq5 - Y2I/PTQ+/jD3J8S1HLr7PS2Dm9YUTSgS/Jz6tLFiXd4Zgkd9S2w5ZQ== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQejNjMTZmRC9JVnRxYTZO - L2xGeW1waWFEek1qajh1dkZINFZaL3N4Y2p3CkMwVHFOekk5OHMwU1BRaS9ReHBB - ZkxpSUo1VUpQd3ZXQWwxeEZzTFBrT00KLS0tIHpYL1NxYUxPN3NZZmxlWXZEaDVB - d3ZYSWJJWHJNa1hsOTZic3hrM1RVVXMKGLwmGojMeCdE83kGSRxVVQdtR0dmCcgh - wqTs32rie8OMbxnfxo6/Cg3EeWWWbMclRFm5gxNmH6s5XvjGYJ9pog== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0d1J2YTJwd2VOcWJqVEE1 - TDg5SUhscFFyQ0VxVTE3ZlVMVUxRcVFlUmtzCm9pRnpxNHVIZmpFNFFyRmloN1pX - K2FKWUN5Y21RR0ZlWDdzYkNmTXFqY2cKLS0tIEp5M3E3bngwdktNdnpPTlFseHBv - OWRrZzE3T01xWFFOaEpjOHNiT0wzUm8KFFliHwff+3JEm/6berdwI8tNE7PiTLPc - ZY+/8Xy+ny+dv8Pj6yQjh+XVc5N3hJgroYE6xmv/aKYGrYRHGkWXBg== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLcmJYNFFNN3g3K2JEYVNH - amFZeG1taGxCeHpNRUY1YytXeW8wTnZJVmdnCklFbGlpUjg3SmEwbmFLNEtYenhP - Wk1NQ3JXdHBDczhlZzlwcCtsWjFHZ2cKLS0tIHB2UXhBZVRqNDFRVTVJZ01sdk4z - aGNtNDRoZHBzbUZqdGYwL3hUOTVFQ28K9eP+g1U95k8ahCbLKCm5NL/Rcasx4aVZ - 3K3w8WOwZpW3Fj7IKJGTyJC2mVaSox9k0Jdd+wAuaojXqQtccSAGbg== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSWnNRZTdIZ3JQaTZ4WC95 - M1BROGhaUEU5bDR3VGg5R0hXRk1sOTgxTVhJCjRSamZBVy9Fc1J6bmNFQ0pSM0or - N0dVYjVvazMrM0JQUFdMeHl1NmkwdmcKLS0tIGkxMXBkQkljK0xRTTBxbWdQS2ts - V0V6VnBOaVJ1YURSNkgxVHJZejRxc00KnwytrMbWxKukt0lpH4QeXYJkM825KDAk - 5/eWoBrTRNmCenJDY1qxDhdUZ+SjVywfaGtgxvcc3GU9pbTH/IMdqQ== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBuZURUbkNjaUlRUzZGZ0dU - RUVkZzBWWmRIeThUOVhKL0Mvay9RRlJKM2x3CkxYb1hnMGFxQWsvcFEzWi92M0FP - ZDRlTUZZZU8xeXF3d0NvZ1lyUXBVL1UKLS0tIEFKVFJJdXI0NWoxT3o0VVlEOTdk - THZBM2x0ZE8vQmZwcDgrK21oWU9GQVkKeZF+s/0q0VcqnJPPKfVucG32DpVSrNzq - zoRKqGUWmu/FOpCRs5tZw7cMvQnI7ZX4LnRa9QfFnOTHjJffq3gdCQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYNjF2WjMvUXRhQUk0THFN - ZG9QbDRRQjA2R0Q4bG90dFpCNHluUDNRWGc0Cmt4bmtIR2IvWFJia3hrRi9yZ3dV - Nkp1dkp3NHd3c0VXejJqeklyN0dYUGcKLS0tIDRaaGNDL1U2ZG9ESmx6OFl5emNF - Wi91LzFvT0RWR2kxOC90bHFZMnI5RU0KILNNlTU0UVrKXsf9+xlxSAaVbAyNTu/2 - NkeNi0RikHs5jfed1a9T/PzCpCUE1w7+S/V3NaUGu4rkyen2h5wAJw== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBwR0EyaHVPWXMvUVlseTBV - cENoU1FncjYvQUtsWEl2ZEdwQzRKV1UramdVCjZVMEVCOEtIbW1RZWY1eXFsakF2 - MyswKzV1QkJIanRKcEMzZXRSRjFBVmsKLS0tIGo0enlYQnhyZGZoUDBjQTFTUVI2 - WnI1YXJ3SDdPT3RuNWUwZ0RLY2dVK0UKcHo5+PpbA6KLVMpqI9yIHN5scej+moxe - EJ8VxBpvR+pxpX2DEUOcPPGuS/otPi6abu9aL/TyQcOaroEpr2RFrQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - lastmodified: "2026-08-16T02:46:20Z" - mac: ENC[AES256_GCM,data:k9jIGtBNd7REyaNoIds6nBvnj4n3dHmKY2a2FQ7ODSSeLQc3BPpTaOcxnDUU1vYcEY8qBcyT8+vOYFSeXDKVYt5b2co7XBVjJUxiGi3EvCFCxacyTz5Ld1/6ErhAmqS7T3jr3YtJFl3kg0FKZs9GIIeq9+caYNpoZIoLIbI8O8g=,iv:kNcYOsis9zwM+ai2jfbnL2G5yMkXWZisTYOdHvOnet8=,tag:KrPTpjOe+5gySi3RkSvBuA==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.3 diff --git a/secrets/wireguard-k3s.yaml b/secrets/wireguard-k3s.yaml deleted file mode 100644 index f2a3e592..00000000 --- a/secrets/wireguard-k3s.yaml +++ /dev/null @@ -1,108 +0,0 @@ -jubilife: ENC[AES256_GCM,data:H5cjoUxUlA3vCB0MRbvYUvED5pGGpSxdJ0d7D3qsYLGuFcXzEFV3O3Cfz78=,iv:DkUNR5vfFvFNzd/rGeU77EBZBaLzHKlhLUMUeOfvoWs=,tag:FzeNBlvlu/0BvBccf0DN9w==,type:str] -pastoria: ENC[AES256_GCM,data:py8vH9j6je/xaukLq7eETM2fCzhFW2DSmAlcJbk9oq9xJZYbt2IoSGTdDmI=,iv:a0XEoEYKDf/uLm+ueSGDEbHZV+wXQsrXebTMMRlUnfU=,tag:8ACJIiQrqHeoOeOfxJWflQ==,type:str] -snowpoint: ENC[AES256_GCM,data:KpqgUvHK+LLVUTa0HKOMzfVSN+eQtz3+pvEcUk8N9GoYXEsToRYpLL9KJq4=,iv:FNdkcz6dfb9mRj5OWv8lwrX60Afphyqdq51yJSrQu0c=,tag:Qudw3LAICz1lU4aVRgXZgQ==,type:str] -sops: - age: - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNUHhpZm5iYVBJc1JkK2s0 - VkR0dExZSVJOaDFDSkxSWlU0TGhVcGpKZ0NRClFpTDcvbkw4MURnQVoxVnZra3FS - cHJTMGVGNkJJTFNSb1VRd1ZNU0lRSnMKLS0tIDNQVlc2UlVORmJXZzY0OWI5L2ti - cXlDNzh5SFo4d1V5SWhCWjlocmR6ZUEKNkbK/46ceWgWEg2JwdiKyoDurQtF6EeP - Se5tpqHqCrYLBIIQwyVGQzq/vUtjX3gynv6BDkDJ/wHreIAcF25Awg== - -----END AGE ENCRYPTED FILE----- - recipient: age1kny9hv9t64ge379mk977slfx8deqy3df0c4cydh0lxu4ffczkftqpe2x6g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZSFlpVkJjOG1nRlRWRkJv - L1BRd3MxNTdiS1l3SjNzUGVWcGRxQ0RTZURJClNGMkh5UlhZUWFocjUreUhmN0sw - cGFoSnFTSEpWYjVoclNxREc3a0lpWjQKLS0tIEZzWjBoQllhS3dnbnVzRjRkcjdR - Qm8vcDhzMkVOOXdLb1QrclV2YWlrajgKrsnAZ4BgG8VY5Vq04dZa/wL7FWvaZNHq - MV1Wqid6laS4p9qlAkK7wAUwLl6kwsDPhwbkKoP4tpDmewJ4rqjLcQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1e5a0aaueyk34klry2qk094zrwfsvga0uft93mwweye30xhqhvfzs3jgqku - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhQ3U0THFSQjZGbG9yakN0 - UGd6WnZKWlVWMmZMTCtKUjJ3dHcrVW9BT1FFClJSeWl2RzlWM21WRmg3SFJJTzRP - aVplVDRLUDNUYjNxSUM1Z1c3M0xrT3MKLS0tIDNvbVlhMHV3UEJRbVFpRHR3TllB - RDhJL1VlN0dDclIzOExjWEk5b3NwalkKZ3yJgsaispee+4sB2RWPe5LUJDBQl8yx - HYmD5vWsRIcehRoR89jaUGtoOH0nNszPrkGSbpm8S51ODSiweRDHPQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1j9jju3whwj72udhge7v4c77gk6v6w2cq8zjngzyppwtptfsz499qyywu9a - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2WDJ6Y1V3NXdxTTVHckll - djY0c3JQTDc4cHArTEhvTzZpVkFwRW9Rb1JJCmJmckhlQ3ROeFlwRmxVRkRCNGgy - dkxWSzE3U2c0eXhIaGIwU016LzcvajQKLS0tIDJCd0VjU2tEM0FmVVBqQTBNeGZ4 - dHhuUXhCZHlWT1FpbkhuNHJlNCtPUTgKRy5Cn/80gLro6HiU5Gc8e/EytG1qm0ym - 71f9jWKHOCw8NCFaCNP74H15r3ny3teSCGZaDj6M2SPghjhx1uINkw== - -----END AGE ENCRYPTED FILE----- - recipient: age162sx8kppp90mjxw88eqs78hgnpkddf8k9kgtksmmexzvcdxknpkspmkgaf - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1eHU3RHpBS0xObjNoTEtT - azdIZ1MxUk5HaGUrc043aS8wcExuc2t4U2hrCnpCTnVnZTg4Wk9neE54UjV2R1JM - QkpCRHNPRVdSYlVNcEFlQStXR1gvbEkKLS0tIHJTdjl2ajhEd2szVFp5SHVqZVlN - NDltSnFnRmY1WUFneVFyVE5TM1NtZVkK5g2eNzmCylpih54RU9leWdz06YFDRaTN - j140k6zBLwwIc+KtEQNetKxzr6l4iS7K5raGu2zcBwHDySVnlZRcbA== - -----END AGE ENCRYPTED FILE----- - recipient: age1hhvzccxzrysq6ak2ktuks00vy3smr6rhey9swhncq8850epftpjqt3c7f3 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyVGJ4b0FSWUZBZUdWQ042 - SjdIVS9FelcvMWduUUxjZmpBN3hPZVlRTUdZCnN1bEVNdVNPVUxkdE81UUo5b3lP - bkVoMWkvMkJqZGxLK1FvMVhtMHk1OGcKLS0tIGpvclphdzhNeDdMVk1SOHJmM3lm - bS8xa1FKV25ESmYrS3EwUGpwUyt4d0kKXucXtr/leALHLjEZuh8eL5ihDu8gJDvT - v2tEm9KbvDARM6sriN1RW2+oTxn8FqFizP6mvLo6v8P13A99HYGz0g== - -----END AGE ENCRYPTED FILE----- - recipient: age1zj2aq2a2v3ngcer7s3jz6pufhh8ula8pw56etmy28dy25wrkk3vq59hu2s - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhVFdqNThrWjNlQjJHUzN4 - KzZSczV2RysxK1EwamRaSENMTk12ejEwakdzCmFsUWY1MWRzbEFQeWloTnoxR1Ru - aXR0MWVydkF0N2FPTnRxaEdxcE81bTgKLS0tIFBvWXJxNmtKNGxTSzZiTm1rMUZR - SW9vaVBBSTNLWGo1Qm1zTHlVUzgzZXMKP/nLJywBZNmCpf4Rt/FEtbGPGyWZEq69 - nCgO5n7g2g2pEqf+wgYNDD3FiYAI/tJv+Ea+3+S/+8/CsLHeJjqnlg== - -----END AGE ENCRYPTED FILE----- - recipient: age15td0jk5e2qeq2pexvxguhuuaxuaa7nhql7mhx9jr79caska6t4pqdv5spl - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5WjBoNUZLOTJPdFBwenAz - bGRMQ3FkQ29HeGlYc3lEUnFrUHQwQVFqcUZvCjVIdGhWNzd0L2tSL1Q2Vysvdnky - MFhxMkI2RWNKOTQ2RWM4R2JnVjc0SEkKLS0tIG91WnhvVUdHd0NTNHFUVmRaSTl1 - TjZUREQ0eEhKaHJRZFlKMXFiT1MxU2MKod5guY3j2VrYIeL9igOv9gzpYtnNkqwZ - cnzaoPU2eNT+GToJNxqHA92sNnDKa85clzxms6Mvn34aNGiuiekv6A== - -----END AGE ENCRYPTED FILE----- - recipient: age157en2pt286a22pxzyugt84ak6rn2at89tpma88juqfgj84lme5csq4999g - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjNWhienY4VXl6RDcrWmlC - alQ3Y2R2dGt0UHZQTTRVbW9pZ256TGNqRW04CjlEcXIvc0RFZjhZNWlpYVlGWHdJ - UmVxZUlXMWgvU2FlbGs2TnhhejhmVHcKLS0tIENrejB0ZzlpYUdwMWZrVExISXQ0 - N2pOeFRwSU1hc21NUFBwOUFaTHZEQlEKAqE1j1LBoGiHYMC+C7Yz9BqxDpI2PMYT - p/8XSw/Jn6nEUgiS2bUdMpbBKNtPAC7zYhFR/ZqphUNxl0onbniGGA== - -----END AGE ENCRYPTED FILE----- - recipient: age1xwlrtfu3du4jxg2l6eemzqeed8tflhdkjn0q5j9pzpecshtp3cpsh60l4j - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5WHdKT20vUS8yVmorREhm - bUc1NUMvVEVFQVFGNEVQZ3VGQU9zeVRHTXhFCmpiUW95RTkrVUxZTEdnZHpkTEg1 - TkxXYWJJTjFXVEYxYVczc3FwU0RlQmsKLS0tIGJ3SE5TV1ZCTjB2Zk4rWlRmUG85 - U3lSdHRzemtkYmZPbXpLS01sMGNFdGcKLqlyNEZL+K+dr5hNNbvRv75FkJnu8i6w - TQFcAdWa7eMB/x+5D08pTssYiSgxWdaorPIXfNjqYICQT9hrkf/jMA== - -----END AGE ENCRYPTED FILE----- - recipient: age1kgp3x48wn0dmzwqp0vdpfsdw42rej0ypkj0qavs7c2t2tgdud5zqcmhl40 - - enc: | - -----BEGIN AGE ENCRYPTED FILE----- - YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzQlFCNThQR2k3aDc2YTVB - M2xzeElwamppNzdWaHljNUhVTmJWTnh2d2p3ClJNZ3BKMExpTkVmSVVyTTFjTlk3 - YUM5KzhmUTZvaTJLVUxDY2ZibXh0d0UKLS0tIENNSDFtQTFMeTJ2R1R1dFliWlZK - dWt5RzQ0SW1HUm9LTlMzSEJlQ0tjV00Ka5zd+JytCf0aQBKa4M+VErkDRm5Qirnq - RiIVNKgMZ5j9uluZyi2d01E41L3LlBfod0QKvR5u7Ry1RULqyEYxfQ== - -----END AGE ENCRYPTED FILE----- - recipient: age1stsuakfyj3gkee4sm328ky2crmymyuzwjjmxrpvnm754sdt2zvnshf68jx - lastmodified: "2026-08-16T03:34:00Z" - mac: ENC[AES256_GCM,data:P7qF4+0PPVECd/LH57e9BJZfeVTbgjOGLyObUYRrQtWrija6vboAIdaoYBSfefXrqA6otAGWnGXgstldx51hkcxWV/g2y0Y4BqhzH23IJN+TtnPKIxiHP8HUARLwcuydz/lsdBRTYrvmrWqVkbvg52MWX/ELZelzie2cV6zkF5A=,iv:jz54W9p2gEv2PvaF8Rqx4BOervK8PPx59DQn8o299tc=,tag:LSEMomMhhfE3zOHLe54hTA==,type:str] - unencrypted_suffix: _unencrypted - version: 3.13.3 diff --git a/terraform/.terraform.lock.hcl b/terraform/.terraform.lock.hcl index fba9e5b3..59ab13b6 100644 --- a/terraform/.terraform.lock.hcl +++ b/terraform/.terraform.lock.hcl @@ -18,30 +18,6 @@ provider "registry.opentofu.org/backblaze/b2" { ] } -provider "registry.opentofu.org/cloudflare/cloudflare" { - version = "5.23.0" - constraints = "~> 5.0" - hashes = [ - "h1:AHGT3iXr4NMNymUXeRXu3WcKIVUbvHKpYRUbdgiQv/4=", - "h1:C6JU7d5XoRQnksREiFD3hTgGRQ18ciV7ynKvpvGIteA=", - "h1:LeM+28HS6S95Ab9xxG7GoLTrE9k9Q0GoJ3mjG2rVbMI=", - "h1:Sixlatj4vbZGhJ9r7I5c0l4gWp5Bej0aNR3akDt7wig=", - "h1:UfdcqA0fWnAbuDsV4hx8/xeAfyVKmjJYyXGFawHLldc=", - "h1:cvzir6P1UJ+IBTLlXNg57K6ojEB2+dQDa6ZK1f6eKuQ=", - "h1:imUBweQvKLcFlE+TjpiwjNg6OlSoyLlAe5LuP5x13kk=", - "h1:s3+LfSvj6fOzcXKjsOQEHg6MmHMuZDBXNNQ+7z4JAF4=", - "zh:3492a18e8753c2734bb253b70b46c8ec66151198b5221dc7772dab76778a2c06", - "zh:698ca2b12417c7477744e5410796f4fa0311f7882e1a6c790581795182b3905c", - "zh:b21e7da03e7529469f042eb5b11d08b084d255ab794bfeec80f6d8a9e8a91df6", - "zh:bbd837ccb1e08335aa7473e6c806da4c2ff04c93bfb63f6606bd09efceb82cff", - "zh:bdcaa21fe92031f5f043a6774821247a26047db92e5a2abfc4bfbd9262358e0c", - "zh:cb2c86565c94822733760015f892c71d3ed886d7db4549c561d62ec7bc20a175", - "zh:ccc101c27eec4ffdcbf43eaedc85a5ba5850c29d38dca7b1d7e20d668edb7a96", - "zh:e029d245d2470b350e12b4747a9a6c6d637010628bfe4f46644ff79f676f56e5", - "zh:f809ab383cca0a5f83072981c64208cbd7fa67e986a86ee02dd2c82333221e32", - ] -} - provider "registry.opentofu.org/tailscale/tailscale" { version = "0.29.2" constraints = "~> 0.29" diff --git a/terraform/providers.tf b/terraform/providers.tf index cfff4f26..9d620627 100644 --- a/terraform/providers.tf +++ b/terraform/providers.tf @@ -12,15 +12,11 @@ terraform { } } - # State in B2 alongside CNPG + Longhorn backups. Auth via AWS_ACCESS_KEY_ID / - # AWS_SECRET_ACCESS_KEY (B2 application key in secrets/b2.yaml). Bucket has - # versioning enabled, so state history is recoverable from B2 if a bad apply - # corrupts it. + # Store state in the versioned B2 `aly-backups` bucket. `.envrc` puts the B2 + # application key from `secrets/b2.yaml` in the AWS variables. # - # No state locking: B2's S3 API at us-east-005 doesn't honor the - # If-None-Match conditional-PUT header that terraform's use_lockfile uses - # (501 NotImplemented). DynamoDB-based locking is overkill for single-user - # operation; the discipline is "don't run terraform from two places at once." + # B2's S3 API at `us-east-005` does not support conditional PUT. The backend + # cannot lock state, so run one apply at a time. backend "s3" { bucket = "aly-backups" key = "cute.haus/terraform/terraform.tfstate" @@ -44,6 +40,6 @@ provider "b2" { } provider "tailscale" { - # Reads TAILSCALE_API_KEY from the environment (API key in - # secrets/tailscale-api.yaml, decrypted by direnv). + # `.envrc` reads `TAILSCALE_API_KEY` from + # `secrets/tailscale-api.yaml`. } diff --git a/terraform/tailscale.tf b/terraform/tailscale.tf index 87375a57..fa71bd10 100644 --- a/terraform/tailscale.tf +++ b/terraform/tailscale.tf @@ -1,6 +1,4 @@ -# Tailscale tailnet ACL policy for narwhal-snapper.ts.net. -# Edit the `acl` field below and `tofu apply` to push changes. -# Run `tofu plan` first to preview the diff. +# Tailscale ACL policy for narwhal-snapper.ts.net. resource "tailscale_acl" "tailnet" { acl = <<-EOT @@ -16,35 +14,23 @@ resource "tailscale_acl" "tailnet" { "nodeAttrs": [ { "attr": ["mullvad"], - "target": ["100.106.251.41"], - }, - { - "attr": ["mullvad"], - "target": ["100.76.68.70"], - }, - { - "attr": ["mullvad"], - "target": ["100.124.238.118"], + "target": ["100.127.147.60"], }, { "attr": ["mullvad"], - "target": ["100.115.185.117"], + "target": ["100.88.43.71"], }, { "attr": ["mullvad"], - "target": ["100.64.222.8"], + "target": ["100.76.68.70"], }, { "attr": ["mullvad"], - "target": ["100.87.104.118"], + "target": ["100.106.251.41"], }, { "attr": ["mullvad"], - "target": ["100.100.102.26"], - }, - { - "attr": ["funnel"], - "target": ["tag:safari-ingress"], + "target": ["100.90.233.55"], }, ], @@ -66,17 +52,9 @@ resource "tailscale_acl" "tailnet" { "autoApprovers": { "services": { - "tag:safari-service": ["tag:safari-ingress"], + "tag:k8s": ["tag:k8s"], }, }, - - "grants": [ - { - "src": ["*"], - "dst": ["tag:safari-service"], - "ip": ["443"], - }, - ], } EOT }